Immediately update bottom badges after reading or starring articles #91
@ -18,6 +18,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.view.doOnNextLayout
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.*
|
||||
import androidx.work.Constraints
|
||||
import androidx.work.ExistingPeriodicWorkPolicy
|
||||
@ -178,8 +179,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
||||
|
||||
adapter.handleItemAtIndex(position)
|
||||
|
||||
reloadBadgeContent()
|
||||
|
||||
val tagHashes = i.tags.map { it.longHash() }
|
||||
tagsBadge = tagsBadge.map {
|
||||
if (tagHashes.contains(it.key)) {
|
||||
@ -207,6 +206,16 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
||||
ItemTouchHelper(simpleItemTouchCallback).attachToRecyclerView(binding.recyclerView)
|
||||
}
|
||||
|
||||
private fun updateBottomBarBadgeCount(badge: TextBadgeItem, count: Int) {
|
||||
if (count > 0) {
|
||||
badge
|
||||
.setText(count.toString())
|
||||
.maybeShow()
|
||||
} else {
|
||||
badge.removeBadge()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleBottomBar() {
|
||||
|
||||
tabNewBadge = TextBadgeItem()
|
||||
@ -219,6 +228,28 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
||||
.setText("")
|
||||
.setHideOnSelect(false).hide(false)
|
||||
|
||||
if (appSettingsService.isDisplayUnreadCountEnabled()) {
|
||||
lifecycleScope.launch {
|
||||
repository.badgeUnread.collect {
|
||||
updateBottomBarBadgeCount(tabNewBadge, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (appSettingsService.isDisplayAllCountEnabled()) {
|
||||
lifecycleScope.launch {
|
||||
repository.badgeAll.collect {
|
||||
updateBottomBarBadgeCount(tabArchiveBadge, it)
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
repository.badgeStarred.collect {
|
||||
updateBottomBarBadgeCount(tabStarredBadge, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val tabNew =
|
||||
BottomNavigationItem(
|
||||
R.drawable.ic_tab_fiber_new_black_24dp,
|
||||
@ -714,29 +745,12 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
||||
|
||||
private fun reloadBadges() {
|
||||
if (appSettingsService.isDisplayUnreadCountEnabled() || appSettingsService.isDisplayAllCountEnabled()) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
repository.reloadBadges()
|
||||
reloadBadgeContent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun reloadBadgeContent() {
|
||||
if (appSettingsService.isDisplayUnreadCountEnabled()) {
|
||||
tabNewBadge
|
||||
.setText(repository.badgeUnread.toString())
|
||||
.maybeShow()
|
||||
}
|
||||
if (appSettingsService.isDisplayAllCountEnabled()) {
|
||||
tabArchiveBadge
|
||||
.setText(repository.badgeAll.toString())
|
||||
.maybeShow()
|
||||
tabStarredBadge
|
||||
.setText(repository.badgeStarred.toString())
|
||||
.maybeShow()
|
||||
}
|
||||
}
|
||||
|
||||
private fun reloadTagsBadges() {
|
||||
tagsBadge.forEach {
|
||||
binding.mainDrawer.updateBadge(it.key, StringHolder(it.value.toString()))
|
||||
@ -858,10 +872,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
||||
|
||||
private fun maxItemNumber(): Int =
|
||||
when (elementsShown) {
|
||||
ItemType.UNREAD -> repository.badgeUnread
|
||||
ItemType.ALL -> repository.badgeAll
|
||||
ItemType.STARRED -> repository.badgeStarred
|
||||
else -> repository.badgeUnread // if !elementsShown then unread are fetched.
|
||||
ItemType.UNREAD -> repository.badgeUnread.value
|
||||
ItemType.ALL -> repository.badgeAll.value
|
||||
ItemType.STARRED -> repository.badgeStarred.value
|
||||
else -> repository.badgeUnread.value // if !elementsShown then unread are fetched.
|
||||
}
|
||||
|
||||
private fun updateItems(adapterItems: ArrayList<SelfossModel.Item>) {
|
||||
|
@ -111,13 +111,11 @@ class ItemCardAdapter(
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
repository.unstarr(item)
|
||||
}
|
||||
item.starred = false
|
||||
binding.favButton.isSelected = false
|
||||
} else {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
repository.starr(item)
|
||||
}
|
||||
item.starred = true
|
||||
binding.favButton.isSelected = true
|
||||
}
|
||||
}
|
||||
|
@ -299,9 +299,9 @@ class RepositoryTest {
|
||||
}
|
||||
|
||||
assertSame(true, success)
|
||||
assertSame(NUMBER_ARTICLES, repository.badgeAll)
|
||||
assertSame(NUMBER_UNREAD, repository.badgeUnread)
|
||||
assertSame(NUMBER_STARRED, repository.badgeStarred)
|
||||
assertEquals(NUMBER_ARTICLES, repository.badgeAll.value)
|
||||
assertEquals(NUMBER_UNREAD, repository.badgeUnread.value)
|
||||
assertEquals(NUMBER_STARRED, repository.badgeStarred.value)
|
||||
coVerify(atLeast = 1) { api.stats() }
|
||||
verify(exactly = 0) { db.itemsQueries.items().executeAsList() }
|
||||
}
|
||||
@ -318,9 +318,9 @@ class RepositoryTest {
|
||||
}
|
||||
|
||||
assertSame(false, success)
|
||||
assertSame(0, repository.badgeAll)
|
||||
assertSame(0, repository.badgeUnread)
|
||||
assertSame(0, repository.badgeStarred)
|
||||
assertSame(0, repository.badgeAll.value)
|
||||
assertSame(0, repository.badgeUnread.value)
|
||||
assertSame(0, repository.badgeStarred.value)
|
||||
coVerify(atLeast = 1) { api.stats() }
|
||||
verify(exactly = 0) { db.itemsQueries.items().executeAsList() }
|
||||
}
|
||||
@ -338,9 +338,9 @@ class RepositoryTest {
|
||||
}
|
||||
|
||||
assertTrue(success)
|
||||
assertSame(1, repository.badgeAll)
|
||||
assertSame(1, repository.badgeUnread)
|
||||
assertSame(1, repository.badgeStarred)
|
||||
assertEquals(1, repository.badgeAll.value)
|
||||
assertEquals(1, repository.badgeUnread.value)
|
||||
assertEquals(1, repository.badgeStarred.value)
|
||||
coVerify(exactly = 0) { api.stats() }
|
||||
verify(atLeast = 1) { db.itemsQueries.items().executeAsList() }
|
||||
}
|
||||
@ -358,9 +358,9 @@ class RepositoryTest {
|
||||
}
|
||||
|
||||
assertFalse(success)
|
||||
assertSame(0, repository.badgeAll)
|
||||
assertSame(0, repository.badgeUnread)
|
||||
assertSame(0, repository.badgeStarred)
|
||||
assertSame(0, repository.badgeAll.value)
|
||||
assertSame(0, repository.badgeUnread.value)
|
||||
assertSame(0, repository.badgeStarred.value)
|
||||
coVerify(exactly = 0) { api.stats() }
|
||||
verify(exactly = 0) { db.itemsQueries.items().executeAsList() }
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import io.github.aakira.napier.Napier
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class Repository(private val api: SelfossApi, private val appSettingsService: AppSettingsService, val isConnectionAvailable: MutableStateFlow<Boolean>, private val db: ReaderForSelfossDB) {
|
||||
@ -27,12 +28,12 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
|
||||
var offlineOverride = false
|
||||
|
||||
var badgeUnread = 0
|
||||
set(value) {field = if (value < 0) { 0 } else { value } }
|
||||
var badgeAll = 0
|
||||
set(value) {field = if (value < 0) { 0 } else { value } }
|
||||
var badgeStarred = 0
|
||||
set(value) {field = if (value < 0) { 0 } else { value } }
|
||||
private val _badgeUnread = MutableStateFlow(0)
|
||||
val badgeUnread = _badgeUnread.asStateFlow()
|
||||
private val _badgeAll = MutableStateFlow(0)
|
||||
val badgeAll = _badgeAll.asStateFlow()
|
||||
private val _badgeStarred = MutableStateFlow(0)
|
||||
val badgeStarred = _badgeStarred.asStateFlow()
|
||||
|
||||
private var fetchedSources = false
|
||||
private var fetchedTags = false
|
||||
@ -125,17 +126,17 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
if (isNetworkAvailable()) {
|
||||
val response = api.stats()
|
||||
if (response.success && response.data != null) {
|
||||
badgeUnread = response.data.unread
|
||||
badgeAll = response.data.total
|
||||
badgeStarred = response.data.starred
|
||||
_badgeUnread.value = response.data.unread
|
||||
_badgeAll.value = response.data.total
|
||||
_badgeStarred.value = response.data.starred
|
||||
success = true
|
||||
}
|
||||
} else if (appSettingsService.isItemCachingEnabled()) {
|
||||
// TODO: do this differently, because it's not efficient
|
||||
val dbItems = getDBItems()
|
||||
badgeUnread = dbItems.filter { item -> item.unread }.size
|
||||
badgeStarred = dbItems.filter { item -> item.starred }.size
|
||||
badgeAll = dbItems.size
|
||||
_badgeUnread.value = dbItems.filter { item -> item.unread }.size
|
||||
_badgeStarred.value = dbItems.filter { item -> item.starred }.size
|
||||
_badgeAll.value = dbItems.size
|
||||
success = true
|
||||
}
|
||||
return success
|
||||
@ -283,7 +284,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
private fun markAsReadLocally(item: SelfossModel.Item) {
|
||||
if (item.unread) {
|
||||
item.unread = false
|
||||
badgeUnread -= 1
|
||||
_badgeUnread.value -= 1
|
||||
}
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -294,7 +295,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
private fun unmarkAsReadLocally(item: SelfossModel.Item) {
|
||||
if (!item.unread) {
|
||||
item.unread = true
|
||||
badgeUnread += 1
|
||||
_badgeUnread.value += 1
|
||||
}
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -305,7 +306,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
private fun starrLocally(item: SelfossModel.Item) {
|
||||
if (!item.starred) {
|
||||
item.starred = true
|
||||
badgeStarred += 1
|
||||
_badgeStarred.value += 1
|
||||
}
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -316,7 +317,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
private fun unstarrLocally(item: SelfossModel.Item) {
|
||||
if (item.starred) {
|
||||
item.starred = false
|
||||
badgeStarred -= 1
|
||||
_badgeStarred.value -= 1
|
||||
}
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
|
Loading…
Reference in New Issue
Block a user