Show hint if navigation section is unavailable #751

master
Koitharu 2 years ago
parent 0e4ef32642
commit 36a74f32df
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -4,13 +4,12 @@ import androidx.annotation.DrawableRes
import androidx.annotation.IdRes import androidx.annotation.IdRes
import androidx.annotation.StringRes import androidx.annotation.StringRes
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.list.ui.model.ListModel
enum class NavItem( enum class NavItem(
@IdRes val id: Int, @IdRes val id: Int,
@StringRes val title: Int, @StringRes val title: Int,
@DrawableRes val icon: Int, @DrawableRes val icon: Int,
) : ListModel { ) {
HISTORY(R.id.nav_history, R.string.history, R.drawable.ic_history_selector), HISTORY(R.id.nav_history, R.string.history, R.drawable.ic_history_selector),
FAVORITES(R.id.nav_favorites, R.string.favourites, R.drawable.ic_favourites_selector), FAVORITES(R.id.nav_favorites, R.string.favourites, R.drawable.ic_favourites_selector),
@ -21,10 +20,6 @@ enum class NavItem(
BOOKMARKS(R.id.nav_bookmarks, R.string.bookmarks, R.drawable.ic_bookmark_selector), BOOKMARKS(R.id.nav_bookmarks, R.string.bookmarks, R.drawable.ic_bookmark_selector),
; ;
override fun areItemsTheSame(other: ListModel): Boolean {
return other is NavItem && ordinal == other.ordinal
}
fun isAvailable(settings: AppSettings): Boolean = when (this) { fun isAvailable(settings: AppSettings): Boolean = when (this) {
SUGGESTIONS -> settings.isSuggestionsEnabled SUGGESTIONS -> settings.isSuggestionsEnabled
FEED -> settings.isTrackerEnabled FEED -> settings.isTrackerEnabled

@ -7,6 +7,7 @@ import androidx.activity.OnBackPressedCallback
import androidx.annotation.IdRes import androidx.annotation.IdRes
import androidx.core.view.isEmpty import androidx.core.view.isEmpty
import androidx.core.view.iterator import androidx.core.view.iterator
import androidx.core.view.size
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
@ -180,6 +181,9 @@ class MainNavigationDelegate(
for (item in items) { for (item in items) {
menu.add(Menu.NONE, item.id, Menu.NONE, item.title) menu.add(Menu.NONE, item.id, Menu.NONE, item.title)
.setIcon(item.icon) .setIcon(item.icon)
if (menu.size >= navBar.maxItemCount) {
break
}
} }
} }

@ -12,6 +12,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.NavItem import org.koitharu.kotatsu.core.prefs.NavItem
import org.koitharu.kotatsu.core.ui.BaseViewModel import org.koitharu.kotatsu.core.ui.BaseViewModel
@ -20,6 +21,7 @@ import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.main.ui.MainActivity import org.koitharu.kotatsu.main.ui.MainActivity
import org.koitharu.kotatsu.parsers.util.move import org.koitharu.kotatsu.parsers.util.move
import org.koitharu.kotatsu.settings.nav.model.NavItemAddModel import org.koitharu.kotatsu.settings.nav.model.NavItemAddModel
import org.koitharu.kotatsu.settings.nav.model.NavItemConfigModel
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
@ -31,15 +33,18 @@ class NavConfigViewModel @Inject constructor(
private val items = MutableStateFlow(settings.mainNavItems) private val items = MutableStateFlow(settings.mainNavItems)
val content: StateFlow<List<ListModel>> = items.map { snapshot -> val content: StateFlow<List<ListModel>> = items.map { snapshot ->
if (snapshot.size < NavItem.entries.size) { buildList(snapshot.size + 1) {
snapshot + NavItemAddModel(snapshot.size < 5) snapshot.mapTo(this) {
} else { NavItemConfigModel(it, getUnavailabilityHint(it))
snapshot }
if (size < NavItem.entries.size) {
add(NavItemAddModel(size < 5))
}
} }
}.stateIn( }.stateIn(
viewModelScope + Dispatchers.Default, viewModelScope + Dispatchers.Default,
SharingStarted.WhileSubscribed(5000), SharingStarted.WhileSubscribed(5000),
emptyList() emptyList(),
) )
private var commitJob: Job? = null private var commitJob: Job? = null
@ -81,4 +86,12 @@ class NavConfigViewModel @Inject constructor(
activityRecreationHandle.recreate(MainActivity::class.java) activityRecreationHandle.recreate(MainActivity::class.java)
} }
} }
private fun getUnavailabilityHint(item: NavItem) = if (item.isAvailable(settings)) {
0
} else when (item) {
NavItem.FEED -> R.string.check_for_new_chapters_disabled
NavItem.SUGGESTIONS -> R.string.suggestions_unavailable_text
else -> 0
}
} }

