diff --git a/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/AddSourceEspressoTest.kt b/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/AddSourceEspressoTest.kt deleted file mode 100644 index 11a8688..0000000 --- a/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/AddSourceEspressoTest.kt +++ /dev/null @@ -1,3 +0,0 @@ -package bou.amine.apps.readerforselfossv2.android - -// TODO: test source adding \ No newline at end of file diff --git a/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/HomeActivityEspressoTest.kt b/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/HomeActivityEspressoTest.kt deleted file mode 100644 index 79cd207..0000000 --- a/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/HomeActivityEspressoTest.kt +++ /dev/null @@ -1,102 +0,0 @@ -package bou.amine.apps.readerforselfossv2.android - -import android.content.Context -import android.content.Intent -import androidx.test.InstrumentationRegistry -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu -import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.action.ViewActions.closeSoftKeyboard -import androidx.test.espresso.action.ViewActions.pressKey -import androidx.test.espresso.action.ViewActions.typeText -import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.intent.Intents -import androidx.test.espresso.intent.Intents.intended -import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent -import androidx.test.espresso.matcher.ViewMatchers.isDisplayed -import androidx.test.espresso.matcher.ViewMatchers.withContentDescription -import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.espresso.matcher.ViewMatchers.withText -import androidx.test.rule.ActivityTestRule -import androidx.test.runner.AndroidJUnit4 -import android.view.KeyEvent -import androidx.test.espresso.matcher.RootMatchers.isDialog -import bou.amine.apps.readerforselfossv2.android.HomeActivity -import bou.amine.apps.readerforselfossv2.android.LoginActivity -import bou.amine.apps.readerforselfossv2.android.utils.Config -import org.junit.After -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class HomeActivityEspressoTest { - lateinit var context: Context - - @Rule @JvmField - val rule = ActivityTestRule(HomeActivity::class.java, true, false) - - @Before - fun clearData() { - context = InstrumentationRegistry.getInstrumentation().targetContext - - val editor = - context - .getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) - .edit() - editor.clear() - - editor.putString("url", BuildConfig.LOGIN_URL) - editor.putString("login", BuildConfig.LOGIN_USERNAME) - editor.putString("password", BuildConfig.LOGIN_PASSWORD) - - editor.commit() - - Intents.init() - } - - @Test - fun menuItems() { - - rule.launchActivity(Intent()) - - onView( - withMenu( - id = R.id.action_search, - titleId = R.string.menu_home_search - ) - ).perform(click()) - - onView(withId(R.id.search_bar)).check(matches(isDisplayed())) - - onView(withId(R.id.search_src_text)).perform( - typeText("android"), - pressKey(KeyEvent.KEYCODE_SEARCH), - closeSoftKeyboard() - ) - - onView(withContentDescription(R.string.abc_toolbar_collapse_description)).perform(click()) - - openActionBarOverflowOrOptionsMenu(context) - - onView(withMenu(id = R.id.refresh, titleId = R.string.menu_home_refresh)) - .perform(click()) - - onView(withText(android.R.string.ok)) - .inRoot(isDialog()).check(matches(isDisplayed())).perform(click()) - - openActionBarOverflowOrOptionsMenu(context) - - onView(withText(R.string.action_disconnect)).perform(click()) - - intended(hasComponent(LoginActivity::class.java.name)) - } - - // TODO: test articles opening and actions for cards and lists - - @After - fun releaseIntents() { - Intents.release() - } -} \ No newline at end of file diff --git a/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/LoginActivityEspressoTest.kt b/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/LoginActivityEspressoTest.kt deleted file mode 100644 index e64adb3..0000000 --- a/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/LoginActivityEspressoTest.kt +++ /dev/null @@ -1,180 +0,0 @@ -package bou.amine.apps.readerforselfossv2.android - -import android.content.Context -import android.content.Intent -import androidx.test.InstrumentationRegistry -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu -import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.action.ViewActions.closeSoftKeyboard -import androidx.test.espresso.action.ViewActions.pressBack -import androidx.test.espresso.action.ViewActions.typeText -import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.intent.Intents -import androidx.test.espresso.intent.Intents.intended -import androidx.test.espresso.intent.Intents.times -import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent -import androidx.test.espresso.matcher.ViewMatchers -import androidx.test.espresso.matcher.ViewMatchers.isRoot -import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility -import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.espresso.matcher.ViewMatchers.withText -import androidx.test.rule.ActivityTestRule -import androidx.test.runner.AndroidJUnit4 -import bou.amine.apps.readerforselfossv2.android.HomeActivity -import bou.amine.apps.readerforselfossv2.android.LoginActivity -import bou.amine.apps.readerforselfossv2.android.utils.Config -import com.mikepenz.aboutlibraries.ui.LibsActivity -import org.junit.After -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class LoginActivityEspressoTest { - - @Rule @JvmField - val rule = ActivityTestRule(LoginActivity::class.java, true, false) - - private lateinit var context: Context - private lateinit var url: String - private lateinit var username: String - private lateinit var password: String - - @Before - fun setUp() { - context = InstrumentationRegistry.getInstrumentation().targetContext - val editor = - context - .getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) - .edit() - editor.clear() - editor.commit() - - - url = BuildConfig.LOGIN_URL - username = BuildConfig.LOGIN_USERNAME - password = BuildConfig.LOGIN_PASSWORD - - Intents.init() - } - - @Test - fun menuItems() { - - rule.launchActivity(Intent()) - - openActionBarOverflowOrOptionsMenu(context) - - onView(withText(R.string.action_about)).perform(click()) - - intended(hasComponent(LibsActivity::class.java.name), times(1)) - - onView(isRoot()).perform(pressBack()) - - intended(hasComponent(LoginActivity::class.java.name)) - } - - @Test - fun wrongLoginUrl() { - rule.launchActivity(Intent()) - - onView(withId(R.id.loginProgress)) - .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE))) - - onView(withId(R.id.urlView)).perform(click()).perform(typeText("WRONGURL")) - - onView(withId(R.id.signInButton)).perform(click()) - - onView(withId(R.id.urlView)).check(matches(isHintOrErrorEnabled())) - } - - // TODO: Add tests for multiple false urls with dialog - - @Test - fun emptyAuthData() { - - rule.launchActivity(Intent()) - - onView(withId(R.id.urlView)).perform(click()).perform(typeText(url), closeSoftKeyboard()) - - onView(withId(R.id.withLogin)).perform(click()) - - onView(withId(R.id.signInButton)).perform(click()) - - onView(withId(R.id.loginView)).check(matches(isHintOrErrorEnabled())) - onView(withId(R.id.passwordView)).check(matches(isHintOrErrorEnabled())) - - onView(withId(R.id.loginView)).perform(click()).perform( - typeText(username), - closeSoftKeyboard() - ) - - onView(withId(R.id.passwordView)).check(matches(isHintOrErrorEnabled())) - - onView(withId(R.id.signInButton)).perform(click()) - - onView(withId(R.id.passwordView)).check( - matches( - isHintOrErrorEnabled() - ) - ) - } - - @Test - fun wrongAuthData() { - - rule.launchActivity(Intent()) - - onView(withId(R.id.urlView)).perform(click()).perform(typeText(url), closeSoftKeyboard()) - - onView(withId(R.id.withLogin)).perform(click()) - - onView(withId(R.id.loginView)).perform(click()).perform( - typeText(username), - closeSoftKeyboard() - ) - - onView(withId(R.id.passwordView)).perform(click()).perform( - typeText("WRONGPASS"), - closeSoftKeyboard() - ) - - onView(withId(R.id.signInButton)).perform(click()) - - onView(withId(R.id.urlView)).check(matches(isHintOrErrorEnabled())) - onView(withId(R.id.loginView)).check(matches(isHintOrErrorEnabled())) - onView(withId(R.id.passwordView)).check(matches(isHintOrErrorEnabled())) - } - - @Test - fun workingAuth() { - - rule.launchActivity(Intent()) - - onView(withId(R.id.urlView)).perform(click()).perform(typeText(url), closeSoftKeyboard()) - - onView(withId(R.id.withLogin)).perform(click()) - - onView(withId(R.id.loginView)).perform(click()).perform( - typeText(username), - closeSoftKeyboard() - ) - - onView(withId(R.id.passwordView)).perform(click()).perform( - typeText(password), - closeSoftKeyboard() - ) - - onView(withId(R.id.signInButton)).perform(click()) - - Thread.sleep(2000) - intended(hasComponent(HomeActivity::class.java.name)) - } - - @After - fun releaseIntents() { - Intents.release() - } -} \ No newline at end of file diff --git a/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/MainActivityEspressoTest.kt b/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/MainActivityEspressoTest.kt deleted file mode 100644 index 1400a0e..0000000 --- a/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/MainActivityEspressoTest.kt +++ /dev/null @@ -1,81 +0,0 @@ -package bou.amine.apps.readerforselfossv2.android - -import android.content.Context -import android.content.Intent -import android.content.SharedPreferences -import androidx.test.InstrumentationRegistry.getInstrumentation -import androidx.test.espresso.intent.Intents -import androidx.test.espresso.intent.Intents.intended -import androidx.test.espresso.intent.Intents.times -import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent -import androidx.test.rule.ActivityTestRule -import androidx.test.runner.AndroidJUnit4 -import bou.amine.apps.readerforselfossv2.android.HomeActivity -import bou.amine.apps.readerforselfossv2.android.LoginActivity -import bou.amine.apps.readerforselfossv2.android.MainActivity -import bou.amine.apps.readerforselfossv2.android.utils.Config -import org.junit.After - -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class MainActivityEspressoTest { - - lateinit var intent: Intent - lateinit var preferencesEditor: SharedPreferences.Editor - private lateinit var url: String - private lateinit var username: String - private lateinit var password: String - - @Rule @JvmField - val rule = ActivityTestRule(MainActivity::class.java, true, false) - - @Before - fun setUp() { - intent = Intent() - val context = getInstrumentation().targetContext - - // create a SharedPreferences editor - preferencesEditor = context.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE).edit() - - url = BuildConfig.LOGIN_URL - username = BuildConfig.LOGIN_USERNAME - password = BuildConfig.LOGIN_PASSWORD - - Intents.init() - } - - @Test - fun checkFirstOpenLaunchesIntro() { - preferencesEditor.putString("url", "") - preferencesEditor.putString("password", "") - preferencesEditor.putString("login", "") - preferencesEditor.commit() - - rule.launchActivity(intent) - - intended(hasComponent(LoginActivity::class.java.name)) - intended(hasComponent(HomeActivity::class.java.name), times(0)) - } - - @Test - fun checkNotFirstOpenLaunchesLogin() { - preferencesEditor.putString("url", url) - preferencesEditor.putString("password", password) - preferencesEditor.putString("login", username) - preferencesEditor.commit() - - rule.launchActivity(intent) - - intended(hasComponent(MainActivity::class.java.name)) - intended(hasComponent(HomeActivity::class.java.name)) - } - - @After - fun releaseIntents() { - Intents.release() - } -} \ No newline at end of file diff --git a/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/Utils.kt b/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/Utils.kt deleted file mode 100644 index b8fd12a..0000000 --- a/androidApp/src/androidTest/java/apps/amine/bou/readerforselfoss/Utils.kt +++ /dev/null @@ -1,29 +0,0 @@ -package bou.amine.apps.readerforselfossv2.android - -import androidx.test.espresso.matcher.ViewMatchers -import android.view.View -import android.widget.EditText -import org.hamcrest.Description -import org.hamcrest.Matcher -import org.hamcrest.Matchers -import org.hamcrest.TypeSafeMatcher - -fun isHintOrErrorEnabled(): Matcher = - object : TypeSafeMatcher() { - override fun describeTo(description: Description?) { - } - - override fun matchesSafely(item: View?): Boolean { - if (item !is EditText) { - return false - } - - return item.error.isNotEmpty() - } - } - -fun withMenu(id: Int, titleId: Int): Matcher = - Matchers.anyOf( - ViewMatchers.withId(id), - ViewMatchers.withText(titleId) - ) diff --git a/androidApp/src/main/AndroidManifest.xml b/androidApp/src/main/AndroidManifest.xml index f2e3130..5ef39dd 100644 --- a/androidApp/src/main/AndroidManifest.xml +++ b/androidApp/src/main/AndroidManifest.xml @@ -68,10 +68,6 @@ android:name=".ImageActivity"> - - diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt index 7df13e1..0c7093c 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt @@ -9,10 +9,10 @@ import androidx.constraintlayout.widget.ConstraintLayout import bou.amine.apps.readerforselfossv2.android.databinding.ActivityAddSourceBinding import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.themes.Toppings -import bou.amine.apps.readerforselfossv2.android.utils.Config import bou.amine.apps.readerforselfossv2.android.utils.isBaseUrlValid import bou.amine.apps.readerforselfossv2.model.NetworkUnavailableException import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import com.ftinc.scoop.Scoop import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -31,6 +31,7 @@ class AddSourceActivity : AppCompatActivity(), DIAware { override val di by closestDI() private val repository : Repository by instance() + private val appSettingsService : AppSettingsService by instance() override fun onCreate(savedInstanceState: Bundle?) { appColors = AppColors(this@AddSourceActivity) @@ -81,9 +82,9 @@ class AddSourceActivity : AppCompatActivity(), DIAware { override fun onResume() { super.onResume() - val config = Config() - if (config.baseUrl.isEmpty() || !config.baseUrl.isBaseUrlValid(this@AddSourceActivity)) { + val baseUrl = appSettingsService.getBaseUrl() + if (baseUrl.isEmpty() || !baseUrl.isBaseUrlValid(this@AddSourceActivity)) { mustLoginToAddSource() } else { handleSpoutsSpinner(binding.spoutsSpinner, binding.progress, binding.formContainer) diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt index 87b5b67..3e8f487 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt @@ -30,13 +30,12 @@ import bou.amine.apps.readerforselfossv2.android.databinding.ActivityHomeBinding import bou.amine.apps.readerforselfossv2.android.settings.SettingsActivity import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.themes.Toppings -import bou.amine.apps.readerforselfossv2.android.utils.Config import bou.amine.apps.readerforselfossv2.android.utils.bottombar.maybeShow import bou.amine.apps.readerforselfossv2.android.utils.bottombar.removeBadge import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActivityHelper -import bou.amine.apps.readerforselfossv2.dao.ACTION -import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.* import com.ashokvarma.bottomnavigation.BottomNavigationBar import com.ashokvarma.bottomnavigation.BottomNavigationItem @@ -58,7 +57,6 @@ import com.mikepenz.materialdrawer.util.DrawerImageLoader import com.mikepenz.materialdrawer.util.addStickyFooterItem import com.mikepenz.materialdrawer.util.updateBadge import com.mikepenz.materialdrawer.widget.AccountHeaderView -import com.russhwolf.settings.Settings import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -68,9 +66,10 @@ import org.kodein.di.instance import java.util.concurrent.TimeUnit import kotlin.concurrent.thread + class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAware { - private val MENU_PREFERENCES = 12302 + private val SETTINGS_ACTIVITY: Int = 101111 private val DRAWER_ID_TAGS = 100101L private val DRAWER_ID_HIDDEN_TAGS = 101100L private val DRAWER_ID_SOURCES = 100110L @@ -78,24 +77,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar private var items: ArrayList = ArrayList() - private var internalBrowser = false - private var articleViewer = false - private var shouldBeCardView = false - private var displayUnreadCount = false - private var displayAllCount = false - private var fullHeightCards: Boolean = false - private var itemsNumber: Int = 200 private var elementsShown: ItemType = ItemType.UNREAD - private var displayAccountHeader: Boolean = false - private var infiniteScroll: Boolean = false private var lastFetchDone: Boolean = false - private var updateSources: Boolean = true - private var markOnScroll: Boolean = false - private var hiddenTags: List = emptyList() - - private var periodicRefresh = false - private var refreshMinutes: Long = 360L - private var refreshWhenChargingOnly = false private lateinit var tabNewBadge: TextBadgeItem private lateinit var tabArchiveBadge: TextBadgeItem @@ -105,7 +88,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar private var offset: Int = 0 private var firstVisible: Int = 0 private lateinit var recyclerViewScrollListener: RecyclerView.OnScrollListener - private var settings = Settings() private lateinit var binding: ActivityHomeBinding private var recyclerAdapter: RecyclerView.Adapter<*>? = null @@ -114,10 +96,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar private lateinit var tagsBadge: Map - private lateinit var config: Config - override val di by closestDI() private val repository : Repository by instance() + private val appSettingsService : AppSettingsService by instance() data class DrawerData(val tags: List?, val sources: List?) @@ -127,8 +108,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } override fun onCreate(savedInstanceState: Bundle?) { + + // Add appcolors to DI appColors = AppColors(this@HomeActivity) - config = Config() super.onCreate(savedInstanceState) binding = ActivityHomeBinding.inflate(layoutInflater) @@ -159,8 +141,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar handleSwipeRefreshLayout() - handleSettings() - getElementsAccordingToTab() @@ -299,7 +279,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar override fun onResume() { super.onResume() - // TODO: Make this the only appcolors init appColors = AppColors(this@HomeActivity) handleDrawerItems() @@ -308,10 +287,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar reloadLayoutManager() - if (!infiniteScroll) { - binding.recyclerView.setHasFixedSize(true) - } else { + if (appSettingsService.isInfiniteLoadingEnabled()) { handleInfiniteScroll() + } else { + binding.recyclerView.setHasFixedSize(true) } handleBottomBarActions() @@ -330,32 +309,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar customTabActivityHelper.unbindCustomTabsService(this) } - private fun handleSettings() { - internalBrowser = settings.getBoolean("prefer_internal_browser", true) - articleViewer = settings.getBoolean("prefer_article_viewer", true) - shouldBeCardView = settings.getBoolean("card_view_active", false) - displayUnreadCount = settings.getBoolean("display_unread_count", true) - displayAllCount = settings.getBoolean("display_other_count", false) - fullHeightCards = settings.getBoolean("full_height_cards", false) - itemsNumber = settings.getString("prefer_api_items_number", "200").toInt() - displayAccountHeader = settings.getBoolean("account_header_displaying", false) - infiniteScroll = settings.getBoolean("infinite_loading", false) - updateSources = settings.getBoolean("update_sources", true) - markOnScroll = settings.getBoolean("mark_on_scroll", false) - hiddenTags = if (settings.getString("hidden_tags", "").isNotEmpty()) { - settings.getString("hidden_tags", "").replace("\\s".toRegex(), "").split(",") - } else { - emptyList() - } - periodicRefresh = settings.getBoolean("periodic_refresh", false) - refreshWhenChargingOnly = settings.getBoolean("refresh_when_charging", false) - refreshMinutes = settings.getString("periodic_refresh_minutes", "360").toLong() - - if (refreshMinutes <= 15) { - refreshMinutes = 15 - } - } - private fun handleThemeBinding() { val scoop = Scoop.getInstance() scoop.bind(this, Toppings.PRIMARY.value, binding.toolBar) @@ -409,16 +362,13 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar binding.drawerContainer.addDrawerListener(drawerListener) - displayAccountHeader = - settings.getBoolean("account_header_displaying", false) - binding.mainDrawer.addStickyFooterItem( PrimaryDrawerItem().apply { nameRes = R.string.drawer_report_bug iconRes = R.drawable.ic_bug_report_black_24dp isIconTinted = true onDrawerItemClickListener = { _, _, _ -> - val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(Config.trackerUrl)) + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(AppSettingsService.trackerUrl)) startActivity(browserIntent) false } @@ -430,17 +380,17 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar iconRes = R.drawable.ic_settings_black_24dp isIconTinted = true onDrawerItemClickListener = { _, _, _ -> - startActivity(Intent(this@HomeActivity, SettingsActivity::class.java)) + startActivityForResult(Intent(this@HomeActivity, SettingsActivity::class.java), SETTINGS_ACTIVITY) false } }) - if (displayAccountHeader) { + if (appSettingsService.isDisplayAccountHeaderEnabled()) { AccountHeaderView(this).apply { attachToSliderView(binding.mainDrawer) addProfiles( ProfileDrawerItem().apply { - nameText = settings.getString("url", "") + nameText = appSettingsService.getBaseUrl() setBackgroundResource(R.drawable.bg) iconRes = R.mipmap.ic_launcher selectionListEnabledForSingleProfile = false @@ -451,6 +401,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } // TODO: refactor this. + // TODO: use updateSources private fun handleDrawerItems() { tagsBadge = emptyMap() fun handleDrawerData(maybeDrawerData: DrawerData?, loadedFromCache: Boolean = false) { @@ -503,7 +454,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } } else { val filteredTags = maybeTags - .filterNot { hiddenTags.contains(it.tag) } + .filterNot { appSettingsService.getHiddenTags().contains(it.tag) } .sortedBy { it.unread == 0 } tagsBadge = filteredTags.map { createDrawerItem(it) @@ -525,7 +476,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } } else { val filteredHiddenTags: List = - maybeTags.filter { hiddenTags.contains(it.tag) } + maybeTags.filter { appSettingsService.getHiddenTags().contains(it.tag) } tagsBadge = filteredHiddenTags.map { createDrawerItem(it) @@ -581,7 +532,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } } ) - if (hiddenTags.isNotEmpty()) { + if (appSettingsService.getHiddenTags().isNotEmpty()) { binding.mainDrawer.itemAdapter.add( DividerDrawerItem(), SecondaryDrawerItem().apply { @@ -714,7 +665,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar // This will only update the layout manager if settings changed when (currentManager) { is StaggeredGridLayoutManager -> - if (!shouldBeCardView) { + if (!appSettingsService.isCardViewEnabled()) { layoutManager = GridLayoutManager( this, calculateNoOfColumns() @@ -722,7 +673,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar binding.recyclerView.layoutManager = layoutManager } is GridLayoutManager -> - if (shouldBeCardView) { + if (appSettingsService.isCardViewEnabled()) { layoutManager = StaggeredGridLayoutManager( calculateNoOfColumns(), StaggeredGridLayoutManager.VERTICAL @@ -733,7 +684,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } else -> if (currentManager == null) { - if (!shouldBeCardView) { + if (!appSettingsService.isCardViewEnabled()) { layoutManager = GridLayoutManager( this, calculateNoOfColumns() @@ -869,17 +820,13 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } if (recyclerAdapter == null) { - if (shouldBeCardView) { + if (appSettingsService.isCardViewEnabled()) { recyclerAdapter = ItemCardAdapter( this, items, customTabActivityHelper, - internalBrowser, - articleViewer, - fullHeightCards, appColors, - config ) { updateItems(it) } @@ -889,10 +836,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar this, items, customTabActivityHelper, - internalBrowser, - articleViewer, appColors, - config ) { updateItems(it) } @@ -914,7 +858,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } private fun reloadBadges() { - if (displayUnreadCount || displayAllCount) { + if (appSettingsService.isDisplayUnreadCountEnabled() || appSettingsService.isDisplayAllCountEnabled()) { CoroutineScope(Dispatchers.Main).launch { repository.reloadBadges() reloadBadgeContent() @@ -923,12 +867,12 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } private fun reloadBadgeContent() { - if (displayUnreadCount) { + if (appSettingsService.isDisplayUnreadCountEnabled()) { tabNewBadge .setText(repository.badgeUnread.toString()) .maybeShow() } - if (displayAllCount) { + if (appSettingsService.isDisplayAllCountEnabled()) { tabArchiveBadge .setText(repository.badgeAll.toString()) .maybeShow() @@ -1047,7 +991,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar return true } R.id.action_disconnect -> { - return Config.logoutAndRedirect(this, this@HomeActivity) + appSettingsService.clearAll() + val intent = Intent(this, LoginActivity::class.java) + this.startActivity(intent) + this@HomeActivity.finish() + return true } else -> return super.onOptionsItemSelected(item) } @@ -1066,15 +1014,15 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } private fun handleRecurringTask() { - if (periodicRefresh) { + if (appSettingsService.isPeriodicRefreshEnabled()) { val myConstraints = Constraints.Builder() .setRequiresBatteryNotLow(true) - .setRequiresCharging(refreshWhenChargingOnly) + .setRequiresCharging(appSettingsService.isRefreshWhenChargingOnlyEnabled()) .setRequiresStorageNotLow(true) .build() val backgroundWork = - PeriodicWorkRequestBuilder(refreshMinutes, TimeUnit.MINUTES) + PeriodicWorkRequestBuilder(appSettingsService.getRefreshMinutes(), TimeUnit.MINUTES) .setConstraints(myConstraints) .addTag("selfoss-loading") .build() @@ -1083,8 +1031,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } } - private fun handleOfflineActions() { - + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == SETTINGS_ACTIVITY) { + appSettingsService.refreshUserSettings() + } } } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt index 544325f..c7883b6 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt @@ -16,8 +16,8 @@ import bou.amine.apps.readerforselfossv2.android.databinding.ActivityLoginBindin import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.utils.isBaseUrlValid import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import com.mikepenz.aboutlibraries.LibsBuilder -import com.russhwolf.settings.Settings import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -25,19 +25,17 @@ import org.kodein.di.DIAware import org.kodein.di.android.closestDI import org.kodein.di.instance -class LoginActivity() : AppCompatActivity(), DIAware { +class LoginActivity : AppCompatActivity(), DIAware { private var inValidCount: Int = 0 - private var isWithSelfSignedCert = false private var isWithLogin = false - private var isWithHTTPLogin = false - private val settings = Settings() private lateinit var appColors: AppColors private lateinit var binding: ActivityLoginBinding override val di by closestDI() private val repository : Repository by instance() + private val appSettingsService : AppSettingsService by instance() override fun onCreate(savedInstanceState: Bundle?) { appColors = AppColors(this@LoginActivity) @@ -52,7 +50,7 @@ class LoginActivity() : AppCompatActivity(), DIAware { handleBaseUrlFail() - if (settings.getString("url", "").isNotEmpty()) { + if (appSettingsService.getBaseUrl().isNotEmpty()) { goToMain() } @@ -61,13 +59,6 @@ class LoginActivity() : AppCompatActivity(), DIAware { private fun handleActions() { - binding.withSelfhostedCert.setOnCheckedChangeListener { _, b -> - isWithSelfSignedCert = !isWithSelfSignedCert - val visi: Int = if (b) View.VISIBLE else View.GONE - - binding.warningText.visibility = visi - } - binding.passwordView.setOnEditorActionListener( TextView.OnEditorActionListener { _, id, _ -> if (id == R.id.loginView || id == EditorInfo.IME_NULL) { @@ -87,14 +78,6 @@ class LoginActivity() : AppCompatActivity(), DIAware { binding.loginView.visibility = visi binding.passwordView.visibility = visi } - - binding.withHttpLogin.setOnCheckedChangeListener { _, b -> - isWithHTTPLogin = !isWithHTTPLogin - val visi: Int = if (b) View.VISIBLE else View.GONE - - binding.httpLoginView.visibility = visi - binding.httpPasswordView.visibility = visi - } } private fun handleBaseUrlFail() { @@ -117,16 +100,11 @@ class LoginActivity() : AppCompatActivity(), DIAware { } private fun preferenceError(t: Throwable) { - settings.remove("url") - settings.remove("login") - settings.remove("httpUserName") - settings.remove("password") - settings.remove("httpPassword") + appSettingsService.resetLoginInformation() + binding.urlView.error = getString(R.string.wrong_infos) binding.loginView.error = getString(R.string.wrong_infos) binding.passwordView.error = getString(R.string.wrong_infos) - binding.httpLoginView.error = getString(R.string.wrong_infos) - binding.httpPasswordView.error = getString(R.string.wrong_infos) } private fun attemptLogin() { @@ -134,16 +112,12 @@ class LoginActivity() : AppCompatActivity(), DIAware { // Reset errors. binding.urlView.error = null binding.loginView.error = null - binding.httpLoginView.error = null binding.passwordView.error = null - binding.httpPasswordView.error = null // Store values at the time of the login attempt. val url = binding.urlView.text.toString() val login = binding.loginView.text.toString() - val httpLogin = binding.httpLoginView.text.toString() val password = binding.passwordView.text.toString() - val httpPassword = binding.httpPasswordView.text.toString() var cancel = false var focusView: View? = null @@ -180,30 +154,17 @@ class LoginActivity() : AppCompatActivity(), DIAware { } } - if (isWithHTTPLogin) { - if (TextUtils.isEmpty(httpPassword)) { - binding.httpPasswordView.error = getString(R.string.error_invalid_password) - focusView = binding.httpPasswordView - cancel = true - } - - if (TextUtils.isEmpty(httpLogin)) { - binding.httpLoginView.error = getString(R.string.error_field_required) - focusView = binding.httpLoginView - cancel = true - } - } - if (cancel) { focusView?.requestFocus() } else { showProgress(true) - repository.refreshLoginInformation(url, login, password, httpLogin, httpPassword, isWithSelfSignedCert) + repository.refreshLoginInformation(url, login, password) CoroutineScope(Dispatchers.IO).launch { val result = repository.login() if (result) { + repository.updateApiVersion() goToMain() } else { CoroutineScope(Dispatchers.Main).launch { diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt index 3345124..4e7c2d4 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt @@ -14,19 +14,17 @@ import androidx.lifecycle.ProcessLifecycleOwner import androidx.multidex.MultiDexApplication import androidx.preference.PreferenceManager import bou.amine.apps.readerforselfossv2.DI.networkModule -import bou.amine.apps.readerforselfossv2.android.utils.Config -import bou.amine.apps.readerforselfossv2.android.utils.glide.loadMaybeBasicAuth import bou.amine.apps.readerforselfossv2.android.viewmodel.AppViewModel import bou.amine.apps.readerforselfossv2.dao.DriverFactory import bou.amine.apps.readerforselfossv2.dao.ReaderForSelfossDB import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import com.bumptech.glide.Glide import com.bumptech.glide.request.RequestOptions import com.ftinc.scoop.Scoop import com.github.ln_12.library.ConnectivityStatus import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader import com.mikepenz.materialdrawer.util.DrawerImageLoader -import com.russhwolf.settings.Settings import io.github.aakira.napier.DebugAntilog import io.github.aakira.napier.Napier import kotlinx.coroutines.CoroutineScope @@ -49,14 +47,10 @@ class MyApp : MultiDexApplication(), DIAware { private val viewModel: AppViewModel by instance() private val connectivityStatus: ConnectivityStatus by instance() private val driverFactory: DriverFactory by instance() - private lateinit var config: Config - private lateinit var settings : Settings override fun onCreate() { super.onCreate() Napier.base(DebugAntilog()) - config = Config() - settings = Settings() initDrawerImageLoader() @@ -93,11 +87,11 @@ class MyApp : MultiDexApplication(), DIAware { val name = getString(R.string.notification_channel_sync) val importance = NotificationManager.IMPORTANCE_LOW - val mChannel = NotificationChannel(Config.syncChannelId, name, importance) + val mChannel = NotificationChannel(AppSettingsService.syncChannelId, name, importance) val newItemsChannelname = getString(R.string.new_items_channel_sync) val newItemsChannelimportance = NotificationManager.IMPORTANCE_DEFAULT - val newItemsChannelmChannel = NotificationChannel(Config.newItemsChannelId, newItemsChannelname, newItemsChannelimportance) + val newItemsChannelmChannel = NotificationChannel(AppSettingsService.newItemsChannelId, newItemsChannelname, newItemsChannelimportance) notificationManager.createNotificationChannel(mChannel) notificationManager.createNotificationChannel(newItemsChannelmChannel) @@ -108,7 +102,7 @@ class MyApp : MultiDexApplication(), DIAware { DrawerImageLoader.init(object : AbstractDrawerImageLoader() { override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) { Glide.with(imageView.context) - .loadMaybeBasicAuth(config, uri.toString()) + .load(uri.toString()) .apply(RequestOptions.fitCenterTransform().placeholder(placeholder)) .into(imageView) } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt index 125940e..ad6a23c 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt @@ -14,10 +14,10 @@ import bou.amine.apps.readerforselfossv2.android.databinding.ActivityReaderBindi import bou.amine.apps.readerforselfossv2.android.fragments.ArticleFragment import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.themes.Toppings -import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import com.ftinc.scoop.Scoop -import com.russhwolf.settings.Settings import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -27,7 +27,6 @@ import org.kodein.di.instance class ReaderActivity : AppCompatActivity(), DIAware { - private var markOnScroll: Boolean = false private var currentItem: Int = 0 private lateinit var appColors: AppColors @@ -35,12 +34,9 @@ class ReaderActivity : AppCompatActivity(), DIAware { private lateinit var binding: ActivityReaderBinding - private var activeAlignment: Int = 1 - private val JUSTIFY = 1 - private val ALIGN_LEFT = 2 - override val di by closestDI() private val repository: Repository by instance() + private val appSettingsService: AppSettingsService by instance() private fun showMenuItem(willAddToFavorite: Boolean) { if (willAddToFavorite) { @@ -58,8 +54,6 @@ class ReaderActivity : AppCompatActivity(), DIAware { showMenuItem(false) } - private var settings = Settings() - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) appColors = AppColors(this) @@ -76,9 +70,6 @@ class ReaderActivity : AppCompatActivity(), DIAware { supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true) - markOnScroll = settings.getBoolean("mark_on_scroll", false) - activeAlignment = settings.getInt("text_align", JUSTIFY) - if (allItems.isEmpty()) { finish() } @@ -98,10 +89,9 @@ class ReaderActivity : AppCompatActivity(), DIAware { } private fun readItem(item: SelfossModel.Item) { - if (markOnScroll) { + if (appSettingsService.isMarkOnScrollEnabled()) { CoroutineScope(Dispatchers.IO).launch { repository.markAsRead(item) - // TODO: Handle failure } } } @@ -142,7 +132,7 @@ class ReaderActivity : AppCompatActivity(), DIAware { } private fun alignmentMenu() { - val showJustify = activeAlignment == ALIGN_LEFT + val showJustify = appSettingsService.getActiveAllignment() == AppSettingsService.ALIGN_LEFT toolbarMenu.findItem(R.id.align_left).isVisible = !showJustify toolbarMenu.findItem(R.id.align_justify).isVisible = showJustify } @@ -211,21 +201,19 @@ class ReaderActivity : AppCompatActivity(), DIAware { } } R.id.align_left -> { - activeAlignment = ALIGN_LEFT - switchAlignmentSetting() + switchAlignmentSetting(AppSettingsService.ALIGN_LEFT) refreshFragment() } R.id.align_justify -> { - activeAlignment = JUSTIFY - switchAlignmentSetting() + switchAlignmentSetting(AppSettingsService.JUSTIFY) refreshFragment() } } return super.onOptionsItemSelected(item) } - private fun switchAlignmentSetting() { - settings.putInt("text_align", activeAlignment) + private fun switchAlignmentSetting(allignment: Int) { + appSettingsService.changeAllignment(allignment) alignmentMenu() } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt index 90591e4..d28b290 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt @@ -10,8 +10,8 @@ import bou.amine.apps.readerforselfossv2.android.adapters.SourcesListAdapter import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySourcesBinding import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.themes.Toppings -import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.repository.Repository import com.ftinc.scoop.Scoop import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt index a7b42d6..23073d7 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt @@ -9,14 +9,15 @@ import android.widget.ImageView.ScaleType import androidx.recyclerview.widget.RecyclerView import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.databinding.CardItemBinding -import bou.amine.apps.readerforselfossv2.android.model.* +import bou.amine.apps.readerforselfossv2.android.model.toTextDrawableString import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.utils.* import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActivityHelper import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable -import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded import bou.amine.apps.readerforselfossv2.utils.getIcon import bou.amine.apps.readerforselfossv2.utils.getThumbnail @@ -34,11 +35,7 @@ class ItemCardAdapter( override val app: Activity, override var items: ArrayList, private val helper: CustomTabActivityHelper, - private val internalBrowser: Boolean, - private val articleViewer: Boolean, - private val fullHeightCards: Boolean, override val appColors: AppColors, - override val config: Config, override val updateItems: (ArrayList) -> Unit ) : ItemsAdapter() { private val c: Context = app.baseContext @@ -48,6 +45,7 @@ class ItemCardAdapter( override val di: DI by closestDI(app) override val repository : Repository by instance() + override val appSettingsService : AppSettingsService by instance() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = CardItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) @@ -67,7 +65,7 @@ class ItemCardAdapter( binding.sourceTitleAndDate.text = itm.sourceAndDateText(repository.dateUtils) - if (!fullHeightCards) { + if (!appSettingsService.isFullHeightCardsEnabled()) { binding.itemImage.maxHeight = imageMaxHeight binding.itemImage.scaleType = ScaleType.CENTER_CROP } @@ -78,7 +76,7 @@ class ItemCardAdapter( binding.itemImage.setImageDrawable(null) } else { binding.itemImage.visibility = View.VISIBLE - c.bitmapCenterCrop(config, itm.getThumbnail(repository.baseUrl), binding.itemImage) + c.bitmapCenterCrop(itm.getThumbnail(repository.baseUrl), binding.itemImage) } if (itm.getIcon(repository.baseUrl).isEmpty()) { @@ -91,7 +89,7 @@ class ItemCardAdapter( .build(itm.title.getHtmlDecoded().toTextDrawableString(), color) binding.sourceImage.setImageDrawable(drawable) } else { - c.circularBitmapDrawable(config, itm.getIcon(repository.baseUrl), binding.sourceImage) + c.circularBitmapDrawable(itm.getIcon(repository.baseUrl), binding.sourceImage) } } } @@ -147,8 +145,8 @@ class ItemCardAdapter( bindingAdapterPosition, items[bindingAdapterPosition].getLinkDecoded(), customTabsIntent, - internalBrowser, - articleViewer, + appSettingsService.isInternalBrowserEnabled(), + appSettingsService.isArticleViewerEnabled(), app ) } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt index 27839a4..b4fef63 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt @@ -6,14 +6,17 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import bou.amine.apps.readerforselfossv2.android.databinding.ListItemBinding -import bou.amine.apps.readerforselfossv2.android.model.* +import bou.amine.apps.readerforselfossv2.android.model.toTextDrawableString import bou.amine.apps.readerforselfossv2.android.themes.AppColors -import bou.amine.apps.readerforselfossv2.android.utils.* +import bou.amine.apps.readerforselfossv2.android.utils.LinkOnTouchListener +import bou.amine.apps.readerforselfossv2.android.utils.buildCustomTabsIntent import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActivityHelper import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable -import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.android.utils.openItemUrl import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded import bou.amine.apps.readerforselfossv2.utils.getIcon import bou.amine.apps.readerforselfossv2.utils.getThumbnail @@ -27,10 +30,7 @@ class ItemListAdapter( override val app: Activity, override var items: ArrayList, private val helper: CustomTabActivityHelper, - private val internalBrowser: Boolean, - private val articleViewer: Boolean, override val appColors: AppColors, - override val config: Config, override val updateItems: (ArrayList) -> Unit ) : ItemsAdapter() { private val generator: ColorGenerator = ColorGenerator.MATERIAL @@ -38,6 +38,7 @@ class ItemListAdapter( override val di: DI by closestDI(app) override val repository : Repository by instance() + override val appSettingsService : AppSettingsService by instance() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = ListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) @@ -69,10 +70,10 @@ class ItemListAdapter( binding.itemImage.setImageDrawable(drawable) } else { - c.circularBitmapDrawable(config, itm.getIcon(repository.baseUrl), binding.itemImage) + c.circularBitmapDrawable(itm.getIcon(repository.baseUrl), binding.itemImage) } } else { - c.bitmapCenterCrop(config, itm.getThumbnail(repository.baseUrl), binding.itemImage) + c.bitmapCenterCrop(itm.getThumbnail(repository.baseUrl), binding.itemImage) } } } @@ -95,8 +96,8 @@ class ItemListAdapter( bindingAdapterPosition, items[bindingAdapterPosition].getLinkDecoded(), customTabsIntent, - internalBrowser, - articleViewer, + appSettingsService.isInternalBrowserEnabled(), + appSettingsService.isArticleViewerEnabled(), app ) } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt index 7dea71a..4c43c85 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt @@ -6,9 +6,9 @@ import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.themes.AppColors -import bou.amine.apps.readerforselfossv2.android.utils.Config -import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.ItemType import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.CoroutineScope @@ -19,9 +19,9 @@ import org.kodein.di.DIAware abstract class ItemsAdapter : RecyclerView.Adapter(), DIAware { abstract var items: ArrayList abstract val repository: Repository + abstract val appSettingsService: AppSettingsService abstract val app: Activity abstract val appColors: AppColors - abstract val config: Config abstract val updateItems: (ArrayList) -> Unit fun updateAllItems(items: ArrayList) { @@ -94,8 +94,6 @@ abstract class ItemsAdapter : RecyclerView.Adapte private fun unreadItemAtIndex(position: Int, showSnackbar: Boolean = true) { CoroutineScope(Dispatchers.IO).launch { repository.unmarkAsRead(items[position]) - // Todo: SharedItems.unreadItem(app, api, db, items[position]) - // TODO: update db } notifyItemChanged(position) diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt index 187af5a..19b800a 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt @@ -11,10 +11,9 @@ import androidx.recyclerview.widget.RecyclerView import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.databinding.SourceListItemBinding import bou.amine.apps.readerforselfossv2.android.model.toTextDrawableString -import bou.amine.apps.readerforselfossv2.android.utils.Config import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable -import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded import bou.amine.apps.readerforselfossv2.utils.getIcon import com.amulyakhare.textdrawable.TextDrawable @@ -33,7 +32,6 @@ class SourcesListAdapter( ) : RecyclerView.Adapter(), DIAware { private val c: Context = app.baseContext private val generator: ColorGenerator = ColorGenerator.MATERIAL - private lateinit var config: Config private lateinit var binding: SourceListItemBinding override val di: DI by closestDI(app) @@ -46,7 +44,6 @@ class SourcesListAdapter( override fun onBindViewHolder(holder: ViewHolder, position: Int) { val itm = items[position] - config = Config() if (itm.getIcon(repository.baseUrl).isEmpty()) { val color = generator.getColor(itm.title.getHtmlDecoded()) @@ -58,7 +55,7 @@ class SourcesListAdapter( .build(itm.title.getHtmlDecoded().toTextDrawableString(), color) binding.itemImage.setImageDrawable(drawable) } else { - c.circularBitmapDrawable(config, itm.getIcon(repository.baseUrl), binding.itemImage) + c.circularBitmapDrawable(itm.getIcon(repository.baseUrl), binding.itemImage) } binding.sourceTitle.text = itm.title.getHtmlDecoded() diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt index 907338d..74a0739 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt @@ -14,12 +14,10 @@ import bou.amine.apps.readerforselfossv2.android.MainActivity import bou.amine.apps.readerforselfossv2.android.MyApp import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.model.preloadImages -import bou.amine.apps.readerforselfossv2.android.utils.Config import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAccessible -import bou.amine.apps.readerforselfossv2.dao.ACTION import bou.amine.apps.readerforselfossv2.model.SelfossModel import bou.amine.apps.readerforselfossv2.repository.Repository -import com.russhwolf.settings.Settings +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -27,39 +25,37 @@ import org.kodein.di.DIAware import org.kodein.di.instance import java.util.* import kotlin.concurrent.schedule -import kotlin.concurrent.thread class LoadingWorker(val context: Context, params: WorkerParameters) : Worker(context, params), DIAware { override val di by lazy { (applicationContext as MyApp).di } private val repository : Repository by instance() + private val appSettingsService : AppSettingsService by instance() override fun doWork(): Result { - val settings = Settings() - val periodicRefresh = settings.getBoolean("periodic_refresh", false) - if (periodicRefresh && isNetworkAccessible(context)) { + if (appSettingsService.isPeriodicRefreshEnabled() && isNetworkAccessible(context)) { CoroutineScope(Dispatchers.IO).launch { val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val notification = - NotificationCompat.Builder(applicationContext, Config.syncChannelId) + NotificationCompat.Builder(applicationContext, AppSettingsService.syncChannelId) .setContentTitle(context.getString(R.string.loading_notification_title)) .setContentText(context.getString(R.string.loading_notification_text)) .setOngoing(true) .setPriority(PRIORITY_LOW) - .setChannelId(Config.syncChannelId) + .setChannelId(AppSettingsService.syncChannelId) .setSmallIcon(R.drawable.ic_stat_cloud_download_black_24dp) notificationManager.notify(1, notification.build()) - val notifyNewItems = settings.getBoolean("notify_new_items", false) - repository.handleDBActions() - launch { - handleNewItemsNotification(repository.tryToCacheItemsAndGetNewOnes(), notifyNewItems, notificationManager) + if (appSettingsService.isNotifyNewItemsEnabled()) { + launch { + handleNewItemsNotification(repository.tryToCacheItemsAndGetNewOnes(), notificationManager) + } } } } @@ -68,7 +64,6 @@ override fun doWork(): Result { private fun handleNewItemsNotification( newItems: List?, - notifyNewItems: Boolean, notificationManager: NotificationManager ) { CoroutineScope(Dispatchers.IO).launch { @@ -76,7 +71,7 @@ override fun doWork(): Result { val newSize = apiItems.filter { it.unread }.size - if (notifyNewItems && newSize > 0) { + if (newSize > 0) { val intent = Intent(context, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK @@ -89,7 +84,7 @@ override fun doWork(): Result { val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, pflags) val newItemsNotification = - NotificationCompat.Builder(applicationContext, Config.newItemsChannelId) + NotificationCompat.Builder(applicationContext, AppSettingsService.newItemsChannelId) .setContentTitle(context.getString(R.string.new_items_notification_title)) .setContentText( context.getString( @@ -98,7 +93,7 @@ override fun doWork(): Result { ) ) .setPriority(PRIORITY_DEFAULT) - .setChannelId(Config.newItemsChannelId) + .setChannelId(AppSettingsService.newItemsChannelId) .setContentIntent(pendingIntent) .setAutoCancel(true) .setSmallIcon(R.drawable.ic_tab_fiber_new_black_24dp) diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt index 7c9f602..f50786a 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt @@ -24,14 +24,19 @@ import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.api.mercury.MercuryApi import bou.amine.apps.readerforselfossv2.android.api.mercury.ParsedContent import bou.amine.apps.readerforselfossv2.android.databinding.FragmentArticleBinding -import bou.amine.apps.readerforselfossv2.android.model.* +import bou.amine.apps.readerforselfossv2.android.model.ParecelableItem +import bou.amine.apps.readerforselfossv2.android.model.toModel +import bou.amine.apps.readerforselfossv2.android.model.toParcelable import bou.amine.apps.readerforselfossv2.android.themes.AppColors -import bou.amine.apps.readerforselfossv2.android.utils.* +import bou.amine.apps.readerforselfossv2.android.utils.buildCustomTabsIntent import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActivityHelper import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStream -import bou.amine.apps.readerforselfossv2.android.utils.glide.loadMaybeBasicAuth -import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.android.utils.openInBrowserAsNewTask +import bou.amine.apps.readerforselfossv2.android.utils.openItemUrlInternalBrowser +import bou.amine.apps.readerforselfossv2.android.utils.shareLink import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded import bou.amine.apps.readerforselfossv2.utils.getImages import bou.amine.apps.readerforselfossv2.utils.getThumbnail @@ -41,7 +46,6 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.RequestOptions import com.github.rubensousa.floatingtoolbar.FloatingToolbar import com.google.android.material.floatingactionbutton.FloatingActionButton -import com.russhwolf.settings.Settings import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -70,14 +74,12 @@ class ArticleFragment : Fragment(), DIAware { private lateinit var fab: FloatingActionButton private lateinit var appColors: AppColors private lateinit var textAlignment: String - private lateinit var config: Config private var _binding: FragmentArticleBinding? = null private val binding get() = _binding!! override val di : DI by closestDI() private val repository: Repository by instance() - - private var settings = Settings() + private val appSettingsService: AppSettingsService by instance() private var typeface: Typeface? = null private var resId: Int = 0 @@ -93,7 +95,6 @@ class ArticleFragment : Fragment(), DIAware { override fun onCreate(savedInstanceState: Bundle?) { appColors = AppColors(requireActivity()) - config = Config() super.onCreate(savedInstanceState) @@ -117,10 +118,10 @@ class ArticleFragment : Fragment(), DIAware { contentSource = item.sourceAndDateText(repository.dateUtils) allImages = item.getImages() - fontSize = settings.getString("reader_font_size", "16").toInt() - staticBar = settings.getBoolean("reader_static_bar", false) + fontSize = appSettingsService.getFontSize() + staticBar = appSettingsService.isStaticBarEnabled() + font = appSettingsService.getFont() - font = settings.getString("reader_font", "") if (font.isNotEmpty()) { resId = requireContext().resources.getIdentifier(font, "font", requireContext().packageName) typeface = try { @@ -213,7 +214,7 @@ class ArticleFragment : Fragment(), DIAware { Glide .with(requireContext()) .asBitmap() - .loadMaybeBasicAuth(config, contentImage) + .load(contentImage) .apply(RequestOptions.fitCenterTransform()) .into(binding.imageView) } else { @@ -242,7 +243,7 @@ class ArticleFragment : Fragment(), DIAware { .setTitle(requireContext().getString(R.string.webview_dialog_issue_title)) .setPositiveButton(android.R.string.ok ) { _, _ -> - settings.putBoolean("prefer_article_viewer", false) + appSettingsService.disableArticleViewer() requireActivity().finish() } .create() @@ -258,7 +259,7 @@ class ArticleFragment : Fragment(), DIAware { } private fun refreshAlignment() { - textAlignment = when (settings.getInt("text_align", 1)) { + textAlignment = when (appSettingsService.getActiveAllignment()) { 1 -> "justify" 2 -> "left" else -> "justify" @@ -307,8 +308,7 @@ class ArticleFragment : Fragment(), DIAware { Glide .with(requireContext()) .asBitmap() - .loadMaybeBasicAuth( - config, + .load( response.body()!!.lead_image_url.orEmpty() ) .apply(RequestOptions.fitCenterTransform()) diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ImageFragment.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ImageFragment.kt index 50d1ea1..129f883 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ImageFragment.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ImageFragment.kt @@ -1,7 +1,9 @@ package bou.amine.apps.readerforselfossv2.android.fragments import android.os.Bundle -import android.view.* +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup import androidx.fragment.app.Fragment import bou.amine.apps.readerforselfossv2.android.databinding.FragmentImageBinding import com.bumptech.glide.Glide diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/settings/SettingsActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/settings/SettingsActivity.kt index f4382ce..f39c198 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/settings/SettingsActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/settings/SettingsActivity.kt @@ -3,22 +3,26 @@ package bou.amine.apps.readerforselfossv2.android.settings import android.content.Intent import android.net.Uri import android.os.Bundle -import android.text.* -import androidx.preference.EditTextPreference -import androidx.preference.PreferenceManager -import android.view.* +import android.text.Editable +import android.text.InputFilter +import android.text.InputType +import android.text.TextWatcher +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.widget.addTextChangedListener +import androidx.preference.EditTextPreference import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat +import androidx.preference.PreferenceManager import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySettingsBinding +import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.themes.Toppings -import bou.amine.apps.readerforselfossv2.android.utils.Config +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import com.ftinc.scoop.Scoop -import com.russhwolf.settings.Settings -import java.lang.NumberFormatException private const val TITLE_TAG = "settingsActivityTitle" @@ -174,12 +178,7 @@ class SettingsActivity : AppCompatActivity(), override fun onOptionsItemSelected(item: MenuItem): Boolean { val id = item.itemId if (id == R.id.clear) { - val settings = Settings() - settings.remove("color_primary") - settings.remove("color_primary_dark") - settings.remove("color_accent") - settings.remove("color_accent_dark") - settings.remove("dark_theme") + AppColors.resetColors() requireActivity().recreate() } return super.onOptionsItemSelected(item) @@ -196,17 +195,17 @@ class SettingsActivity : AppCompatActivity(), setPreferencesFromResource(R.xml.pref_links, rootKey) preferenceManager.findPreference("trackerLink")?.onPreferenceClickListener = Preference.OnPreferenceClickListener { - openUrl(Uri.parse(Config.trackerUrl)) + openUrl(Uri.parse(AppSettingsService.trackerUrl)) true } preferenceManager.findPreference("sourceLink")?.onPreferenceClickListener = Preference.OnPreferenceClickListener { - openUrl(Uri.parse(Config.sourceUrl)) + openUrl(Uri.parse(AppSettingsService.sourceUrl)) false } preferenceManager.findPreference("translation")?.onPreferenceClickListener = Preference.OnPreferenceClickListener { - openUrl(Uri.parse(Config.translationUrl)) + openUrl(Uri.parse(AppSettingsService.translationUrl)) false } } @@ -217,4 +216,11 @@ class SettingsActivity : AppCompatActivity(), setPreferencesFromResource(R.xml.pref_experimental, rootKey) } } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + android.R.id.home -> super.onBackPressed() + } + return super.onOptionsItemSelected(item) + } } \ No newline at end of file diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/themes/AppColors.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/themes/AppColors.kt index 78db5a6..bd01677 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/themes/AppColors.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/themes/AppColors.kt @@ -58,4 +58,15 @@ class AppColors(a: Activity) { a.resources.getColor(R.color.grey_900) } } + + companion object { + fun resetColors() { + val settings = Settings() + settings.remove("color_primary") + settings.remove("color_primary_dark") + settings.remove("color_accent") + settings.remove("color_accent_dark") + settings.remove("dark_theme") + } + } } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/Config.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/Config.kt deleted file mode 100644 index 9ce7ede..0000000 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/Config.kt +++ /dev/null @@ -1,62 +0,0 @@ -package bou.amine.apps.readerforselfossv2.android.utils - -import android.app.Activity -import android.content.Context -import android.content.Intent -import bou.amine.apps.readerforselfossv2.android.LoginActivity -import com.russhwolf.settings.Settings - -class Config { - - val settings = Settings() - - val baseUrl: String - get() = settings.getString("url", "") - - val userLogin: String - get() = settings.getString("login", "") - - val userPassword: String - get() = settings.getString("password", "") - - val httpUserLogin: String - get() = settings.getString("httpUserName", "") - - val httpUserPassword: String - get() = settings.getString("httpPassword", "") - - companion object { - const val settingsName = "paramsselfoss" - - const val feedbackEmail = "aminecmi@pm.me.com" - - const val translationUrl = "https://crwd.in/readerforselfoss" - - const val sourceUrl = "https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform" - - const val trackerUrl = "https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform/issues" - - const val syncChannelId = "sync-channel-id" - - const val newItemsChannelId = "new-items-channel-id" - - var apiVersion = 0 - - /* Execute logout and clear all settings to default */ - fun logoutAndRedirect( - c: Context, - callingActivity: Activity, - baseUrlFail: Boolean = false - ): Boolean { - val settings = Settings() - settings.clear() - val intent = Intent(c, LoginActivity::class.java) - if (baseUrlFail) { - intent.putExtra("baseUrlFail", baseUrlFail) - } - c.startActivity(intent) - callingActivity.finish() - return true - } - } -} diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/customtabs/CustomTabsHelper.java b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/customtabs/CustomTabsHelper.java index 5f07408..f4fe0d4 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/customtabs/CustomTabsHelper.java +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/customtabs/CustomTabsHelper.java @@ -7,15 +7,14 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; -import androidx.browser.customtabs.CustomTabsService; import android.text.TextUtils; import android.util.Log; +import androidx.browser.customtabs.CustomTabsService; +import bou.amine.apps.readerforselfossv2.android.utils.customtabs.helpers.KeepAliveService; import java.util.ArrayList; import java.util.List; -import bou.amine.apps.readerforselfossv2.android.utils.customtabs.helpers.KeepAliveService; - @SuppressWarnings("ALL") class CustomTabsHelper { private static final String TAG = "CustomTabsHelper"; diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/drawer/CustomBaseViewHolder.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/drawer/CustomBaseViewHolder.kt index 1bc0f86..569e91e 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/drawer/CustomBaseViewHolder.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/drawer/CustomBaseViewHolder.kt @@ -1,11 +1,10 @@ /* From https://github.com/mikepenz/MaterialDrawer/blob/develop/app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomBaseViewHolder.java */ package bou.amine.apps.readerforselfossv2.android.utils.drawer -import androidx.recyclerview.widget.RecyclerView import android.view.View import android.widget.ImageView import android.widget.TextView - +import androidx.recyclerview.widget.RecyclerView import bou.amine.apps.readerforselfossv2.android.R open class CustomBaseViewHolder(var view: View) : RecyclerView.ViewHolder(view) { diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt index be63485..5d91e62 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/GlideUtils.kt @@ -2,33 +2,26 @@ package bou.amine.apps.readerforselfossv2.android.utils.glide import android.content.Context import android.graphics.Bitmap -import android.graphics.drawable.Drawable -import android.util.Base64 -import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory import android.widget.ImageView -import bou.amine.apps.readerforselfossv2.android.utils.Config +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory import com.bumptech.glide.Glide -import com.bumptech.glide.RequestBuilder -import com.bumptech.glide.RequestManager -import com.bumptech.glide.load.model.GlideUrl -import com.bumptech.glide.load.model.LazyHeaders import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.target.BitmapImageViewTarget import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.InputStream -fun Context.bitmapCenterCrop(config: Config, url: String, iv: ImageView) = +fun Context.bitmapCenterCrop(url: String, iv: ImageView) = Glide.with(this) .asBitmap() - .loadMaybeBasicAuth(config, url) + .load(url) .apply(RequestOptions.centerCropTransform()) .into(iv) -fun Context.circularBitmapDrawable(config: Config, url: String, iv: ImageView) = +fun Context.circularBitmapDrawable(url: String, iv: ImageView) = Glide.with(this) .asBitmap() - .loadMaybeBasicAuth(config, url) + .load(url) .apply(RequestOptions.centerCropTransform()) .into(object : BitmapImageViewTarget(iv) { override fun setResource(resource: Bitmap?) { @@ -41,26 +34,6 @@ fun Context.circularBitmapDrawable(config: Config, url: String, iv: ImageView) = } }) -fun RequestBuilder.loadMaybeBasicAuth(config: Config, url: String): RequestBuilder { - val builder: LazyHeaders.Builder = LazyHeaders.Builder() - if (config.httpUserLogin.isNotEmpty() || config.httpUserPassword.isNotEmpty()) { - val basicAuth = "Basic " + Base64.encodeToString("${config.httpUserLogin}:${config.httpUserPassword}".toByteArray(), Base64.NO_WRAP) - builder.addHeader("Authorization", basicAuth) - } - val glideUrl = GlideUrl(url, builder.build()) - return this.load(glideUrl) -} - -fun RequestManager.loadMaybeBasicAuth(config: Config, url: String): RequestBuilder { - val builder: LazyHeaders.Builder = LazyHeaders.Builder() - if (config.httpUserLogin.isNotEmpty() || config.httpUserPassword.isNotEmpty()) { - val basicAuth = "Basic " + Base64.encodeToString("${config.httpUserLogin}:${config.httpUserPassword}".toByteArray(), Base64.NO_WRAP) - builder.addHeader("Authorization", basicAuth) - } - val glideUrl = GlideUrl(url, builder.build()) - return this.load(glideUrl) -} - fun getBitmapInputStream(bitmap:Bitmap,compressFormat: Bitmap.CompressFormat): InputStream { val byteArrayOutputStream = ByteArrayOutputStream() bitmap.compress(compressFormat, 80, byteArrayOutputStream) diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/SelfSignedGlideModule.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/SelfSignedGlideModule.kt deleted file mode 100644 index 999a130..0000000 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/SelfSignedGlideModule.kt +++ /dev/null @@ -1,33 +0,0 @@ -package bou.amine.apps.readerforselfossv2.android.utils.glide - -import android.content.Context -import bou.amine.apps.readerforselfossv2.android.utils.getUnsafeHttpClient -import com.bumptech.glide.Glide -import com.bumptech.glide.GlideBuilder -import com.bumptech.glide.Registry -import com.bumptech.glide.load.model.GlideUrl -import com.bumptech.glide.module.GlideModule -import com.russhwolf.settings.Settings -import java.io.InputStream - -class SelfSignedGlideModule : GlideModule { - - override fun applyOptions(context: Context?, builder: GlideBuilder?) { - } - - override fun registerComponents(context: Context?, glide: Glide?, registry: Registry?) { - - if (context != null) { - val settings = Settings() - if (settings.getBoolean("isSelfSignedCert", false)) { - val client = getUnsafeHttpClient().build() - - registry?.append( - GlideUrl::class.java, - InputStream::class.java, - com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader.Factory(client) - ) - } - } - } -} \ No newline at end of file diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/viewmodel/AppViewModel.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/viewmodel/AppViewModel.kt index 018900e..affba80 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/viewmodel/AppViewModel.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/viewmodel/AppViewModel.kt @@ -2,7 +2,6 @@ package bou.amine.apps.readerforselfossv2.android.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.repository.Repository import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow diff --git a/androidApp/src/main/res/drawable/ic_bug_report_white_24dp.xml b/androidApp/src/main/res/drawable/ic_bug_report_white_24dp.xml deleted file mode 100644 index 5c8f5bc..0000000 --- a/androidApp/src/main/res/drawable/ic_bug_report_white_24dp.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/androidApp/src/main/res/drawable/ic_color_lens_white_24dp.xml b/androidApp/src/main/res/drawable/ic_color_lens_white_24dp.xml deleted file mode 100644 index 4abeea5..0000000 --- a/androidApp/src/main/res/drawable/ic_color_lens_white_24dp.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/androidApp/src/main/res/layout/activity_login.xml b/androidApp/src/main/res/layout/activity_login.xml index 7887f3d..4c37ea3 100644 --- a/androidApp/src/main/res/layout/activity_login.xml +++ b/androidApp/src/main/res/layout/activity_login.xml @@ -82,45 +82,6 @@ android:maxLines="1" android:visibility="gone" /> - - - - - - - - - -