From ece1e5cbe62219a9d71ef2ed27c7398e6a468e79 Mon Sep 17 00:00:00 2001 From: davidoskky Date: Thu, 26 Jan 2023 15:13:49 +0100 Subject: [PATCH 1/5] Handle public access in the home screen In public access mode we can only read articles. Disable swiping articles in the listing to read them and remove the menu items to read all articles and to access sources settings. --- .../apps/readerforselfossv2/android/HomeActivity.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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 64f9428..3b1ed43 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 @@ -114,10 +114,16 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } } + val swipeDirs = if (appSettingsService.getPublicAccess()) { + 0 + } else { + ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT + } + val simpleItemTouchCallback = object : ItemTouchHelper.SimpleCallback( 0, - ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT + swipeDirs ) { override fun getSwipeDirs( recyclerView: RecyclerView, @@ -510,6 +516,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar override fun onCreateOptionsMenu(menu: Menu): Boolean { val inflater = menuInflater inflater.inflate(R.menu.home_menu, menu) + if (appSettingsService.getPublicAccess()) { + menu.removeItem(R.id.readAll) + menu.removeItem(R.id.action_sources) + } val searchItem = menu.findItem(R.id.action_search) val searchView = searchItem.getActionView() as SearchView From 993a630d889c47529277057f57d374cf30406d66 Mon Sep 17 00:00:00 2001 From: davidoskky Date: Thu, 26 Jan 2023 15:48:54 +0100 Subject: [PATCH 2/5] Handle public access in the article reader screen Remove the favourite button from the article reader if accessing a public instance --- .../android/ReaderActivity.kt | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) 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 70ec25d..d00162e 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 @@ -137,28 +137,34 @@ class ReaderActivity : AppCompatActivity(), DIAware { inflater.inflate(R.menu.reader_menu, menu) toolbarMenu = menu - if (allItems.isNotEmpty() && allItems[currentItem].starred) { - canRemoveFromFavorite() - } else { - canFavorite() - } alignmentMenu() - binding.pager.registerOnPageChangeCallback( - object : ViewPager2.OnPageChangeCallback() { - - override fun onPageSelected(position: Int) { - super.onPageSelected(position) - - if (allItems[position].starred) { - canRemoveFromFavorite() - } else { - canFavorite() - } - readItem(allItems[position]) - } + if (appSettingsService.getPublicAccess()) { + menu.removeItem(R.id.star) + } else { + if (allItems.isNotEmpty() && allItems[currentItem].starred) { + canRemoveFromFavorite() + } else { + canFavorite() } - ) + + + binding.pager.registerOnPageChangeCallback( + object : ViewPager2.OnPageChangeCallback() { + + override fun onPageSelected(position: Int) { + super.onPageSelected(position) + + if (allItems[position].starred) { + canRemoveFromFavorite() + } else { + canFavorite() + } + readItem(allItems[position]) + } + } + ) + } return true } @@ -177,7 +183,7 @@ class ReaderActivity : AppCompatActivity(), DIAware { when (item.itemId) { android.R.id.home -> { - onBackPressed() + onBackPressedDispatcher.onBackPressed() return true } R.id.star -> { From b69e0ae6bc49c7b47f2d266e9896ffe4472540ea Mon Sep 17 00:00:00 2001 From: davidoskky Date: Thu, 26 Jan 2023 16:22:42 +0100 Subject: [PATCH 3/5] Handle public access in the article fragment Remove the button to read/unread articles --- .../android/fragments/ArticleFragment.kt | 3 +++ .../src/main/res/layout/fragment_article.xml | 5 ++--- .../src/main/res/menu/reader_toolbar_no_read.xml | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 androidApp/src/main/res/menu/reader_toolbar_no_read.xml 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 3fb842c..4dd0221 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 @@ -195,6 +195,9 @@ class ArticleFragment : Fragment(), DIAware { private fun handleFloatingToolbar(): FloatingToolbar { val floatingToolbar: FloatingToolbar = binding.floatingToolbar + if (appSettingsService.getPublicAccess()) { + floatingToolbar.setMenu(R.menu.reader_toolbar_no_read) + } floatingToolbar.attachFab(fab) floatingToolbar.background = ColorDrawable(resources.getColor(R.color.colorAccent)) diff --git a/androidApp/src/main/res/layout/fragment_article.xml b/androidApp/src/main/res/layout/fragment_article.xml index 8e6db28..664015d 100644 --- a/androidApp/src/main/res/layout/fragment_article.xml +++ b/androidApp/src/main/res/layout/fragment_article.xml @@ -83,7 +83,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintLeft_toLeftOf="parent" - android:layout_gravity="end|bottom|right"> + android:layout_gravity="end|bottom|end"> + + + + + + \ No newline at end of file From badd6bfc6d511051b9b5540c45a9a15a92ca2ac6 Mon Sep 17 00:00:00 2001 From: davidoskky Date: Thu, 26 Jan 2023 16:29:57 +0100 Subject: [PATCH 4/5] Fix broken tests --- androidApp/src/test/kotlin/RepositoryTest.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/androidApp/src/test/kotlin/RepositoryTest.kt b/androidApp/src/test/kotlin/RepositoryTest.kt index 96ef289..950b07e 100644 --- a/androidApp/src/test/kotlin/RepositoryTest.kt +++ b/androidApp/src/test/kotlin/RepositoryTest.kt @@ -20,6 +20,8 @@ import org.junit.Test private const val BASE_URL = "https://test.com/selfoss/" +private const val USERNAME = "username" + private const val SPOUT = "spouts\\rss\\fulltextrss" private const val IMAGE_URL = "b3aa8a664d08eb15d6ff1db2fa83e0d9.png" @@ -58,12 +60,13 @@ class RepositoryTest { clearAllMocks() every { appSettingsService.getApiVersion() } returns 4 every { appSettingsService.getBaseUrl() } returns BASE_URL + every { appSettingsService.getUserName() } returns USERNAME every { appSettingsService.isItemCachingEnabled() } returns false every { appSettingsService.isUpdateSourcesEnabled() } returns false coEvery { api.apiInformation() } returns StatusAndData( success = true, - data = SelfossModel.ApiInformation("2.19-ba1e8e3", "4.0.0") + data = SelfossModel.ApiInformation("2.19-ba1e8e3", "4.0.0", SelfossModel.ApiConfiguration(false, true)) ) coEvery { api.stats() } returns StatusAndData( success = true, From c4b6874e7c3647233784bc6ab94c2830d2174fb0 Mon Sep 17 00:00:00 2001 From: davidoskky Date: Thu, 26 Jan 2023 17:20:29 +0100 Subject: [PATCH 5/5] Add tests for the public access determination logic --- androidApp/src/test/kotlin/RepositoryTest.kt | 60 ++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/androidApp/src/test/kotlin/RepositoryTest.kt b/androidApp/src/test/kotlin/RepositoryTest.kt index 950b07e..ec307b9 100644 --- a/androidApp/src/test/kotlin/RepositoryTest.kt +++ b/androidApp/src/test/kotlin/RepositoryTest.kt @@ -113,6 +113,66 @@ class RepositoryTest { verify(exactly = 1) { appSettingsService.updateApiVersion(4) } } + @Test + fun get_public_access() { + every { appSettingsService.updatePublicAccess(any()) } returns Unit + coEvery { api.apiInformation() } returns StatusAndData( + success = true, + data = SelfossModel.ApiInformation("2.19-ba1e8e3", "4.0.0", SelfossModel.ApiConfiguration(true, true)) + ) + every { appSettingsService.getUserName() } returns "" + + initializeRepository() + + coVerify(exactly = 1) { api.apiInformation() } + coVerify(exactly = 1) { appSettingsService.updatePublicAccess(true) } + } + + @Test + fun get_public_access_username_not_empty() { + every { appSettingsService.updatePublicAccess(any()) } returns Unit + coEvery { api.apiInformation() } returns StatusAndData( + success = true, + data = SelfossModel.ApiInformation("2.19-ba1e8e3", "4.0.0", SelfossModel.ApiConfiguration(true, true)) + ) + every { appSettingsService.getUserName() } returns "username" + + initializeRepository() + + coVerify(exactly = 1) { api.apiInformation() } + coVerify(exactly = 0) { appSettingsService.updatePublicAccess(true) } + } + + @Test + fun get_public_access_no_auth() { + every { appSettingsService.updatePublicAccess(any()) } returns Unit + coEvery { api.apiInformation() } returns StatusAndData( + success = true, + data = SelfossModel.ApiInformation("2.19-ba1e8e3", "4.0.0", SelfossModel.ApiConfiguration(true, false)) + ) + every { appSettingsService.getUserName() } returns "" + + initializeRepository() + + coVerify(exactly = 1) { api.apiInformation() } + coVerify(exactly = 0) { appSettingsService.updatePublicAccess(true) } + } + + @Test + fun get_public_access_disabled() { + every { appSettingsService.updatePublicAccess(any()) } returns Unit + coEvery { api.apiInformation() } returns StatusAndData( + success = true, + data = SelfossModel.ApiInformation("2.19-ba1e8e3", "4.0.0", SelfossModel.ApiConfiguration(false, true)) + ) + every { appSettingsService.getUserName() } returns "" + + initializeRepository() + + coVerify(exactly = 1) { api.apiInformation() } + coVerify(exactly = 0) { appSettingsService.updatePublicAccess(true) } + } + @Test fun get_api_1_date_with_api_4_version_stored() { every { appSettingsService.getApiVersion() } returns 4