Compare commits
	
		
			6 Commits
		
	
	
		
			updates
			...
			v172202040
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 288970483b | |||
| 5b540dbc38 | |||
| def75b6431 | |||
| 4826ed0355 | |||
| 3b47a4a2f0 | |||
| 9693dec807 | 
@@ -44,8 +44,12 @@
 | 
			
		||||
 | 
			
		||||
- Closing #236. New sources can be added in Selfoss 2.19.
 | 
			
		||||
 | 
			
		||||
- Closing #397 and #355. Tag and Sources filters are now exclusive.
 | 
			
		||||
 | 
			
		||||
- Dropped support for android 4, the last version supporting it is v1721030811
 | 
			
		||||
 | 
			
		||||
- Added ability to scroll articles up and down using the volume keys #400
 | 
			
		||||
 | 
			
		||||
**1.6.x**
 | 
			
		||||
 | 
			
		||||
- Handling hidden tags.
 | 
			
		||||
 
 | 
			
		||||
@@ -7,23 +7,20 @@ 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.pressKey
 | 
			
		||||
import androidx.test.espresso.action.ViewActions.typeText
 | 
			
		||||
import androidx.test.espresso.assertion.ViewAssertions.matches
 | 
			
		||||
import androidx.test.espresso.contrib.DrawerActions
 | 
			
		||||
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.isDisplayed
 | 
			
		||||
import androidx.test.espresso.matcher.ViewMatchers.isRoot
 | 
			
		||||
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 apps.amine.bou.readerforselfoss.utils.Config
 | 
			
		||||
import org.junit.After
 | 
			
		||||
import org.junit.Before
 | 
			
		||||
@@ -84,11 +81,14 @@ class HomeActivityEspressoTest {
 | 
			
		||||
        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), times(1))
 | 
			
		||||
        intended(hasComponent(LoginActivity::class.java.name))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: test articles opening and actions for cards and lists
 | 
			
		||||
 
 | 
			
		||||
