mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-06 02:37:26 +01:00
Merge 3107b1dd12
into 9580a00aa6
This commit is contained in:
commit
b79a45619a
@ -13,9 +13,11 @@ import eu.kanade.domain.manga.interactor.SetExcludedScanlators
|
||||
import eu.kanade.domain.manga.interactor.SetMangaViewerFlags
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.source.interactor.GetEnabledSources
|
||||
import eu.kanade.domain.source.interactor.GetIncognitoState
|
||||
import eu.kanade.domain.source.interactor.GetLanguagesWithSources
|
||||
import eu.kanade.domain.source.interactor.GetSourcesWithFavoriteCount
|
||||
import eu.kanade.domain.source.interactor.SetMigrateSorting
|
||||
import eu.kanade.domain.source.interactor.ToggleIncognitoSource
|
||||
import eu.kanade.domain.source.interactor.ToggleLanguage
|
||||
import eu.kanade.domain.source.interactor.ToggleSource
|
||||
import eu.kanade.domain.source.interactor.ToggleSourcePin
|
||||
@ -177,9 +179,11 @@ class DomainModule : InjektModule {
|
||||
addFactory { GetRemoteManga(get()) }
|
||||
addFactory { GetSourcesWithFavoriteCount(get(), get()) }
|
||||
addFactory { GetSourcesWithNonLibraryManga(get()) }
|
||||
addFactory { GetIncognitoState(get(), get()) }
|
||||
addFactory { SetMigrateSorting(get()) }
|
||||
addFactory { ToggleLanguage(get()) }
|
||||
addFactory { ToggleSource(get()) }
|
||||
addFactory { ToggleIncognitoSource(get()) }
|
||||
addFactory { ToggleSourcePin(get()) }
|
||||
addFactory { TrustExtension(get(), get()) }
|
||||
|
||||
|
@ -0,0 +1,15 @@
|
||||
package eu.kanade.domain.source.interactor
|
||||
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
|
||||
class GetIncognitoState(
|
||||
private val basePreferences: BasePreferences,
|
||||
private val sourcePreferences: SourcePreferences,
|
||||
) {
|
||||
fun isEnabled(sourceId: Long): Boolean {
|
||||
val globalIncognito = basePreferences.incognitoMode().get()
|
||||
val sourceIncognito = sourceId.toString() in sourcePreferences.incognitoSources().get()
|
||||
return globalIncognito || sourceIncognito
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package eu.kanade.domain.source.interactor
|
||||
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import tachiyomi.core.common.preference.getAndSet
|
||||
|
||||
class ToggleIncognitoSource(
|
||||
private val preferences: SourcePreferences,
|
||||
) {
|
||||
fun await(sourceIds: List<Long>, enable: Boolean) {
|
||||
val transformedSourceIds = sourceIds.map { it.toString() }
|
||||
preferences.incognitoSources().getAndSet { incognitoed ->
|
||||
if (enable) incognitoed.plus(transformedSourceIds) else incognitoed.minus(transformedSourceIds)
|
||||
}
|
||||
}
|
||||
}
|
@ -8,17 +8,17 @@ class ToggleSource(
|
||||
private val preferences: SourcePreferences,
|
||||
) {
|
||||
|
||||
fun await(source: Source, enable: Boolean = isEnabled(source.id)) {
|
||||
await(source.id, enable)
|
||||
fun awaitDisable(source: Source, enable: Boolean = isEnabled(source.id)) {
|
||||
awaitDisable(source.id, enable)
|
||||
}
|
||||
|
||||
fun await(sourceId: Long, enable: Boolean = isEnabled(sourceId)) {
|
||||
fun awaitDisable(sourceId: Long, enable: Boolean = isEnabled(sourceId)) {
|
||||
preferences.disabledSources().getAndSet { disabled ->
|
||||
if (enable) disabled.minus("$sourceId") else disabled.plus("$sourceId")
|
||||
}
|
||||
}
|
||||
|
||||
fun await(sourceIds: List<Long>, enable: Boolean) {
|
||||
fun awaitDisable(sourceIds: List<Long>, enable: Boolean) {
|
||||
val transformedSourceIds = sourceIds.map { it.toString() }
|
||||
preferences.disabledSources().getAndSet { disabled ->
|
||||
if (enable) disabled.minus(transformedSourceIds) else disabled.plus(transformedSourceIds)
|
||||
|
@ -22,6 +22,8 @@ class SourcePreferences(
|
||||
|
||||
fun disabledSources() = preferenceStore.getStringSet("hidden_catalogues", emptySet())
|
||||
|
||||
fun incognitoSources() = preferenceStore.getStringSet("incognito_catalogues", emptySet())
|
||||
|
||||
fun pinnedSources() = preferenceStore.getStringSet("pinned_catalogues", emptySet())
|
||||
|
||||
fun lastUsedSource() = preferenceStore.getLong(
|
||||
|
@ -35,8 +35,10 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
@ -48,6 +50,7 @@ import eu.kanade.presentation.components.AppBarActions
|
||||
import eu.kanade.presentation.components.WarningBanner
|
||||
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
|
||||
import eu.kanade.presentation.more.settings.widget.TrailingWidgetBuffer
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.extension.model.Extension
|
||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||
import eu.kanade.tachiyomi.ui.browse.extension.details.ExtensionDetailsScreenModel
|
||||
@ -66,12 +69,14 @@ import tachiyomi.presentation.core.screens.EmptyScreen
|
||||
fun ExtensionDetailsScreen(
|
||||
navigateUp: () -> Unit,
|
||||
state: ExtensionDetailsScreenModel.State,
|
||||
extIncognitoMode: Boolean,
|
||||
onClickSourcePreferences: (sourceId: Long) -> Unit,
|
||||
onClickEnableAll: () -> Unit,
|
||||
onClickDisableAll: () -> Unit,
|
||||
onClickClearCookies: () -> Unit,
|
||||
onClickUninstall: () -> Unit,
|
||||
onClickSource: (sourceId: Long) -> Unit,
|
||||
onExtIncognitoChange: (Boolean) -> Unit
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val url = remember(state.extension) {
|
||||
@ -140,9 +145,11 @@ fun ExtensionDetailsScreen(
|
||||
contentPadding = paddingValues,
|
||||
extension = state.extension,
|
||||
sources = state.sources,
|
||||
extIncognitoMode = extIncognitoMode,
|
||||
onClickSourcePreferences = onClickSourcePreferences,
|
||||
onClickUninstall = onClickUninstall,
|
||||
onClickSource = onClickSource,
|
||||
onExtIncognitoChange = onExtIncognitoChange,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -152,9 +159,11 @@ private fun ExtensionDetails(
|
||||
contentPadding: PaddingValues,
|
||||
extension: Extension.Installed,
|
||||
sources: ImmutableList<ExtensionSourceItem>,
|
||||
extIncognitoMode: Boolean,
|
||||
onClickSourcePreferences: (sourceId: Long) -> Unit,
|
||||
onClickUninstall: () -> Unit,
|
||||
onClickSource: (sourceId: Long) -> Unit,
|
||||
onExtIncognitoChange: (Boolean) -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
var showNsfwWarning by remember { mutableStateOf(false) }
|
||||
@ -171,6 +180,7 @@ private fun ExtensionDetails(
|
||||
item {
|
||||
DetailsHeader(
|
||||
extension = extension,
|
||||
extIncognitoMode = extIncognitoMode,
|
||||
onClickUninstall = onClickUninstall,
|
||||
onClickAppInfo = {
|
||||
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
|
||||
@ -182,6 +192,7 @@ private fun ExtensionDetails(
|
||||
onClickAgeRating = {
|
||||
showNsfwWarning = true
|
||||
},
|
||||
onExtIncognitoChange = onExtIncognitoChange,
|
||||
)
|
||||
}
|
||||
|
||||
@ -209,9 +220,11 @@ private fun ExtensionDetails(
|
||||
@Composable
|
||||
private fun DetailsHeader(
|
||||
extension: Extension,
|
||||
extIncognitoMode: Boolean,
|
||||
onClickAgeRating: () -> Unit,
|
||||
onClickUninstall: () -> Unit,
|
||||
onClickAppInfo: (() -> Unit)?,
|
||||
onExtIncognitoChange: (Boolean) -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
@ -317,7 +330,7 @@ private fun DetailsHeader(
|
||||
start = MaterialTheme.padding.medium,
|
||||
end = MaterialTheme.padding.medium,
|
||||
top = MaterialTheme.padding.small,
|
||||
bottom = MaterialTheme.padding.medium,
|
||||
bottom = MaterialTheme.padding.small,
|
||||
),
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.medium),
|
||||
) {
|
||||
@ -341,6 +354,35 @@ private fun DetailsHeader(
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.padding(
|
||||
start = MaterialTheme.padding.small,
|
||||
end = MaterialTheme.padding.small,
|
||||
top = MaterialTheme.padding.extraSmall,
|
||||
bottom = MaterialTheme.padding.medium,
|
||||
),
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.medium),
|
||||
) {
|
||||
TextPreferenceWidget(
|
||||
modifier = Modifier,
|
||||
title = stringResource(MR.strings.pref_incognito_mode),
|
||||
subtitle = stringResource(MR.strings.pref_incognito_mode_summary),
|
||||
icon = ImageVector.vectorResource(R.drawable.ic_glasses_24dp),
|
||||
widget = {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Switch(
|
||||
checked = extIncognitoMode,
|
||||
onCheckedChange = onExtIncognitoChange,
|
||||
modifier = Modifier.padding(start = TrailingWidgetBuffer),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
HorizontalDivider()
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.extension
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import eu.kanade.domain.extension.interactor.TrustExtension
|
||||
import eu.kanade.domain.source.interactor.ToggleIncognitoSource
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.tachiyomi.extension.api.ExtensionApi
|
||||
import eu.kanade.tachiyomi.extension.api.ExtensionUpdateNotifier
|
||||
@ -42,6 +43,8 @@ import java.util.Locale
|
||||
class ExtensionManager(
|
||||
private val context: Context,
|
||||
private val preferences: SourcePreferences = Injekt.get(),
|
||||
private val sourcePreferences: SourcePreferences = Injekt.get(),
|
||||
private val toggleIncognitoSource: ToggleIncognitoSource = Injekt.get(),
|
||||
private val trustExtension: TrustExtension = Injekt.get(),
|
||||
) {
|
||||
|
||||
@ -292,6 +295,19 @@ class ExtensionManager(
|
||||
* @param extension The extension to be registered.
|
||||
*/
|
||||
private fun registerUpdatedExtension(extension: Extension.Installed) {
|
||||
val oldExtension = installedExtensionMapFlow.value[extension.pkgName]
|
||||
if (oldExtension != null) {
|
||||
// If a extension has incognito mode enabled we need to consider that sources change and update them
|
||||
if (oldExtension.sources.first().id.toString() in sourcePreferences.incognitoSources().get()) {
|
||||
oldExtension.sources
|
||||
.map { it.id }
|
||||
.let { toggleIncognitoSource.await(it, false) }
|
||||
|
||||
extension.sources
|
||||
.map { it.id }
|
||||
.let { toggleIncognitoSource.await(it, true) }
|
||||
}
|
||||
}
|
||||
installedExtensionMapFlow.value += extension
|
||||
}
|
||||
|
||||
@ -302,6 +318,11 @@ class ExtensionManager(
|
||||
* @param pkgName The package name of the uninstalled application.
|
||||
*/
|
||||
private fun unregisterExtension(pkgName: String) {
|
||||
val installedExtension = installedExtensionMapFlow.value[pkgName]
|
||||
installedExtension?.sources?.map { it.id }?.let {
|
||||
toggleIncognitoSource.await(it, false)
|
||||
}
|
||||
|
||||
installedExtensionMapFlow.value -= pkgName
|
||||
untrustedExtensionMapFlow.value -= pkgName
|
||||
}
|
||||
|
@ -4,6 +4,9 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
@ -22,6 +25,8 @@ data class ExtensionDetailsScreen(
|
||||
val context = LocalContext.current
|
||||
val screenModel = rememberScreenModel { ExtensionDetailsScreenModel(pkgName = pkgName, context = context) }
|
||||
val state by screenModel.state.collectAsState()
|
||||
var isIncognitoMode by remember { mutableStateOf(screenModel.isIncognito()) }
|
||||
|
||||
|
||||
if (state.isLoading) {
|
||||
LoadingScreen()
|
||||
@ -33,12 +38,17 @@ data class ExtensionDetailsScreen(
|
||||
ExtensionDetailsScreen(
|
||||
navigateUp = navigator::pop,
|
||||
state = state,
|
||||
extIncognitoMode = isIncognitoMode,
|
||||
onClickSourcePreferences = { navigator.push(SourcePreferencesScreen(it)) },
|
||||
onClickEnableAll = { screenModel.toggleSources(true) },
|
||||
onClickDisableAll = { screenModel.toggleSources(false) },
|
||||
onClickClearCookies = screenModel::clearCookies,
|
||||
onClickUninstall = screenModel::uninstallExtension,
|
||||
onClickSource = screenModel::toggleSource,
|
||||
onExtIncognitoChange = { newState ->
|
||||
screenModel.toggleIncognito(newState)
|
||||
isIncognitoMode = screenModel.isIncognito()
|
||||
}
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
|
@ -6,7 +6,9 @@ import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.domain.extension.interactor.ExtensionSourceItem
|
||||
import eu.kanade.domain.extension.interactor.GetExtensionSources
|
||||
import eu.kanade.domain.source.interactor.ToggleIncognitoSource
|
||||
import eu.kanade.domain.source.interactor.ToggleSource
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.model.Extension
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
@ -36,6 +38,8 @@ class ExtensionDetailsScreenModel(
|
||||
private val extensionManager: ExtensionManager = Injekt.get(),
|
||||
private val getExtensionSources: GetExtensionSources = Injekt.get(),
|
||||
private val toggleSource: ToggleSource = Injekt.get(),
|
||||
private val toggleIncognitoSource: ToggleIncognitoSource = Injekt.get(),
|
||||
private val preferences: SourcePreferences = Injekt.get(),
|
||||
) : StateScreenModel<ExtensionDetailsScreenModel.State>(State()) {
|
||||
|
||||
private val _events: Channel<ExtensionDetailsEvent> = Channel()
|
||||
@ -109,13 +113,25 @@ class ExtensionDetailsScreenModel(
|
||||
}
|
||||
|
||||
fun toggleSource(sourceId: Long) {
|
||||
toggleSource.await(sourceId)
|
||||
toggleSource.awaitDisable(sourceId)
|
||||
}
|
||||
|
||||
fun toggleSources(enable: Boolean) {
|
||||
state.value.extension?.sources
|
||||
?.map { it.id }
|
||||
?.let { toggleSource.await(it, enable) }
|
||||
?.let { toggleSource.awaitDisable(it, enable) }
|
||||
}
|
||||
|
||||
fun toggleIncognito(enable: Boolean) {
|
||||
state.value.extension?.sources
|
||||
?.map { it.id }
|
||||
?.let { toggleIncognitoSource.await(it, enable) }
|
||||
}
|
||||
|
||||
fun isIncognito(): Boolean {
|
||||
return state.value.extension?.sources
|
||||
?.first()
|
||||
?.id.toString() in preferences.incognitoSources().get()
|
||||
}
|
||||
|
||||
@Immutable
|
||||
|
@ -51,7 +51,7 @@ class SourcesFilterScreenModel(
|
||||
}
|
||||
|
||||
fun toggleSource(source: Source) {
|
||||
toggleSource.await(source)
|
||||
toggleSource.awaitDisable(source)
|
||||
}
|
||||
|
||||
fun toggleLanguage(language: String) {
|
||||
|
@ -83,7 +83,7 @@ class SourcesScreenModel(
|
||||
}
|
||||
|
||||
fun toggleSource(source: Source) {
|
||||
toggleSource.await(source)
|
||||
toggleSource.awaitDisable(source)
|
||||
}
|
||||
|
||||
fun togglePin(source: Source) {
|
||||
|
@ -14,9 +14,9 @@ import androidx.paging.map
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.core.preference.asState
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.toDomainManga
|
||||
import eu.kanade.domain.source.interactor.GetIncognitoState
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.domain.track.interactor.AddTracks
|
||||
import eu.kanade.presentation.util.ioCoroutineScope
|
||||
@ -59,7 +59,6 @@ class BrowseSourceScreenModel(
|
||||
listingQuery: String?,
|
||||
sourceManager: SourceManager = Injekt.get(),
|
||||
sourcePreferences: SourcePreferences = Injekt.get(),
|
||||
basePreferences: BasePreferences = Injekt.get(),
|
||||
private val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||
private val coverCache: CoverCache = Injekt.get(),
|
||||
private val getRemoteManga: GetRemoteManga = Injekt.get(),
|
||||
@ -71,7 +70,8 @@ class BrowseSourceScreenModel(
|
||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
private val addTracks: AddTracks = Injekt.get(),
|
||||
) : StateScreenModel<BrowseSourceScreenModel.State>(State(Listing.valueOf(listingQuery))) {
|
||||
private val getIncognitoState: GetIncognitoState = Injekt.get(),
|
||||
) : StateScreenModel<BrowseSourceScreenModel.State>(State(Listing.valueOf(listingQuery))) {
|
||||
|
||||
var displayMode by sourcePreferences.sourceDisplayMode().asState(screenModelScope)
|
||||
|
||||
@ -96,7 +96,7 @@ class BrowseSourceScreenModel(
|
||||
}
|
||||
}
|
||||
|
||||
if (!basePreferences.incognitoMode().get()) {
|
||||
if (!getIncognitoState.isEnabled(source.id)) {
|
||||
sourcePreferences.lastUsedSource().set(source.id)
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ import eu.kanade.domain.chapter.model.toDbChapter
|
||||
import eu.kanade.domain.manga.interactor.SetMangaViewerFlags
|
||||
import eu.kanade.domain.manga.model.readerOrientation
|
||||
import eu.kanade.domain.manga.model.readingMode
|
||||
import eu.kanade.domain.source.interactor.GetIncognitoState
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.domain.track.interactor.TrackChapter
|
||||
import eu.kanade.domain.track.service.TrackPreferences
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainChapter
|
||||
@ -91,6 +93,7 @@ class ReaderViewModel @JvmOverloads constructor(
|
||||
val readerPreferences: ReaderPreferences = Injekt.get(),
|
||||
private val basePreferences: BasePreferences = Injekt.get(),
|
||||
private val downloadPreferences: DownloadPreferences = Injekt.get(),
|
||||
private val sourcePreferences: SourcePreferences = Injekt.get(),
|
||||
private val trackPreferences: TrackPreferences = Injekt.get(),
|
||||
private val trackChapter: TrackChapter = Injekt.get(),
|
||||
private val getManga: GetManga = Injekt.get(),
|
||||
@ -99,6 +102,7 @@ class ReaderViewModel @JvmOverloads constructor(
|
||||
private val upsertHistory: UpsertHistory = Injekt.get(),
|
||||
private val updateChapter: UpdateChapter = Injekt.get(),
|
||||
private val setMangaViewerFlags: SetMangaViewerFlags = Injekt.get(),
|
||||
private val getIncognitoState: GetIncognitoState = Injekt.get()
|
||||
) : ViewModel() {
|
||||
|
||||
private val mutableState = MutableStateFlow(State())
|
||||
@ -216,7 +220,10 @@ class ReaderViewModel @JvmOverloads constructor(
|
||||
.map(::ReaderChapter)
|
||||
}
|
||||
|
||||
private val incognitoMode = preferences.incognitoMode().get()
|
||||
// Use lazy here as manga can be null
|
||||
private val incognitoMode: Boolean by lazy {
|
||||
getIncognitoState.isEnabled(manga!!.source)
|
||||
}
|
||||
private val downloadAheadAmount = downloadPreferences.autoDownloadWhileReading().get()
|
||||
|
||||
init {
|
||||
|
Loading…
Reference in New Issue
Block a user