@ -7,33 +7,37 @@ import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.NavItem import org.koitharu.kotatsu.core.prefs.NavItem
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.setTextAndVisible
import org.koitharu.kotatsu.databinding.ItemNavAvailableBinding import org.koitharu.kotatsu.databinding.ItemNavAvailableBinding
import org.koitharu.kotatsu.databinding.ItemNavConfigBinding import org.koitharu.kotatsu.databinding.ItemNavConfigBinding
import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.settings.nav.model.NavItemAddModel import org.koitharu.kotatsu.settings.nav.model.NavItemAddModel
import org.koitharu.kotatsu.settings.nav.model.NavItemConfigModel
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
fun navConfigAD( fun navConfigAD(
clickListener: OnListItemClickListener<NavItem>, clickListener: OnListItemClickListener<NavItem>,
) = adapterDelegateViewBinding<NavItem, ListModel, ItemNavConfigBinding>( ) = adapterDelegateViewBinding<NavItemConfigModel, ListModel, ItemNavConfigBinding>(
{ layoutInflater, parent -> ItemNavConfigBinding.inflate(layoutInflater, parent, false) }, { layoutInflater, parent -> ItemNavConfigBinding.inflate(layoutInflater, parent, false) },
) { ) {
val eventListener = object : View.OnClickListener, View.OnTouchListener { val eventListener = object : View.OnClickListener, View.OnTouchListener {
override fun onClick(v: View) = clickListener.onItemClick(item, v) override fun onClick(v: View) = clickListener.onItemClick(item.item, v)
override fun onTouch(v: View?, event: MotionEvent): Boolean = override fun onTouch(v: View?, event: MotionEvent): Boolean =
event.actionMasked == MotionEvent.ACTION_DOWN && event.actionMasked == MotionEvent.ACTION_DOWN &&
clickListener.onItemLongClick(item, itemView) clickListener.onItemLongClick(item.item, itemView)
} }
binding.imageViewRemove.setOnClickListener(eventListener) binding.imageViewRemove.setOnClickListener(eventListener)
binding.imageViewReorder.setOnTouchListener(eventListener) binding.imageViewReorder.setOnTouchListener(eventListener)
bind { bind {
with(binding.textViewTitle) { with(binding.textViewTitle) {
setText(item.title) isEnabled = item.disabledHintResId == 0
setCompoundDrawablesRelativeWithIntrinsicBounds(item.icon, 0, 0, 0) setText(item.item.title)
setCompoundDrawablesRelativeWithIntrinsicBounds(item.item.icon, 0, 0, 0)
} }
binding.textViewHint.setTextAndVisible(item.disabledHintResId)
} }
} }

@ -0,0 +1,15 @@
package org.koitharu.kotatsu.settings.nav.model
import androidx.annotation.StringRes
import org.koitharu.kotatsu.core.prefs.NavItem
import org.koitharu.kotatsu.list.ui.model.ListModel
data class NavItemConfigModel(
val item: NavItem,
@StringRes val disabledHintResId: Int,
) : ListModel {
override fun areItemsTheSame(other: ListModel): Boolean {
return other is NavItemConfigModel && other.item == item
}
}

@ -5,13 +5,18 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:windowBackground" android:background="?android:windowBackground"
android:baselineAligned="false" android:orientation="vertical"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingVertical="@dimen/margin_small" android:paddingVertical="@dimen/margin_small"
android:paddingStart="?listPreferredItemPaddingStart" android:paddingStart="?listPreferredItemPaddingStart"
android:paddingEnd="?listPreferredItemPaddingEnd"> android:paddingEnd="?listPreferredItemPaddingEnd">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView <TextView
android:id="@+id/textView_title" android:id="@+id/textView_title"
android:layout_width="0dp" android:layout_width="0dp"
@ -44,4 +49,13 @@
android:scaleType="center" android:scaleType="center"
android:src="@drawable/ic_reorder_handle" /> android:src="@drawable/ic_reorder_handle" />
</LinearLayout>
<TextView
android:id="@+id/textView_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?attr/textAppearanceBodySmall"
tools:text="@string/suggestions_unavailable_text" />
</LinearLayout> </LinearLayout>

@ -591,4 +591,6 @@
<string name="fraction_pattern" translatable="false">%1$d/%2$d</string> <string name="fraction_pattern" translatable="false">%1$d/%2$d</string>
<string name="reading_time_estimation">Show estimated reading time</string> <string name="reading_time_estimation">Show estimated reading time</string>
<string name="reading_time_estimation_summary">The time estimation value may be inaccurate</string> <string name="reading_time_estimation_summary">The time estimation value may be inaccurate</string>
<string name="suggestions_unavailable_text">Suggestions feature is disabled</string>
<string name="check_for_new_chapters_disabled">Checking for new chapters is disabled</string>
</resources> </resources>

Loading…
Cancel
Save