@@ -85,7 +85,7 @@ class LoginActivityEspressoTest {
 | 
			
		||||
 | 
			
		||||
        onView(withId(R.id.signInButton)).perform(click())
 | 
			
		||||
 | 
			
		||||
        onView(withId(R.id.urlLayout)).check(matches(isHintOrErrorEnabled()))
 | 
			
		||||
        onView(withId(R.id.urlView)).check(matches(isHintOrErrorEnabled()))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: Add tests for multiple false urls with dialog
 | 
			
		||||
@@ -101,19 +101,19 @@ class LoginActivityEspressoTest {
 | 
			
		||||
 | 
			
		||||
        onView(withId(R.id.signInButton)).perform(click())
 | 
			
		||||
 | 
			
		||||
        onView(withId(R.id.loginLayout)).check(matches(isHintOrErrorEnabled()))
 | 
			
		||||
        onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled()))
 | 
			
		||||
        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.passwordLayout)).check(matches(isHintOrErrorEnabled()))
 | 
			
		||||
        onView(withId(R.id.passwordView)).check(matches(isHintOrErrorEnabled()))
 | 
			
		||||
 | 
			
		||||
        onView(withId(R.id.signInButton)).perform(click())
 | 
			
		||||
 | 
			
		||||
        onView(withId(R.id.passwordLayout)).check(
 | 
			
		||||
        onView(withId(R.id.passwordView)).check(
 | 
			
		||||
                matches(
 | 
			
		||||
                        isHintOrErrorEnabled()
 | 
			
		||||
                )
 | 
			
		||||
@@ -141,9 +141,9 @@ class LoginActivityEspressoTest {
 | 
			
		||||
 | 
			
		||||
        onView(withId(R.id.signInButton)).perform(click())
 | 
			
		||||
 | 
			
		||||
        onView(withId(R.id.urlLayout)).check(matches(isHintOrErrorEnabled()))
 | 
			
		||||
        onView(withId(R.id.loginLayout)).check(matches(isHintOrErrorEnabled()))
 | 
			
		||||
        onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled()))
 | 
			
		||||
        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
 | 
			
		||||
@@ -167,6 +167,7 @@ class LoginActivityEspressoTest {
 | 
			
		||||
 | 
			
		||||
        onView(withId(R.id.signInButton)).perform(click())
 | 
			
		||||
 | 
			
		||||
        Thread.sleep(2000)
 | 
			
		||||
        intended(hasComponent(HomeActivity::class.java.name))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
package apps.amine.bou.readerforselfoss
 | 
			
		||||
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import android.preference.PreferenceManager
 | 
			
		||||
@@ -10,6 +11,7 @@ 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 apps.amine.bou.readerforselfoss.utils.Config
 | 
			
		||||
import org.junit.After
 | 
			
		||||
 | 
			
		||||
import org.junit.Before
 | 
			
		||||
@@ -22,6 +24,9 @@ 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)
 | 
			
		||||
@@ -32,31 +37,39 @@ class MainActivityEspressoTest {
 | 
			
		||||
        val context = getInstrumentation().targetContext
 | 
			
		||||
 | 
			
		||||
        // create a SharedPreferences editor
 | 
			
		||||
        preferencesEditor = PreferenceManager.getDefaultSharedPreferences(context).edit()
 | 
			
		||||
        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.putBoolean("firstStart", true)
 | 
			
		||||
        preferencesEditor.putString("url", "")
 | 
			
		||||
        preferencesEditor.putString("password", "")
 | 
			
		||||
        preferencesEditor.putString("login", "")
 | 
			
		||||
        preferencesEditor.commit()
 | 
			
		||||
 | 
			
		||||
        rule.launchActivity(intent)
 | 
			
		||||
 | 
			
		||||
        intended(hasComponent(MainActivity::class.java.name))
 | 
			
		||||
        intended(hasComponent(LoginActivity::class.java.name), times(0))
 | 
			
		||||
        intended(hasComponent(LoginActivity::class.java.name))
 | 
			
		||||
        intended(hasComponent(HomeActivity::class.java.name), times(0))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun checkNotFirstOpenLaunchesLogin() {
 | 
			
		||||
        preferencesEditor.putBoolean("firstStart", false)
 | 
			
		||||
        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(LoginActivity::class.java.name))
 | 
			
		||||
        intended(hasComponent(HomeActivity::class.java.name))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @After
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
package apps.amine.bou.readerforselfoss
 | 
			
		||||
 | 
			
		||||
import com.google.android.material.textfield.TextInputLayout
 | 
			
		||||
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
 | 
			
		||||
@@ -14,11 +14,11 @@ fun isHintOrErrorEnabled(): Matcher<View> =
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            override fun matchesSafely(item: View?): Boolean {
 | 
			
		||||
                if (item !is TextInputLayout) {
 | 
			
		||||
                if (item !is EditText) {
 | 
			
		||||
                    return false
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return item.isHintEnabled || item.isErrorEnabled
 | 
			
		||||
                return item.error.isNotEmpty()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
package apps.amine.bou.readerforselfoss
 | 
			
		||||
package apps.amine.bou.readerforselfoss.utils
 | 
			
		||||
 | 
			
		||||
import apps.amine.bou.readerforselfoss.utils.Config
 | 
			
		||||
import apps.amine.bou.readerforselfoss.utils.parseDate
 | 
			
		||||
import org.junit.Test
 | 
			
		||||
 | 
			
		||||
class DateUtilsTest {
 | 
			
		||||
@@ -18,7 +18,6 @@ import androidx.appcompat.app.ActionBarDrawerToggle
 | 
			
		||||
import androidx.appcompat.app.AlertDialog
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity
 | 
			
		||||
import androidx.appcompat.widget.SearchView
 | 
			
		||||
import androidx.core.view.MenuItemCompat
 | 
			
		||||
import androidx.core.view.doOnNextLayout
 | 
			
		||||
import androidx.drawerlayout.widget.DrawerLayout
 | 
			
		||||
import androidx.recyclerview.widget.*
 | 
			
		||||
@@ -101,9 +100,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
    private var fullHeightCards: Boolean = false
 | 
			
		||||
    private var itemsNumber: Int = 200
 | 
			
		||||
    private var elementsShown: Int = 1
 | 
			
		||||
    private var maybeTagFilter: Tag? = null
 | 
			
		||||
    private var maybeSourceFilter: Source? = null
 | 
			
		||||
    private var maybeSearchFilter: String? = null
 | 
			
		||||
    private var userIdentifier: String = ""
 | 
			
		||||
    private var displayAccountHeader: Boolean = false
 | 
			
		||||
    private var infiniteScroll: Boolean = false
 | 
			
		||||
@@ -220,7 +216,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
            lastFetchDone = false
 | 
			
		||||
            handleDrawerItems()
 | 
			
		||||
            CoroutineScope(Dispatchers.Main).launch {
 | 
			
		||||
                refreshFocusedItems(applicationContext, api, db)
 | 
			
		||||
                refreshFocusedItems(applicationContext, api, db, itemsNumber)
 | 
			
		||||
                getElementsAccordingToTab()
 | 
			
		||||
                binding.swipeRefreshLayout.isRefreshing = false
 | 
			
		||||
            }
 | 
			
		||||
@@ -251,7 +247,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
                ): Boolean = false
 | 
			
		||||
 | 
			
		||||
                override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
 | 
			
		||||
                    val position = viewHolder.adapterPosition
 | 
			
		||||
                    val position = viewHolder.bindingAdapterPosition
 | 
			
		||||
                    val i = items.elementAtOrNull(position)
 | 
			
		||||
 | 
			
		||||
                    if (i != null) {
 | 
			
		||||
@@ -563,8 +559,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
                                        color = ColorHolder.fromColor(appColors.colorAccent) }
 | 
			
		||||
                                    onDrawerItemClickListener = { _,_,_ ->
 | 
			
		||||
                                        allItems = ArrayList()
 | 
			
		||||
                                        maybeTagFilter = it
 | 
			
		||||
                                        SharedItems.tagFilter = it.tag
 | 
			
		||||
                                        SharedItems.sourceFilter = null
 | 
			
		||||
                                        SharedItems.sourceIDFilter = null
 | 
			
		||||
                                        getElementsAccordingToTab()
 | 
			
		||||
                                        fetchOnEmptyList()
 | 
			
		||||
                                        false
 | 
			
		||||
@@ -615,8 +612,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
                                    color = ColorHolder.fromColor(appColors.colorAccent) }
 | 
			
		||||
                                onDrawerItemClickListener = { _,_,_ ->
 | 
			
		||||
                                    allItems = ArrayList()
 | 
			
		||||
                                    maybeTagFilter = it
 | 
			
		||||
                                    SharedItems.tagFilter = it.tag
 | 
			
		||||
                                    SharedItems.sourceFilter = null
 | 
			
		||||
                                    SharedItems.sourceIDFilter = null
 | 
			
		||||
                                    getElementsAccordingToTab()
 | 
			
		||||
                                    fetchOnEmptyList()
 | 
			
		||||
                                    false
 | 
			
		||||
@@ -650,9 +648,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
                            iconUrl = source.getIcon(this@HomeActivity)
 | 
			
		||||
                            onDrawerItemClickListener = { _,_,_ ->
 | 
			
		||||
                                allItems = ArrayList()
 | 
			
		||||
                                maybeSourceFilter = source
 | 
			
		||||
                                SharedItems.sourceIDFilter = source.id.toLong()
 | 
			
		||||
                                SharedItems.sourceFilter = source.title
 | 
			
		||||
                                SharedItems.tagFilter = null
 | 
			
		||||
                                getElementsAccordingToTab()
 | 
			
		||||
                                fetchOnEmptyList()
 | 
			
		||||
                                false
 | 
			
		||||
@@ -673,11 +671,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
                        badgeRes = R.string.drawer_action_clear
 | 
			
		||||
                        onDrawerItemClickListener = { _,_,_ ->
 | 
			
		||||
                            allItems = ArrayList()
 | 
			
		||||
                            maybeSourceFilter = null
 | 
			
		||||
                            SharedItems.sourceFilter = null
 | 
			
		||||
                            SharedItems.sourceIDFilter = null
 | 
			
		||||
                            maybeTagFilter = null
 | 
			
		||||
                            SharedItems.tagFilter = null
 | 
			
		||||
                            binding.mainDrawer.setSelectionAtPosition(-1)
 | 
			
		||||
                            getElementsAccordingToTab()
 | 
			
		||||
                            fetchOnEmptyList()
 | 
			
		||||
                            false
 | 
			
		||||
@@ -984,7 +981,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
        CoroutineScope(Dispatchers.Main).launch {
 | 
			
		||||
            if (appendResults || !SharedItems.fetchedUnread) {
 | 
			
		||||
                binding.swipeRefreshLayout.isRefreshing = true
 | 
			
		||||
                getUnreadItems(applicationContext, api, db, offset)
 | 
			
		||||
                getUnreadItems(applicationContext, api, db, itemsNumber, offset)
 | 
			
		||||
                binding.swipeRefreshLayout.isRefreshing = false
 | 
			
		||||
            }
 | 
			
		||||
            SharedItems.getUnRead()
 | 
			
		||||
@@ -997,7 +994,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
        CoroutineScope(Dispatchers.Main).launch {
 | 
			
		||||
            if (appendResults || !SharedItems.fetchedAll) {
 | 
			
		||||
                binding.swipeRefreshLayout.isRefreshing = true
 | 
			
		||||
                getReadItems(applicationContext, api, db, offset)
 | 
			
		||||
                getReadItems(applicationContext, api, db, itemsNumber, offset)
 | 
			
		||||
                binding.swipeRefreshLayout.isRefreshing = false
 | 
			
		||||
            }
 | 
			
		||||
            SharedItems.getAll()
 | 
			
		||||
@@ -1010,7 +1007,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
        CoroutineScope(Dispatchers.Main).launch {
 | 
			
		||||
            if (appendResults || !SharedItems.fetchedStarred) {
 | 
			
		||||
                binding.swipeRefreshLayout.isRefreshing = true
 | 
			
		||||
                getStarredItems(applicationContext, api, db, offset)
 | 
			
		||||
                getStarredItems(applicationContext, api, db, itemsNumber, offset)
 | 
			
		||||
                binding.swipeRefreshLayout.isRefreshing = false
 | 
			
		||||
            }
 | 
			
		||||
            SharedItems.getStarred()
 | 
			
		||||
@@ -1122,7 +1119,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
 | 
			
		||||
    override fun onQueryTextChange(p0: String?): Boolean {
 | 
			
		||||
        if (p0.isNullOrBlank()) {
 | 
			
		||||
            maybeSearchFilter = null
 | 
			
		||||
            SharedItems.searchFilter = null
 | 
			
		||||
            getElementsAccordingToTab()
 | 
			
		||||
            fetchOnEmptyList()
 | 
			
		||||
@@ -1131,29 +1127,18 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onQueryTextSubmit(p0: String?): Boolean {
 | 
			
		||||
        maybeSearchFilter = p0
 | 
			
		||||
        SharedItems.searchFilter = p0
 | 
			
		||||
        getElementsAccordingToTab()
 | 
			
		||||
        fetchOnEmptyList()
 | 
			
		||||
        return false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onActivityResult(req: Int, result: Int, data: Intent?) {
 | 
			
		||||
        when (req) {
 | 
			
		||||
            MENU_PREFERENCES -> {
 | 
			
		||||
                //drawer.closeDrawer()
 | 
			
		||||
                recreate()
 | 
			
		||||
            }
 | 
			
		||||
            else -> super.onActivityResult(req, result, data)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
 | 
			
		||||
        val inflater = menuInflater
 | 
			
		||||
        inflater.inflate(R.menu.home_menu, menu)
 | 
			
		||||
 | 
			
		||||
        val searchItem = menu.findItem(R.id.action_search)
 | 
			
		||||
        val searchView = MenuItemCompat.getActionView(searchItem) as SearchView
 | 
			
		||||
        val searchView = searchItem.getActionView() as SearchView
 | 
			
		||||
        searchView.setOnQueryTextListener(this)
 | 
			
		||||
 | 
			
		||||
        return true
 | 
			
		||||
@@ -1268,8 +1253,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
 | 
			
		||||
                    .addTag("selfoss-loading")
 | 
			
		||||
                    .build()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            WorkManager.getInstance().enqueueUniquePeriodicWork("selfoss-loading", ExistingPeriodicWorkPolicy.KEEP, backgroundWork)
 | 
			
		||||
            WorkManager.getInstance(baseContext).enqueueUniquePeriodicWork("selfoss-loading", ExistingPeriodicWorkPolicy.KEEP, backgroundWork)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import android.content.Context
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import android.graphics.Color
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.view.KeyEvent
 | 
			
		||||
import androidx.preference.PreferenceManager
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity
 | 
			
		||||
import android.view.Menu
 | 
			
		||||
@@ -135,13 +136,30 @@ class ReaderActivity : AppCompatActivity() {
 | 
			
		||||
    private inner class ScreenSlidePagerAdapter(fa: FragmentActivity) :
 | 
			
		||||
        FragmentStateAdapter(fa) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        override fun getItemCount(): Int = allItems.size
 | 
			
		||||
 | 
			
		||||
        override fun createFragment(position: Int): Fragment = ArticleFragment.newInstance(allItems[position])
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
 | 
			
		||||
        return when (keyCode) {
 | 
			
		||||
            KeyEvent.KEYCODE_VOLUME_DOWN -> {
 | 
			
		||||
                val currentFragment = supportFragmentManager.findFragmentByTag("f" + binding.pager.currentItem) as ArticleFragment
 | 
			
		||||
                currentFragment.scrollDown()
 | 
			
		||||
                true
 | 
			
		||||
            }
 | 
			
		||||
            KeyEvent.KEYCODE_VOLUME_UP -> {
 | 
			
		||||
                val currentFragment = supportFragmentManager.findFragmentByTag("f" + binding.pager.currentItem) as ArticleFragment
 | 
			
		||||
                currentFragment.scrollUp()
 | 
			
		||||
                true
 | 
			
		||||
            }
 | 
			
		||||
            else -> {
 | 
			
		||||
                super.onKeyDown(keyCode, event)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun alignmentMenu(showJustify: Boolean) {
 | 
			
		||||
        toolbarMenu.findItem(R.id.align_left).isVisible = !showJustify
 | 
			
		||||
        toolbarMenu.findItem(R.id.align_justify).isVisible = showJustify
 | 
			
		||||
 
 | 
			
		||||
@@ -39,13 +39,13 @@ suspend fun updateItems(context: Context, api: SelfossApi, db: AppDatabase) = co
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
suspend fun refreshFocusedItems(context: Context, api: SelfossApi, db: AppDatabase) = withContext(Dispatchers.IO) {
 | 
			
		||||
suspend fun refreshFocusedItems(context: Context, api: SelfossApi, db: AppDatabase, itemsNumber: Int) = withContext(Dispatchers.IO) {
 | 
			
		||||
    if (isNetworkAvailable(context)) {
 | 
			
		||||
        val response = when (SharedItems.displayedItems) {
 | 
			
		||||
            "read" -> api.readItems(200, 0)
 | 
			
		||||
            "unread" -> api.newItems(200, 0)
 | 
			
		||||
            "starred" -> api.starredItems(200, 0)
 | 
			
		||||
            else -> api.readItems(200, 0)
 | 
			
		||||
            "read" -> api.readItems(itemsNumber, 0)
 | 
			
		||||
            "unread" -> api.newItems(itemsNumber, 0)
 | 
			
		||||
            "starred" -> api.starredItems(itemsNumber, 0)
 | 
			
		||||
            else -> api.readItems(itemsNumber, 0)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (response.isSuccessful) {
 | 
			
		||||
@@ -55,33 +55,33 @@ suspend fun refreshFocusedItems(context: Context, api: SelfossApi, db: AppDataba
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
suspend fun getReadItems(context: Context, api: SelfossApi, db: AppDatabase, offset: Int) = withContext(Dispatchers.IO) {
 | 
			
		||||
suspend fun getReadItems(context: Context, api: SelfossApi, db: AppDatabase, itemsNumber: Int, offset: Int) = withContext(Dispatchers.IO) {
 | 
			
		||||
    if (isNetworkAvailable(context)) {
 | 
			
		||||
            try {
 | 
			
		||||
                enqueueArticles(api.readItems( 200, offset), db, false)
 | 
			
		||||
                enqueueArticles(api.readItems( itemsNumber, offset), db, false)
 | 
			
		||||
                SharedItems.fetchedAll = true
 | 
			
		||||
                SharedItems.updateDatabase(db)
 | 
			
		||||
            } catch (e: Throwable) {}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
suspend fun getUnreadItems(context: Context, api: SelfossApi, db: AppDatabase, offset: Int) = withContext(Dispatchers.IO) {
 | 
			
		||||
suspend fun getUnreadItems(context: Context, api: SelfossApi, db: AppDatabase, itemsNumber: Int, offset: Int) = withContext(Dispatchers.IO) {
 | 
			
		||||
    if (isNetworkAvailable(context)) {
 | 
			
		||||
        try {
 | 
			
		||||
            if (!SharedItems.fetchedUnread) {
 | 
			
		||||
                SharedItems.clearDBItems(db)
 | 
			
		||||
            }
 | 
			
		||||
            enqueueArticles(api.newItems(200, offset), db, false)
 | 
			
		||||
            enqueueArticles(api.newItems(itemsNumber, offset), db, false)
 | 
			
		||||
            SharedItems.fetchedUnread = true
 | 
			
		||||
        } catch (e: Throwable) {}
 | 
			
		||||
    }
 | 
			
		||||
    SharedItems.updateDatabase(db)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
suspend fun getStarredItems(context: Context, api: SelfossApi, db: AppDatabase, offset: Int) = withContext(Dispatchers.IO) {
 | 
			
		||||
suspend fun getStarredItems(context: Context, api: SelfossApi, db: AppDatabase, itemsNumber: Int, offset: Int) = withContext(Dispatchers.IO) {
 | 
			
		||||
    if (isNetworkAvailable(context)) {
 | 
			
		||||
        try {
 | 
			
		||||
            enqueueArticles(api.starredItems(200, offset), db, false)
 | 
			
		||||
            enqueueArticles(api.starredItems(itemsNumber, offset), db, false)
 | 
			
		||||
            SharedItems.fetchedStarred = true
 | 
			
		||||
            SharedItems.updateDatabase(db)
 | 
			
		||||
        } catch (e: Throwable) {
 | 
			
		||||
 
 | 
			
		||||
@@ -511,6 +511,16 @@ class ArticleFragment : Fragment() {
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun scrollDown() {
 | 
			
		||||
        val height = binding.nestedScrollView.measuredHeight
 | 
			
		||||
        binding.nestedScrollView.smoothScrollBy(0, height/2)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun scrollUp() {
 | 
			
		||||
        val height = binding.nestedScrollView.measuredHeight
 | 
			
		||||
        binding.nestedScrollView.smoothScrollBy(0, -height/2)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun openInBrowserAfterFailing(customTabsIntent: CustomTabsIntent) {
 | 
			
		||||
        binding.progressBar.visibility = View.GONE
 | 
			
		||||
        requireActivity().openItemUrlInternalBrowser(
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user