Move app state banner to the very top (#8706)
This moves the banners to the root composable and so eliminates the need to track the app states in every screen.
This commit is contained in:
parent
a61e2799db
commit
d97eab0328
@ -182,6 +182,7 @@ dependencies {
|
||||
implementation(compose.accompanist.flowlayout)
|
||||
implementation(compose.accompanist.permissions)
|
||||
implementation(compose.accompanist.themeadapter)
|
||||
implementation(compose.accompanist.systemuicontroller)
|
||||
|
||||
implementation(androidx.paging.runtime)
|
||||
implementation(androidx.paging.compose)
|
||||
|
@ -63,9 +63,6 @@ fun AppBar(
|
||||
actionModeCounter: Int = 0,
|
||||
onCancelActionMode: () -> Unit = {},
|
||||
actionModeActions: @Composable RowScope.() -> Unit = {},
|
||||
// Banners
|
||||
downloadedOnlyMode: Boolean = false,
|
||||
incognitoMode: Boolean = false,
|
||||
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null,
|
||||
) {
|
||||
@ -93,8 +90,6 @@ fun AppBar(
|
||||
},
|
||||
isActionMode = isActionMode,
|
||||
onCancelActionMode = onCancelActionMode,
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
incognitoMode = incognitoMode,
|
||||
scrollBehavior = scrollBehavior,
|
||||
)
|
||||
}
|
||||
@ -112,9 +107,6 @@ fun AppBar(
|
||||
// Action mode
|
||||
isActionMode: Boolean = false,
|
||||
onCancelActionMode: () -> Unit = {},
|
||||
// Banners
|
||||
downloadedOnlyMode: Boolean = false,
|
||||
incognitoMode: Boolean = false,
|
||||
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null,
|
||||
) {
|
||||
@ -150,8 +142,6 @@ fun AppBar(
|
||||
),
|
||||
scrollBehavior = scrollBehavior,
|
||||
)
|
||||
|
||||
AppStateBanners(downloadedOnlyMode, incognitoMode)
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,8 +226,6 @@ fun SearchToolbar(
|
||||
onSearch: (String) -> Unit = {},
|
||||
onClickCloseSearch: () -> Unit = { onChangeSearchQuery(null) },
|
||||
actions: @Composable RowScope.() -> Unit = {},
|
||||
incognitoMode: Boolean = false,
|
||||
downloadedOnlyMode: Boolean = false,
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null,
|
||||
visualTransformation: VisualTransformation = VisualTransformation.None,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
@ -326,8 +314,6 @@ fun SearchToolbar(
|
||||
key("actions") { actions() }
|
||||
},
|
||||
isActionMode = false,
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
incognitoMode = incognitoMode,
|
||||
scrollBehavior = scrollBehavior,
|
||||
)
|
||||
LaunchedEffect(searchClickCount) {
|
||||
|
@ -3,8 +3,13 @@ package eu.kanade.presentation.components
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.systemBars
|
||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@ -37,24 +42,34 @@ fun AppStateBanners(
|
||||
incognitoMode: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val insets = WindowInsets.systemBars.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)
|
||||
Column(modifier = modifier) {
|
||||
if (downloadedOnlyMode) {
|
||||
DownloadedOnlyModeBanner()
|
||||
DownloadedOnlyModeBanner(
|
||||
modifier = Modifier.windowInsetsPadding(insets),
|
||||
)
|
||||
}
|
||||
if (incognitoMode) {
|
||||
IncognitoModeBanner()
|
||||
IncognitoModeBanner(
|
||||
modifier = if (!downloadedOnlyMode) {
|
||||
Modifier.windowInsetsPadding(insets)
|
||||
} else {
|
||||
Modifier
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DownloadedOnlyModeBanner() {
|
||||
private fun DownloadedOnlyModeBanner(modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
text = stringResource(R.string.label_downloaded_only),
|
||||
modifier = Modifier
|
||||
.background(color = MaterialTheme.colorScheme.tertiary)
|
||||
.fillMaxWidth()
|
||||
.padding(4.dp),
|
||||
.padding(4.dp)
|
||||
.then(modifier),
|
||||
color = MaterialTheme.colorScheme.onTertiary,
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
@ -62,13 +77,14 @@ private fun DownloadedOnlyModeBanner() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun IncognitoModeBanner() {
|
||||
private fun IncognitoModeBanner(modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
text = stringResource(R.string.pref_incognito_mode),
|
||||
modifier = Modifier
|
||||
.background(color = MaterialTheme.colorScheme.primary)
|
||||
.fillMaxWidth()
|
||||
.padding(4.dp),
|
||||
.padding(4.dp)
|
||||
.then(modifier),
|
||||
color = MaterialTheme.colorScheme.onPrimary,
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
|
@ -29,8 +29,6 @@ fun TabbedScreen(
|
||||
startIndex: Int? = null,
|
||||
searchQuery: String? = null,
|
||||
onChangeSearchQuery: (String?) -> Unit = {},
|
||||
incognitoMode: Boolean,
|
||||
downloadedOnlyMode: Boolean,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val state = rememberPagerState()
|
||||
@ -78,8 +76,6 @@ fun TabbedScreen(
|
||||
}
|
||||
}
|
||||
|
||||
AppStateBanners(downloadedOnlyMode, incognitoMode)
|
||||
|
||||
HorizontalPager(
|
||||
count = tabs.size,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
|
@ -26,8 +26,6 @@ import java.util.Date
|
||||
fun HistoryScreen(
|
||||
state: HistoryState,
|
||||
snackbarHostState: SnackbarHostState,
|
||||
incognitoMode: Boolean,
|
||||
downloadedOnlyMode: Boolean,
|
||||
onSearchQueryChange: (String?) -> Unit,
|
||||
onClickCover: (mangaId: Long) -> Unit,
|
||||
onClickResume: (mangaId: Long, chapterId: Long) -> Unit,
|
||||
@ -47,8 +45,6 @@ fun HistoryScreen(
|
||||
)
|
||||
}
|
||||
},
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
incognitoMode = incognitoMode,
|
||||
scrollBehavior = scrollBehavior,
|
||||
)
|
||||
},
|
||||
|
@ -45,8 +45,6 @@ fun LibraryContent(
|
||||
getDisplayModeForPage: @Composable (Int) -> LibraryDisplayMode,
|
||||
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
|
||||
getLibraryForPage: (Int) -> List<LibraryItem>,
|
||||
isDownloadOnly: Boolean,
|
||||
isIncognitoMode: Boolean,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(
|
||||
@ -65,8 +63,6 @@ fun LibraryContent(
|
||||
LibraryTabs(
|
||||
categories = categories,
|
||||
currentPageIndex = pagerState.currentPage,
|
||||
isDownloadOnly = isDownloadOnly,
|
||||
isIncognitoMode = isIncognitoMode,
|
||||
getNumberOfMangaForCategory = getNumberOfMangaForCategory,
|
||||
) { scope.launch { pagerState.animateScrollToPage(it) } }
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.domain.category.model.Category
|
||||
import eu.kanade.presentation.category.visualName
|
||||
import eu.kanade.presentation.components.AppStateBanners
|
||||
import eu.kanade.presentation.components.Divider
|
||||
import eu.kanade.presentation.components.TabIndicator
|
||||
import eu.kanade.presentation.components.TabText
|
||||
@ -17,8 +16,6 @@ import eu.kanade.presentation.components.TabText
|
||||
fun LibraryTabs(
|
||||
categories: List<Category>,
|
||||
currentPageIndex: Int,
|
||||
isDownloadOnly: Boolean,
|
||||
isIncognitoMode: Boolean,
|
||||
getNumberOfMangaForCategory: (Category) -> Int?,
|
||||
onTabItemClick: (Int) -> Unit,
|
||||
) {
|
||||
@ -47,7 +44,5 @@ fun LibraryTabs(
|
||||
}
|
||||
|
||||
Divider()
|
||||
|
||||
AppStateBanners(isDownloadOnly, isIncognitoMode)
|
||||
}
|
||||
}
|
||||
|
@ -32,8 +32,6 @@ fun LibraryToolbar(
|
||||
hasActiveFilters: Boolean,
|
||||
selectedCount: Int,
|
||||
title: LibraryToolbarTitle,
|
||||
incognitoMode: Boolean,
|
||||
downloadedOnlyMode: Boolean,
|
||||
onClickUnselectAll: () -> Unit,
|
||||
onClickSelectAll: () -> Unit,
|
||||
onClickInvertSelection: () -> Unit,
|
||||
@ -46,8 +44,6 @@ fun LibraryToolbar(
|
||||
) = when {
|
||||
selectedCount > 0 -> LibrarySelectionToolbar(
|
||||
selectedCount = selectedCount,
|
||||
incognitoMode = incognitoMode,
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
onClickUnselectAll = onClickUnselectAll,
|
||||
onClickSelectAll = onClickSelectAll,
|
||||
onClickInvertSelection = onClickInvertSelection,
|
||||
@ -55,8 +51,6 @@ fun LibraryToolbar(
|
||||
else -> LibraryRegularToolbar(
|
||||
title = title,
|
||||
hasFilters = hasActiveFilters,
|
||||
incognitoMode = incognitoMode,
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
searchQuery = searchQuery,
|
||||
onSearchQueryChange = onSearchQueryChange,
|
||||
onClickFilter = onClickFilter,
|
||||
@ -70,8 +64,6 @@ fun LibraryToolbar(
|
||||
fun LibraryRegularToolbar(
|
||||
title: LibraryToolbarTitle,
|
||||
hasFilters: Boolean,
|
||||
incognitoMode: Boolean,
|
||||
downloadedOnlyMode: Boolean,
|
||||
searchQuery: String?,
|
||||
onSearchQueryChange: (String?) -> Unit,
|
||||
onClickFilter: () -> Unit,
|
||||
@ -123,8 +115,6 @@ fun LibraryRegularToolbar(
|
||||
)
|
||||
}
|
||||
},
|
||||
incognitoMode = incognitoMode,
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
scrollBehavior = scrollBehavior,
|
||||
)
|
||||
}
|
||||
@ -132,8 +122,6 @@ fun LibraryRegularToolbar(
|
||||
@Composable
|
||||
fun LibrarySelectionToolbar(
|
||||
selectedCount: Int,
|
||||
incognitoMode: Boolean,
|
||||
downloadedOnlyMode: Boolean,
|
||||
onClickUnselectAll: () -> Unit,
|
||||
onClickSelectAll: () -> Unit,
|
||||
onClickInvertSelection: () -> Unit,
|
||||
@ -150,8 +138,6 @@ fun LibrarySelectionToolbar(
|
||||
},
|
||||
isActionMode = true,
|
||||
onCancelActionMode = onClickUnselectAll,
|
||||
incognitoMode = incognitoMode,
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -238,8 +238,6 @@ private fun MangaScreenSmallImpl(
|
||||
titleAlphaProvider = { animatedTitleAlpha },
|
||||
backgroundAlphaProvider = { animatedBgAlpha },
|
||||
hasFilters = state.manga.chaptersFiltered(),
|
||||
incognitoMode = state.isIncognitoMode,
|
||||
downloadedOnlyMode = state.isDownloadedOnlyMode,
|
||||
onBackClicked = internalOnBackPressed,
|
||||
onClickFilter = onFilterClicked,
|
||||
onClickShare = onShareClicked,
|
||||
@ -450,8 +448,6 @@ fun MangaScreenLargeImpl(
|
||||
titleAlphaProvider = { if (chapters.fastAny { it.selected }) 1f else 0f },
|
||||
backgroundAlphaProvider = { 1f },
|
||||
hasFilters = state.manga.chaptersFiltered(),
|
||||
incognitoMode = state.isIncognitoMode,
|
||||
downloadedOnlyMode = state.isDownloadedOnlyMode,
|
||||
onBackClicked = internalOnBackPressed,
|
||||
onClickFilter = onFilterButtonClicked,
|
||||
onClickShare = onShareClicked,
|
||||
|
@ -26,7 +26,6 @@ import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.presentation.components.AppStateBanners
|
||||
import eu.kanade.presentation.components.DownloadDropdownMenu
|
||||
import eu.kanade.presentation.components.OverflowMenu
|
||||
import eu.kanade.presentation.manga.DownloadAction
|
||||
@ -40,8 +39,6 @@ fun MangaToolbar(
|
||||
titleAlphaProvider: () -> Float,
|
||||
backgroundAlphaProvider: () -> Float = titleAlphaProvider,
|
||||
hasFilters: Boolean,
|
||||
incognitoMode: Boolean,
|
||||
downloadedOnlyMode: Boolean,
|
||||
onBackClicked: () -> Unit,
|
||||
onClickFilter: () -> Unit,
|
||||
onClickShare: (() -> Unit)?,
|
||||
@ -151,7 +148,5 @@ fun MangaToolbar(
|
||||
.copy(alpha = if (isActionMode) 1f else backgroundAlphaProvider()),
|
||||
),
|
||||
)
|
||||
|
||||
AppStateBanners(downloadedOnlyMode, incognitoMode)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,13 @@
|
||||
package eu.kanade.presentation.more
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.systemBars
|
||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.CloudOff
|
||||
import androidx.compose.material.icons.outlined.GetApp
|
||||
@ -18,8 +24,8 @@ import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import eu.kanade.presentation.components.AppStateBanners
|
||||
import eu.kanade.presentation.components.Divider
|
||||
import eu.kanade.presentation.components.Scaffold
|
||||
import eu.kanade.presentation.components.ScrollbarLazyColumn
|
||||
import eu.kanade.presentation.components.WarningBanner
|
||||
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
|
||||
@ -45,11 +51,14 @@ fun MoreScreen(
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
|
||||
ScrollbarLazyColumn(
|
||||
modifier = Modifier.systemBarsPadding(),
|
||||
Scaffold(
|
||||
topBar = {
|
||||
Column(
|
||||
modifier = Modifier.windowInsetsPadding(
|
||||
WindowInsets.systemBars.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal),
|
||||
),
|
||||
) {
|
||||
if (isFDroid) {
|
||||
item {
|
||||
WarningBanner(
|
||||
textRes = R.string.fdroid_warning,
|
||||
modifier = Modifier.clickable {
|
||||
@ -58,18 +67,14 @@ fun MoreScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
) { contentPadding ->
|
||||
ScrollbarLazyColumn(
|
||||
modifier = Modifier.padding(contentPadding),
|
||||
) {
|
||||
item {
|
||||
LogoHeader()
|
||||
}
|
||||
|
||||
item {
|
||||
AppStateBanners(
|
||||
downloadedOnlyMode = downloadedOnly,
|
||||
incognitoMode = incognitoMode,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
SwitchPreferenceWidget(
|
||||
title = stringResource(R.string.label_downloaded_only),
|
||||
@ -166,4 +171,5 @@ fun MoreScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,8 +43,6 @@ import kotlin.time.Duration.Companion.seconds
|
||||
fun UpdateScreen(
|
||||
state: UpdatesState,
|
||||
snackbarHostState: SnackbarHostState,
|
||||
incognitoMode: Boolean,
|
||||
downloadedOnlyMode: Boolean,
|
||||
lastUpdated: Long,
|
||||
relativeTime: Int,
|
||||
onClickCover: (UpdatesItem) -> Unit,
|
||||
@ -65,8 +63,6 @@ fun UpdateScreen(
|
||||
Scaffold(
|
||||
topBar = { scrollBehavior ->
|
||||
UpdatesAppBar(
|
||||
incognitoMode = incognitoMode,
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
onUpdateLibrary = { onUpdateLibrary() },
|
||||
actionModeCounter = state.selected.size,
|
||||
onSelectAll = { onSelectAll(true) },
|
||||
@ -136,8 +132,6 @@ fun UpdateScreen(
|
||||
@Composable
|
||||
private fun UpdatesAppBar(
|
||||
modifier: Modifier = Modifier,
|
||||
incognitoMode: Boolean,
|
||||
downloadedOnlyMode: Boolean,
|
||||
onUpdateLibrary: () -> Unit,
|
||||
// For action mode
|
||||
actionModeCounter: Int,
|
||||
@ -173,8 +167,6 @@ private fun UpdatesAppBar(
|
||||
)
|
||||
}
|
||||
},
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
incognitoMode = incognitoMode,
|
||||
scrollBehavior = scrollBehavior,
|
||||
)
|
||||
}
|
||||
|
@ -9,13 +9,9 @@ import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.navigator.tab.LocalTabNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||
import eu.kanade.core.prefs.asState
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.presentation.components.TabbedScreen
|
||||
import eu.kanade.presentation.util.Tab
|
||||
import eu.kanade.tachiyomi.R
|
||||
@ -25,8 +21,6 @@ import eu.kanade.tachiyomi.ui.browse.migration.sources.migrateSourceTab
|
||||
import eu.kanade.tachiyomi.ui.browse.source.sourcesTab
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
data class BrowseTab(
|
||||
private val toExtensions: Boolean = false,
|
||||
@ -47,7 +41,6 @@ data class BrowseTab(
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val context = LocalContext.current
|
||||
val screenModel = rememberScreenModel { BrowseScreenModel() }
|
||||
|
||||
// Hoisted for extensions tab's search bar
|
||||
val extensionsScreenModel = rememberScreenModel { ExtensionsScreenModel() }
|
||||
@ -63,8 +56,6 @@ data class BrowseTab(
|
||||
startIndex = 1.takeIf { toExtensions },
|
||||
searchQuery = extensionsQuery,
|
||||
onChangeSearchQuery = extensionsScreenModel::search,
|
||||
incognitoMode = screenModel.isIncognitoMode,
|
||||
downloadedOnlyMode = screenModel.isDownloadOnly,
|
||||
)
|
||||
|
||||
// For local source
|
||||
@ -75,10 +66,3 @@ data class BrowseTab(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class BrowseScreenModel(
|
||||
preferences: BasePreferences = Injekt.get(),
|
||||
) : ScreenModel {
|
||||
val isDownloadOnly: Boolean by preferences.downloadedOnly().asState(coroutineScope)
|
||||
val isIncognitoMode: Boolean by preferences.incognitoMode().asState(coroutineScope)
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ import eu.kanade.domain.source.interactor.GetRemoteManga
|
||||
import eu.kanade.presentation.browse.BrowseSourceContent
|
||||
import eu.kanade.presentation.browse.components.BrowseSourceToolbar
|
||||
import eu.kanade.presentation.browse.components.RemoveMangaDialog
|
||||
import eu.kanade.presentation.components.AppStateBanners
|
||||
import eu.kanade.presentation.components.ChangeCategoryDialog
|
||||
import eu.kanade.presentation.components.Divider
|
||||
import eu.kanade.presentation.components.DuplicateMangaDialog
|
||||
@ -167,8 +166,6 @@ data class BrowseSourceScreen(
|
||||
}
|
||||
|
||||
Divider()
|
||||
|
||||
AppStateBanners(screenModel.isDownloadOnly, screenModel.isIncognitoMode)
|
||||
}
|
||||
},
|
||||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
||||
|
@ -17,7 +17,6 @@ import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.core.prefs.CheckboxState
|
||||
import eu.kanade.core.prefs.asState
|
||||
import eu.kanade.core.prefs.mapAsCheckboxState
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.category.interactor.GetCategories
|
||||
import eu.kanade.domain.category.interactor.SetMangaCategories
|
||||
import eu.kanade.domain.category.model.Category
|
||||
@ -82,7 +81,6 @@ class BrowseSourceScreenModel(
|
||||
private val sourceId: Long,
|
||||
searchQuery: String?,
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
preferences: BasePreferences = Injekt.get(),
|
||||
sourcePreferences: SourcePreferences = Injekt.get(),
|
||||
private val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||
private val coverCache: CoverCache = Injekt.get(),
|
||||
@ -103,9 +101,6 @@ class BrowseSourceScreenModel(
|
||||
|
||||
var displayMode by sourcePreferences.sourceDisplayMode().asState(coroutineScope)
|
||||
|
||||
val isDownloadOnly: Boolean by preferences.downloadedOnly().asState(coroutineScope)
|
||||
val isIncognitoMode: Boolean by preferences.incognitoMode().asState(coroutineScope)
|
||||
|
||||
val source = sourceManager.get(sourceId) as CatalogueSource
|
||||
|
||||
/**
|
||||
|
@ -1,12 +1,9 @@
|
||||
package eu.kanade.tachiyomi.ui.history
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.getValue
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import eu.kanade.core.prefs.asState
|
||||
import eu.kanade.core.util.insertSeparators
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.chapter.model.Chapter
|
||||
import eu.kanade.domain.history.interactor.GetHistory
|
||||
import eu.kanade.domain.history.interactor.GetNextChapters
|
||||
@ -37,15 +34,11 @@ class HistoryScreenModel(
|
||||
private val getHistory: GetHistory = Injekt.get(),
|
||||
private val getNextChapters: GetNextChapters = Injekt.get(),
|
||||
private val removeHistory: RemoveHistory = Injekt.get(),
|
||||
preferences: BasePreferences = Injekt.get(),
|
||||
) : StateScreenModel<HistoryState>(HistoryState()) {
|
||||
|
||||
private val _events: Channel<Event> = Channel(Channel.UNLIMITED)
|
||||
val events: Flow<Event> = _events.receiveAsFlow()
|
||||
|
||||
val isDownloadOnly: Boolean by preferences.downloadedOnly().asState(coroutineScope)
|
||||
val isIncognitoMode: Boolean by preferences.incognitoMode().asState(coroutineScope)
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
state.map { it.searchQuery }
|
||||
|
@ -62,8 +62,6 @@ object HistoryTab : Tab {
|
||||
HistoryScreen(
|
||||
state = state,
|
||||
snackbarHostState = snackbarHostState,
|
||||
incognitoMode = screenModel.isIncognitoMode,
|
||||
downloadedOnlyMode = screenModel.isDownloadOnly,
|
||||
onSearchQueryChange = screenModel::updateSearchQuery,
|
||||
onClickCover = { navigator.push(MangaScreen(it)) },
|
||||
onClickResume = screenModel::getNextChapterForManga,
|
||||
|
@ -89,9 +89,6 @@ class LibraryScreenModel(
|
||||
|
||||
var activeCategoryIndex: Int by libraryPreferences.lastUsedCategory().asState(coroutineScope)
|
||||
|
||||
val isDownloadOnly: Boolean by preferences.downloadedOnly().asState(coroutineScope)
|
||||
val isIncognitoMode: Boolean by preferences.incognitoMode().asState(coroutineScope)
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
combine(
|
||||
|
@ -112,8 +112,6 @@ object LibraryTab : Tab {
|
||||
hasActiveFilters = state.hasActiveFilters,
|
||||
selectedCount = state.selection.size,
|
||||
title = title,
|
||||
incognitoMode = !tabVisible && screenModel.isIncognitoMode,
|
||||
downloadedOnlyMode = !tabVisible && screenModel.isDownloadOnly,
|
||||
onClickUnselectAll = screenModel::clearSelection,
|
||||
onClickSelectAll = { screenModel.selectAll(screenModel.activeCategoryIndex) },
|
||||
onClickInvertSelection = { screenModel.invertSelection(screenModel.activeCategoryIndex) },
|
||||
@ -197,10 +195,7 @@ object LibraryTab : Tab {
|
||||
getNumberOfMangaForCategory = { state.getMangaCountForCategory(it) },
|
||||
getDisplayModeForPage = { state.categories[it].display },
|
||||
getColumnsForOrientation = { screenModel.getColumnsPreferenceForCurrentOrientation(it) },
|
||||
getLibraryForPage = { state.getLibraryItemsByPage(it) },
|
||||
isDownloadOnly = screenModel.isDownloadOnly,
|
||||
isIncognitoMode = screenModel.isIncognitoMode,
|
||||
)
|
||||
) { state.getLibraryItemsByPage(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,12 @@ import android.view.View
|
||||
import android.view.Window
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
import androidx.compose.foundation.layout.statusBars
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
@ -20,6 +26,7 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.core.animation.doOnEnd
|
||||
@ -36,12 +43,14 @@ import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.navigator.NavigatorDisposeBehavior
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
import cafe.adriel.voyager.transitions.ScreenTransition
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.category.model.Category
|
||||
import eu.kanade.domain.library.service.LibraryPreferences
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.domain.ui.UiPreferences
|
||||
import eu.kanade.presentation.components.AppStateBanners
|
||||
import eu.kanade.presentation.util.Transition
|
||||
import eu.kanade.presentation.util.collectAsState
|
||||
import eu.kanade.tachiyomi.BuildConfig
|
||||
@ -142,6 +151,23 @@ class MainActivity : BaseActivity() {
|
||||
.launchIn(lifecycleScope)
|
||||
|
||||
setComposeContent {
|
||||
val incognito by preferences.incognitoMode().collectAsState()
|
||||
val download by preferences.downloadedOnly().collectAsState()
|
||||
Column {
|
||||
AppStateBanners(
|
||||
downloadedOnlyMode = download,
|
||||
incognitoMode = incognito,
|
||||
)
|
||||
val systemUiController = rememberSystemUiController()
|
||||
val active = incognito || download
|
||||
val useDarkIcons = if (isSystemInDarkTheme()) active else !active
|
||||
LaunchedEffect(systemUiController, useDarkIcons) {
|
||||
systemUiController.setStatusBarColor(
|
||||
color = androidx.compose.ui.graphics.Color.Transparent,
|
||||
darkIcons = useDarkIcons,
|
||||
)
|
||||
}
|
||||
|
||||
Navigator(
|
||||
screen = HomeScreen,
|
||||
disposeBehavior = NavigatorDisposeBehavior(disposeNestedNavigators = false, disposeSteps = true),
|
||||
@ -162,8 +188,16 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
// Consume insets already used by app state banners
|
||||
val boxModifier = if (incognito || download) {
|
||||
Modifier.consumeWindowInsets(WindowInsets.statusBars)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
Box(modifier = boxModifier) {
|
||||
// Shows current screen
|
||||
ScreenTransition(navigator = navigator, transition = { Transition.OneWayFade })
|
||||
}
|
||||
|
||||
// Pop source-related screens when incognito mode is turned off
|
||||
LaunchedEffect(Unit) {
|
||||
@ -184,6 +218,7 @@ class MainActivity : BaseActivity() {
|
||||
|
||||
CheckForUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
var showChangelog by remember { mutableStateOf(didMigration && !BuildConfig.DEBUG) }
|
||||
if (showChangelog) {
|
||||
|
@ -10,7 +10,6 @@ import eu.kanade.core.prefs.CheckboxState
|
||||
import eu.kanade.core.prefs.mapAsCheckboxState
|
||||
import eu.kanade.core.util.addOrRemove
|
||||
import eu.kanade.data.chapter.NoChaptersException
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.category.interactor.GetCategories
|
||||
import eu.kanade.domain.category.interactor.SetMangaCategories
|
||||
import eu.kanade.domain.category.model.Category
|
||||
@ -53,7 +52,6 @@ import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
||||
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import eu.kanade.tachiyomi.util.preference.asHotFlow
|
||||
import eu.kanade.tachiyomi.util.removeCovers
|
||||
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
@ -64,7 +62,6 @@ import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.isActive
|
||||
@ -81,7 +78,6 @@ class MangaInfoScreenModel(
|
||||
val context: Context,
|
||||
val mangaId: Long,
|
||||
private val isFromSource: Boolean,
|
||||
basePreferences: BasePreferences = Injekt.get(),
|
||||
private val downloadPreferences: DownloadPreferences = Injekt.get(),
|
||||
private val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||
private val uiPreferences: UiPreferences = Injekt.get(),
|
||||
@ -130,17 +126,6 @@ class MangaInfoScreenModel(
|
||||
mutableState.update { if (it is MangaScreenState.Success) func(it) else it }
|
||||
}
|
||||
|
||||
private var incognitoMode = false
|
||||
set(value) {
|
||||
updateSuccessState { it.copy(isIncognitoMode = value) }
|
||||
field = value
|
||||
}
|
||||
private var downloadedOnlyMode = false
|
||||
set(value) {
|
||||
updateSuccessState { it.copy(isDownloadedOnlyMode = value) }
|
||||
field = value
|
||||
}
|
||||
|
||||
init {
|
||||
val toChapterItemsParams: List<Chapter>.(manga: Manga) -> List<ChapterItem> = { manga ->
|
||||
toChapterItems(
|
||||
@ -189,8 +174,6 @@ class MangaInfoScreenModel(
|
||||
isFromSource = isFromSource,
|
||||
chapters = chapters,
|
||||
isRefreshingData = needRefreshInfo || needRefreshChapter,
|
||||
isIncognitoMode = incognitoMode,
|
||||
isDownloadedOnlyMode = downloadedOnlyMode,
|
||||
dialog = null,
|
||||
)
|
||||
}
|
||||
@ -210,14 +193,6 @@ class MangaInfoScreenModel(
|
||||
// Initial loading finished
|
||||
updateSuccessState { it.copy(isRefreshingData = false) }
|
||||
}
|
||||
|
||||
basePreferences.incognitoMode()
|
||||
.asHotFlow { incognitoMode = it }
|
||||
.launchIn(coroutineScope)
|
||||
|
||||
basePreferences.downloadedOnly()
|
||||
.asHotFlow { downloadedOnlyMode = it }
|
||||
.launchIn(coroutineScope)
|
||||
}
|
||||
|
||||
fun fetchAllFromSource(manualFetch: Boolean = true) {
|
||||
@ -1037,8 +1012,6 @@ sealed class MangaScreenState {
|
||||
val chapters: List<ChapterItem>,
|
||||
val trackItems: List<TrackItem> = emptyList(),
|
||||
val isRefreshingData: Boolean = false,
|
||||
val isIncognitoMode: Boolean = false,
|
||||
val isDownloadedOnlyMode: Boolean = false,
|
||||
val dialog: MangaInfoScreenModel.Dialog? = null,
|
||||
) : MangaScreenState() {
|
||||
|
||||
|
@ -11,7 +11,6 @@ import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import eu.kanade.core.prefs.asState
|
||||
import eu.kanade.core.util.addOrRemove
|
||||
import eu.kanade.core.util.insertSeparators
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.chapter.interactor.GetChapter
|
||||
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
||||
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
||||
@ -62,16 +61,12 @@ class UpdatesScreenModel(
|
||||
private val getChapter: GetChapter = Injekt.get(),
|
||||
private val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||
val snackbarHostState: SnackbarHostState = SnackbarHostState(),
|
||||
basePreferences: BasePreferences = Injekt.get(),
|
||||
uiPreferences: UiPreferences = Injekt.get(),
|
||||
) : StateScreenModel<UpdatesState>(UpdatesState()) {
|
||||
|
||||
private val _events: Channel<Event> = Channel(Int.MAX_VALUE)
|
||||
val events: Flow<Event> = _events.receiveAsFlow()
|
||||
|
||||
val isDownloadOnly: Boolean by basePreferences.downloadedOnly().asState(coroutineScope)
|
||||
val isIncognitoMode: Boolean by basePreferences.incognitoMode().asState(coroutineScope)
|
||||
|
||||
val lastUpdated by libraryPreferences.libraryUpdateLastTimestamp().asState(coroutineScope)
|
||||
|
||||
val relativeTime: Int by uiPreferences.relativeTime().asState(coroutineScope)
|
||||
|
@ -56,8 +56,6 @@ object UpdatesTab : Tab {
|
||||
UpdateScreen(
|
||||
state = state,
|
||||
snackbarHostState = screenModel.snackbarHostState,
|
||||
incognitoMode = screenModel.isIncognitoMode,
|
||||
downloadedOnlyMode = screenModel.isDownloadOnly,
|
||||
lastUpdated = screenModel.lastUpdated,
|
||||
relativeTime = screenModel.relativeTime,
|
||||
onClickCover = { item -> navigator.push(MangaScreen(item.update.mangaId)) },
|
||||
|
@ -24,3 +24,4 @@ accompanist-webview = { module = "com.google.accompanist:accompanist-webview", v
|
||||
accompanist-flowlayout = { module = "com.google.accompanist:accompanist-flowlayout", version.ref = "accompanist" }
|
||||
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" }
|
||||
accompanist-themeadapter = { module = "com.google.accompanist:accompanist-themeadapter-material3", version.ref = "accompanist" }
|
||||
accompanist-systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" }
|
||||
|
Loading…
Reference in New Issue
Block a user