Application update indicator
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
package org.koitharu.kotatsu.core.ui.util
|
||||
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import com.google.android.material.badge.BadgeDrawable
|
||||
import com.google.android.material.badge.BadgeUtils
|
||||
import com.google.android.material.badge.ExperimentalBadgeUtils
|
||||
|
||||
@androidx.annotation.OptIn(ExperimentalBadgeUtils::class)
|
||||
class OptionsMenuBadgeHelper(
|
||||
private val toolbar: Toolbar,
|
||||
@IdRes private val itemId: Int,
|
||||
) {
|
||||
|
||||
private var badge: BadgeDrawable? = null
|
||||
|
||||
fun setBadgeVisible(isVisible: Boolean) {
|
||||
if (isVisible) {
|
||||
showBadge()
|
||||
} else {
|
||||
hideBadge()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideBadge() {
|
||||
badge?.let {
|
||||
BadgeUtils.detachBadgeDrawable(it, toolbar, itemId)
|
||||
}
|
||||
badge = null
|
||||
}
|
||||
|
||||
private fun showBadge() {
|
||||
val badgeDrawable = badge ?: BadgeDrawable.create(toolbar.context).also {
|
||||
badge = it
|
||||
}
|
||||
BadgeUtils.attachBadgeDrawable(badgeDrawable, toolbar, itemId)
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,7 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.core.ui.util.OptionsMenuBadgeHelper
|
||||
import org.koitharu.kotatsu.core.ui.widgets.SlidingBottomNavigationView
|
||||
import org.koitharu.kotatsu.core.util.ext.hideKeyboard
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
@@ -63,6 +64,7 @@ import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionFragment
|
||||
import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener
|
||||
import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionViewModel
|
||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||
import org.koitharu.kotatsu.settings.about.AppUpdateDialog
|
||||
import org.koitharu.kotatsu.settings.newsources.NewSourcesDialogFragment
|
||||
import org.koitharu.kotatsu.settings.onboard.OnboardDialogFragment
|
||||
import javax.inject.Inject
|
||||
@@ -81,6 +83,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
|
||||
private val searchSuggestionViewModel by viewModels<SearchSuggestionViewModel>()
|
||||
private val closeSearchCallback = CloseSearchCallback()
|
||||
private lateinit var navigationDelegate: MainNavigationDelegate
|
||||
private lateinit var appUpdateBadge: OptionsMenuBadgeHelper
|
||||
|
||||
override val appBar: AppBarLayout
|
||||
get() = viewBinding.appbar
|
||||
@@ -119,6 +122,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
|
||||
navigationDelegate.addOnFragmentChangedListener(this)
|
||||
navigationDelegate.onCreate()
|
||||
|
||||
appUpdateBadge = OptionsMenuBadgeHelper(viewBinding.toolbar, R.id.action_app_update)
|
||||
|
||||
onBackPressedDispatcher.addCallback(ExitCallback(this, viewBinding.container))
|
||||
onBackPressedDispatcher.addCallback(navigationDelegate)
|
||||
onBackPressedDispatcher.addCallback(closeSearchCallback)
|
||||
@@ -132,6 +137,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
|
||||
viewModel.isLoading.observe(this, this::onLoadingStateChanged)
|
||||
viewModel.isResumeEnabled.observe(this, this::onResumeEnabledChanged)
|
||||
viewModel.counters.observe(this, ::onCountersChanged)
|
||||
viewModel.appUpdate.observe(this) { invalidateMenu() }
|
||||
viewModel.isFeedAvailable.observe(this, ::onFeedAvailabilityChanged)
|
||||
searchSuggestionViewModel.isIncognitoModeEnabled.observe(this, this::onIncognitoModeChanged)
|
||||
}
|
||||
@@ -158,6 +164,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
|
||||
menu?.findItem(R.id.action_incognito)?.isChecked = searchSuggestionViewModel.isIncognitoModeEnabled.value
|
||||
val hasAppUpdate = viewModel.appUpdate.value != null
|
||||
menu?.findItem(R.id.action_app_update)?.isVisible = hasAppUpdate
|
||||
appUpdateBadge.setBadgeVisible(hasAppUpdate)
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
@@ -179,6 +188,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
|
||||
true
|
||||
}
|
||||
|
||||
R.id.action_app_update -> {
|
||||
viewModel.appUpdate.value?.also {
|
||||
AppUpdateDialog(this)
|
||||
.show(it)
|
||||
} != null
|
||||
}
|
||||
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.plus
|
||||
import org.koitharu.kotatsu.R
|
||||
@@ -46,12 +47,14 @@ class MainViewModel @Inject constructor(
|
||||
valueProducer = { isTrackerEnabled },
|
||||
)
|
||||
|
||||
val appUpdate = appUpdateRepository.observeAvailableUpdate()
|
||||
|
||||
val counters = combine(
|
||||
appUpdateRepository.observeAvailableUpdate(),
|
||||
trackingRepository.observeUpdatedMangaCount(),
|
||||
) { appUpdate, tracks ->
|
||||
flow { emit(settings.newSources) },
|
||||
) { tracks, newSources ->
|
||||
val a = SparseIntArray(2)
|
||||
// a[R.id.nav_tools] = if (appUpdate != null) 1 else 0
|
||||
a[R.id.nav_explore] = newSources.size
|
||||
a[R.id.nav_feed] = tracks
|
||||
a
|
||||
}.stateIn(
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_app_update"
|
||||
android:icon="@drawable/ic_app_update"
|
||||
android:orderInCategory="1"
|
||||
android:title="@string/update"
|
||||
android:visible="false"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_incognito"
|
||||
android:checkable="true"
|
||||
|
||||
Reference in New Issue
Block a user