Filter for Local storage tab on main screen
This commit is contained in:
@@ -575,7 +575,7 @@ class AppRouter private constructor(
|
|||||||
/** Public utils **/
|
/** Public utils **/
|
||||||
|
|
||||||
fun isFilterSupported(): Boolean = when {
|
fun isFilterSupported(): Boolean = when {
|
||||||
fragment != null -> fragment.activity is FilterCoordinator.Owner
|
fragment != null -> FilterCoordinator.find(fragment) != null
|
||||||
activity != null -> activity is FilterCoordinator.Owner
|
activity != null -> activity is FilterCoordinator.Owner
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
@@ -812,6 +812,7 @@ class AppRouter private constructor(
|
|||||||
const val KEY_FILTER = "filter"
|
const val KEY_FILTER = "filter"
|
||||||
const val KEY_ID = "id"
|
const val KEY_ID = "id"
|
||||||
const val KEY_INDEX = "index"
|
const val KEY_INDEX = "index"
|
||||||
|
const val KEY_IS_BOTTOMTAB = "is_btab"
|
||||||
const val KEY_KIND = "kind"
|
const val KEY_KIND = "kind"
|
||||||
const val KEY_LIST_SECTION = "list_section"
|
const val KEY_LIST_SECTION = "list_section"
|
||||||
const val KEY_MANGA = "manga"
|
const val KEY_MANGA = "manga"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.koitharu.kotatsu.filter.ui
|
package org.koitharu.kotatsu.filter.ui
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import dagger.hilt.android.ViewModelLifecycle
|
import dagger.hilt.android.ViewModelLifecycle
|
||||||
import dagger.hilt.android.scopes.ViewModelScoped
|
import dagger.hilt.android.scopes.ViewModelScoped
|
||||||
@@ -489,9 +490,27 @@ class FilterCoordinator @Inject constructor(
|
|||||||
val filterCoordinator: FilterCoordinator
|
val filterCoordinator: FilterCoordinator
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
companion object {
|
||||||
|
|
||||||
const val TAGS_LIMIT = 12
|
private const val TAGS_LIMIT = 12
|
||||||
val MAX_YEAR = Calendar.getInstance()[Calendar.YEAR] + 1
|
private val MAX_YEAR = Calendar.getInstance()[Calendar.YEAR] + 1
|
||||||
}
|
|
||||||
|
fun find(fragment: Fragment): FilterCoordinator? {
|
||||||
|
(fragment.activity as? Owner)?.let {
|
||||||
|
return it.filterCoordinator
|
||||||
|
}
|
||||||
|
var f = fragment
|
||||||
|
while (true) {
|
||||||
|
(f as? Owner)?.let {
|
||||||
|
return it.filterCoordinator
|
||||||
|
}
|
||||||
|
f = f.parentFragment ?: break
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun require(fragment: Fragment): FilterCoordinator {
|
||||||
|
return find(fragment) ?: throw IllegalStateException("FilterCoordinator cannot be found")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class FilterSheetFragment : BaseAdaptiveSheet<SheetFilterBinding>(),
|
|||||||
binding.scrollView.scrollIndicators = 0
|
binding.scrollView.scrollIndicators = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val filter = requireFilter()
|
val filter = FilterCoordinator.require(this)
|
||||||
filter.sortOrder.observe(viewLifecycleOwner, this::onSortOrderChanged)
|
filter.sortOrder.observe(viewLifecycleOwner, this::onSortOrderChanged)
|
||||||
filter.locale.observe(viewLifecycleOwner, this::onLocaleChanged)
|
filter.locale.observe(viewLifecycleOwner, this::onLocaleChanged)
|
||||||
filter.originalLocale.observe(viewLifecycleOwner, this::onOriginalLocaleChanged)
|
filter.originalLocale.observe(viewLifecycleOwner, this::onOriginalLocaleChanged)
|
||||||
@@ -103,7 +103,7 @@ class FilterSheetFragment : BaseAdaptiveSheet<SheetFilterBinding>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemSelected(parent: AdapterView<*>, view: View?, position: Int, id: Long) {
|
override fun onItemSelected(parent: AdapterView<*>, view: View?, position: Int, id: Long) {
|
||||||
val filter = requireFilter()
|
val filter = FilterCoordinator.require(this)
|
||||||
when (parent.id) {
|
when (parent.id) {
|
||||||
R.id.spinner_order -> filter.setSortOrder(filter.sortOrder.value.availableItems[position])
|
R.id.spinner_order -> filter.setSortOrder(filter.sortOrder.value.availableItems[position])
|
||||||
R.id.spinner_locale -> filter.setLocale(filter.locale.value.availableItems[position])
|
R.id.spinner_locale -> filter.setLocale(filter.locale.value.availableItems[position])
|
||||||
@@ -118,7 +118,7 @@ class FilterSheetFragment : BaseAdaptiveSheet<SheetFilterBinding>(),
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val intValue = value.toInt()
|
val intValue = value.toInt()
|
||||||
val filter = requireFilter()
|
val filter = FilterCoordinator.require(this)
|
||||||
when (slider.id) {
|
when (slider.id) {
|
||||||
R.id.slider_year -> filter.setYear(
|
R.id.slider_year -> filter.setYear(
|
||||||
if (intValue <= slider.valueFrom.toIntUp()) {
|
if (intValue <= slider.valueFrom.toIntUp()) {
|
||||||
@@ -134,7 +134,7 @@ class FilterSheetFragment : BaseAdaptiveSheet<SheetFilterBinding>(),
|
|||||||
if (!fromUser) {
|
if (!fromUser) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val filter = requireFilter()
|
val filter = FilterCoordinator.require(this)
|
||||||
when (slider.id) {
|
when (slider.id) {
|
||||||
R.id.slider_yearsRange -> filter.setYearRange(
|
R.id.slider_yearsRange -> filter.setYearRange(
|
||||||
valueFrom = slider.values.firstOrNull()?.let {
|
valueFrom = slider.values.firstOrNull()?.let {
|
||||||
@@ -148,7 +148,7 @@ class FilterSheetFragment : BaseAdaptiveSheet<SheetFilterBinding>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onChipClick(chip: Chip, data: Any?) {
|
override fun onChipClick(chip: Chip, data: Any?) {
|
||||||
val filter = requireFilter()
|
val filter = FilterCoordinator.require(this)
|
||||||
when (data) {
|
when (data) {
|
||||||
is MangaState -> filter.toggleState(data, !chip.isChecked)
|
is MangaState -> filter.toggleState(data, !chip.isChecked)
|
||||||
is MangaTag -> if (chip.parentView?.id == R.id.chips_genresExclude) {
|
is MangaTag -> if (chip.parentView?.id == R.id.chips_genresExclude) {
|
||||||
@@ -356,6 +356,4 @@ class FilterSheetFragment : BaseAdaptiveSheet<SheetFilterBinding>(),
|
|||||||
)
|
)
|
||||||
b.sliderYearsRange.setValuesRounded(currentValueFrom, currentValueTo)
|
b.sliderYearsRange.setValuesRounded(currentValueFrom, currentValueTo)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun requireFilter() = (requireActivity() as FilterCoordinator.Owner).filterCoordinator
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class TagsCatalogSheet : BaseAdaptiveSheet<SheetTagsBinding>(),
|
|||||||
extrasProducer = {
|
extrasProducer = {
|
||||||
defaultViewModelCreationExtras.withCreationCallback<TagsCatalogViewModel.Factory> { factory ->
|
defaultViewModelCreationExtras.withCreationCallback<TagsCatalogViewModel.Factory> { factory ->
|
||||||
factory.create(
|
factory.create(
|
||||||
filter = (requireActivity() as FilterCoordinator.Owner).filterCoordinator,
|
filter = FilterCoordinator.require(this),
|
||||||
isExcludeTag = requireArguments().getBoolean(AppRouter.KEY_EXCLUDE),
|
isExcludeTag = requireArguments().getBoolean(AppRouter.KEY_EXCLUDE),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ class CoverImageView @JvmOverloads constructor(
|
|||||||
|
|
||||||
override fun onError(request: ImageRequest, result: ErrorResult) {
|
override fun onError(request: ImageRequest, result: ErrorResult) {
|
||||||
super.onError(request, result)
|
super.onError(request, result)
|
||||||
foreground = if (result.throwable.isNetworkError()) {
|
foreground = if (result.throwable.isNetworkError() && !networkState.isOnline()) {
|
||||||
ContextCompat.getDrawable(context, R.drawable.ic_offline)?.let {
|
ContextCompat.getDrawable(context, R.drawable.ic_offline)?.let {
|
||||||
LayerDrawable(arrayOf(it)).apply {
|
LayerDrawable(arrayOf(it)).apply {
|
||||||
setLayerGravity(0, Gravity.CENTER)
|
setLayerGravity(0, Gravity.CENTER)
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class PreviewFragment : BaseFragment<FragmentPreviewBinding>(), View.OnClickList
|
|||||||
|
|
||||||
override fun onChipClick(chip: Chip, data: Any?) {
|
override fun onChipClick(chip: Chip, data: Any?) {
|
||||||
val tag = data as? MangaTag ?: return
|
val tag = data as? MangaTag ?: return
|
||||||
val filter = (activity as? FilterCoordinator.Owner)?.filterCoordinator
|
val filter = FilterCoordinator.find(this)
|
||||||
if (filter == null) {
|
if (filter == null) {
|
||||||
router.openList(tag)
|
router.openList(tag)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import org.koitharu.kotatsu.core.util.ShareHelper
|
|||||||
import org.koitharu.kotatsu.core.util.ext.addMenuProvider
|
import org.koitharu.kotatsu.core.util.ext.addMenuProvider
|
||||||
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||||
import org.koitharu.kotatsu.core.util.ext.tryLaunch
|
import org.koitharu.kotatsu.core.util.ext.tryLaunch
|
||||||
import org.koitharu.kotatsu.core.util.ext.withArgs
|
|
||||||
import org.koitharu.kotatsu.databinding.FragmentListBinding
|
import org.koitharu.kotatsu.databinding.FragmentListBinding
|
||||||
import org.koitharu.kotatsu.filter.ui.FilterCoordinator
|
import org.koitharu.kotatsu.filter.ui.FilterCoordinator
|
||||||
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
import org.koitharu.kotatsu.list.ui.MangaListFragment
|
||||||
@@ -45,13 +44,14 @@ class LocalListFragment : MangaListFragment(), FilterCoordinator.Owner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
withArgs(1) {
|
super.onCreate(savedInstanceState)
|
||||||
putString(
|
val args = arguments ?: Bundle(1)
|
||||||
RemoteListFragment.ARG_SOURCE,
|
args.putString(
|
||||||
LocalMangaSource.name,
|
RemoteListFragment.ARG_SOURCE,
|
||||||
) // required by FilterCoordinator
|
LocalMangaSource.name,
|
||||||
}
|
) // required by FilterCoordinator
|
||||||
|
arguments = args
|
||||||
}
|
}
|
||||||
|
|
||||||
override val viewModel by viewModels<LocalListViewModel>()
|
override val viewModel by viewModels<LocalListViewModel>()
|
||||||
|
|||||||
@@ -6,10 +6,13 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.SharedFlow
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.model.toChipModel
|
||||||
|
import org.koitharu.kotatsu.core.nav.AppRouter
|
||||||
import org.koitharu.kotatsu.core.parser.MangaDataRepository
|
import org.koitharu.kotatsu.core.parser.MangaDataRepository
|
||||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.core.prefs.ListMode
|
import org.koitharu.kotatsu.core.prefs.ListMode
|
||||||
|
import org.koitharu.kotatsu.core.ui.widgets.ChipsView
|
||||||
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
|
||||||
import org.koitharu.kotatsu.core.util.ext.call
|
import org.koitharu.kotatsu.core.util.ext.call
|
||||||
import org.koitharu.kotatsu.core.util.ext.toFileOrNull
|
import org.koitharu.kotatsu.core.util.ext.toFileOrNull
|
||||||
@@ -17,10 +20,13 @@ import org.koitharu.kotatsu.core.util.ext.toUriOrNull
|
|||||||
import org.koitharu.kotatsu.explore.data.MangaSourcesRepository
|
import org.koitharu.kotatsu.explore.data.MangaSourcesRepository
|
||||||
import org.koitharu.kotatsu.explore.domain.ExploreRepository
|
import org.koitharu.kotatsu.explore.domain.ExploreRepository
|
||||||
import org.koitharu.kotatsu.filter.ui.FilterCoordinator
|
import org.koitharu.kotatsu.filter.ui.FilterCoordinator
|
||||||
|
import org.koitharu.kotatsu.list.domain.ListFilterOption
|
||||||
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
import org.koitharu.kotatsu.list.domain.MangaListMapper
|
||||||
|
import org.koitharu.kotatsu.list.domain.QuickFilterListener
|
||||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
import org.koitharu.kotatsu.list.ui.model.MangaListModel
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.QuickFilter
|
||||||
import org.koitharu.kotatsu.list.ui.model.TipModel
|
import org.koitharu.kotatsu.list.ui.model.TipModel
|
||||||
import org.koitharu.kotatsu.local.data.LocalStorageChanges
|
import org.koitharu.kotatsu.local.data.LocalStorageChanges
|
||||||
import org.koitharu.kotatsu.local.data.LocalStorageManager
|
import org.koitharu.kotatsu.local.data.LocalStorageManager
|
||||||
@@ -52,9 +58,10 @@ class LocalListViewModel @Inject constructor(
|
|||||||
exploreRepository = exploreRepository,
|
exploreRepository = exploreRepository,
|
||||||
sourcesRepository = sourcesRepository,
|
sourcesRepository = sourcesRepository,
|
||||||
mangaDataRepository = mangaDataRepository,
|
mangaDataRepository = mangaDataRepository,
|
||||||
), SharedPreferences.OnSharedPreferenceChangeListener {
|
), SharedPreferences.OnSharedPreferenceChangeListener, QuickFilterListener {
|
||||||
|
|
||||||
val onMangaRemoved = MutableEventFlow<Unit>()
|
val onMangaRemoved = MutableEventFlow<Unit>()
|
||||||
|
private val showInlineFilter: Boolean = savedStateHandle[AppRouter.KEY_IS_BOTTOMTAB] ?: false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
launchJob(Dispatchers.Default) {
|
launchJob(Dispatchers.Default) {
|
||||||
@@ -68,29 +75,49 @@ class LocalListViewModel @Inject constructor(
|
|||||||
|
|
||||||
override suspend fun onBuildList(list: MutableList<ListModel>) {
|
override suspend fun onBuildList(list: MutableList<ListModel>) {
|
||||||
super.onBuildList(list)
|
super.onBuildList(list)
|
||||||
if (localStorageManager.hasExternalStoragePermission(isReadOnly = true)) {
|
if (showInlineFilter) {
|
||||||
return
|
createFilterHeader(maxCount = 16)?.let {
|
||||||
}
|
list.add(0, it)
|
||||||
for (item in list) {
|
|
||||||
if (item !is MangaListModel) {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
val file = item.manga.url.toUriOrNull()?.toFileOrNull() ?: continue
|
}
|
||||||
if (localStorageManager.isOnExternalStorage(file)) {
|
if (!localStorageManager.hasExternalStoragePermission(isReadOnly = true)) {
|
||||||
val tip = TipModel(
|
for (item in list) {
|
||||||
key = "permission",
|
if (item !is MangaListModel) {
|
||||||
title = R.string.external_storage,
|
continue
|
||||||
text = R.string.missing_storage_permission,
|
}
|
||||||
icon = R.drawable.ic_storage,
|
val file = item.manga.url.toUriOrNull()?.toFileOrNull() ?: continue
|
||||||
primaryButtonText = R.string.fix,
|
if (localStorageManager.isOnExternalStorage(file)) {
|
||||||
secondaryButtonText = R.string.settings,
|
val tip = TipModel(
|
||||||
)
|
key = "permission",
|
||||||
list.add(0, tip)
|
title = R.string.external_storage,
|
||||||
return
|
text = R.string.missing_storage_permission,
|
||||||
|
icon = R.drawable.ic_storage,
|
||||||
|
primaryButtonText = R.string.fix,
|
||||||
|
secondaryButtonText = R.string.settings,
|
||||||
|
)
|
||||||
|
list.add(0, tip)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setFilterOption(option: ListFilterOption, isApplied: Boolean) {
|
||||||
|
if (option is ListFilterOption.Tag) {
|
||||||
|
filterCoordinator.toggleTag(option.tag, isApplied)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toggleFilterOption(option: ListFilterOption) {
|
||||||
|
if (option is ListFilterOption.Tag) {
|
||||||
|
val tag = option.tag
|
||||||
|
val isSelected = tag in filterCoordinator.snapshot().listFilter.tags
|
||||||
|
filterCoordinator.toggleTag(option.tag, !isSelected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clearFilter() = filterCoordinator.reset()
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
settings.unsubscribe(this)
|
settings.unsubscribe(this)
|
||||||
super.onCleared()
|
super.onCleared()
|
||||||
@@ -125,4 +152,26 @@ class LocalListViewModel @Inject constructor(
|
|||||||
actionStringRes = R.string._import,
|
actionStringRes = R.string._import,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun createFilterHeader(maxCount: Int): QuickFilter? {
|
||||||
|
val appliedTags = filterCoordinator.snapshot().listFilter.tags
|
||||||
|
val availableTags = repository.getFilterOptions().availableTags
|
||||||
|
if (appliedTags.isEmpty() && availableTags.size < 3) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val result = ArrayList<ChipsView.ChipModel>(minOf(availableTags.size, maxCount))
|
||||||
|
appliedTags.mapTo(result) { tag ->
|
||||||
|
ListFilterOption.Tag(tag).toChipModel(isChecked = true)
|
||||||
|
}
|
||||||
|
for (tag in availableTags) {
|
||||||
|
if (result.size >= maxCount) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (tag in appliedTags) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result.add(ListFilterOption.Tag(tag).toChipModel(isChecked = false))
|
||||||
|
}
|
||||||
|
return QuickFilter(result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,12 @@ import kotlinx.coroutines.flow.map
|
|||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.bookmarks.ui.AllBookmarksFragment
|
import org.koitharu.kotatsu.bookmarks.ui.AllBookmarksFragment
|
||||||
|
import org.koitharu.kotatsu.core.nav.AppRouter
|
||||||
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.util.RecyclerViewOwner
|
import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner
|
||||||
import org.koitharu.kotatsu.core.ui.widgets.SlidingBottomNavigationView
|
import org.koitharu.kotatsu.core.ui.widgets.SlidingBottomNavigationView
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.buildBundle
|
||||||
import org.koitharu.kotatsu.core.util.ext.setContentDescriptionAndTooltip
|
import org.koitharu.kotatsu.core.util.ext.setContentDescriptionAndTooltip
|
||||||
import org.koitharu.kotatsu.core.util.ext.smoothScrollToTop
|
import org.koitharu.kotatsu.core.util.ext.smoothScrollToTop
|
||||||
import org.koitharu.kotatsu.databinding.NavigationRailFabBinding
|
import org.koitharu.kotatsu.databinding.NavigationRailFabBinding
|
||||||
@@ -211,10 +213,13 @@ class MainNavigationDelegate(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val fragment = instantiateFragment(fragmentClass)
|
val fragment = instantiateFragment(fragmentClass)
|
||||||
|
val args = buildBundle(1) {
|
||||||
|
putBoolean(AppRouter.KEY_IS_BOTTOMTAB, true)
|
||||||
|
}
|
||||||
fragment.enterTransition = MaterialFadeThrough()
|
fragment.enterTransition = MaterialFadeThrough()
|
||||||
fragmentManager.beginTransaction()
|
fragmentManager.beginTransaction()
|
||||||
.setReorderingAllowed(true)
|
.setReorderingAllowed(true)
|
||||||
.replace(R.id.container, fragmentClass, null, TAG_PRIMARY)
|
.replace(R.id.container, fragmentClass, args, TAG_PRIMARY)
|
||||||
.runOnCommit { onFragmentChanged(fragment, fromUser = true) }
|
.runOnCommit { onFragmentChanged(fragment, fromUser = true) }
|
||||||
.commit()
|
.commit()
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ open class RemoteListViewModel @Inject constructor(
|
|||||||
val isRandomLoading = MutableStateFlow(false)
|
val isRandomLoading = MutableStateFlow(false)
|
||||||
val onOpenManga = MutableEventFlow<Manga>()
|
val onOpenManga = MutableEventFlow<Manga>()
|
||||||
|
|
||||||
private val repository = mangaRepositoryFactory.create(source)
|
protected val repository = mangaRepositoryFactory.create(source)
|
||||||
private val mangaList = MutableStateFlow<List<Manga>?>(null)
|
private val mangaList = MutableStateFlow<List<Manga>?>(null)
|
||||||
private val hasNextPage = MutableStateFlow(false)
|
private val hasNextPage = MutableStateFlow(false)
|
||||||
private val listError = MutableStateFlow<Throwable?>(null)
|
private val listError = MutableStateFlow<Throwable?>(null)
|
||||||
|
|||||||
Reference in New Issue
Block a user