From 083488433573052d194a31e5e5f57e383f8ba9b7 Mon Sep 17 00:00:00 2001 From: AntsyLich <59261191+AntsyLich@users.noreply.github.com> Date: Sat, 8 Aug 2026 11:57:55 +0600 Subject: [PATCH] Make MangaCoverViewModel collect manga only while subscribed (#3716) Assisted-by: Claude:claude-opus-5 --- .../tachiyomi/ui/manga/MangaCoverViewModel.kt | 22 ++++++++++--------- .../kanade/tachiyomi/ui/manga/MangaScreen.kt | 3 +-- .../data/manga/MangaRepositoryImpl.kt | 2 +- .../domain/manga/interactor/GetManga.kt | 2 +- .../manga/repository/MangaRepository.kt | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaCoverViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaCoverViewModel.kt index d8887d3e3..e996e7634 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaCoverViewModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaCoverViewModel.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.manga import android.content.Context import android.net.Uri import androidx.compose.material3.SnackbarHostState +import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.CreationExtras import androidx.lifecycle.viewmodel.initializer @@ -19,10 +20,14 @@ import eu.kanade.tachiyomi.data.saver.Location import eu.kanade.tachiyomi.util.editCover import eu.kanade.tachiyomi.util.system.getBitmapOrNull import eu.kanade.tachiyomi.util.system.toShareIntent -import kotlinx.coroutines.flow.update +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.WhileSubscribed +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import logcat.LogPriority -import mihon.core.viewmodel.StateViewModel import tachiyomi.core.common.i18n.stringResource import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.withIOContext @@ -33,6 +38,7 @@ import tachiyomi.domain.manga.model.Manga import tachiyomi.i18n.MR import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import kotlin.time.Duration.Companion.seconds class MangaCoverViewModel( private val mangaId: Long, @@ -42,7 +48,7 @@ class MangaCoverViewModel( private val updateManga: UpdateManga = Injekt.get(), val snackbarHostState: SnackbarHostState = SnackbarHostState(), -) : StateViewModel(null) { +) : ViewModel() { companion object { val MANGA_ID_KEY = CreationExtras.Key() @@ -56,12 +62,9 @@ class MangaCoverViewModel( } } - init { - viewModelScope.launchIO { - getManga.subscribe(mangaId) - .collect { newManga -> mutableState.update { newManga } } - } - } + val state: StateFlow = getManga.subscribe(mangaId) + .flowOn(Dispatchers.IO) + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5.seconds), null) fun saveCover(context: Context) { viewModelScope.launch { @@ -147,7 +150,6 @@ class MangaCoverViewModel( } fun deleteCustomCover(context: Context) { - val mangaId = state.value?.id ?: return viewModelScope.launchIO { try { coverCache.deleteCustomCover(mangaId) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt index 6240a8cc8..d577fd377 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt @@ -6,7 +6,6 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.layout.systemBarsPadding 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 @@ -250,7 +249,7 @@ class MangaScreen( set(MangaCoverViewModel.MANGA_ID_KEY, successState.manga.id) }, ) - val manga by sm.state.collectAsState() + val manga by sm.state.collectAsStateWithLifecycle() if (manga != null) { val getContent = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { if (it == null) return@rememberLauncherForActivityResult diff --git a/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt b/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt index 74820f142..833a26763 100644 --- a/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt +++ b/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt @@ -33,7 +33,7 @@ class MangaRepositoryImpl( .awaitAsOne() } - override suspend fun getMangaByIdAsFlow(id: Long): Flow { + override fun getMangaByIdAsFlow(id: Long): Flow { return database.mangasQueries .getMangaById(id, MangaMapper::mapManga) .subscribeToOne() diff --git a/domain/src/main/java/tachiyomi/domain/manga/interactor/GetManga.kt b/domain/src/main/java/tachiyomi/domain/manga/interactor/GetManga.kt index d4cad69d6..bbe22f989 100644 --- a/domain/src/main/java/tachiyomi/domain/manga/interactor/GetManga.kt +++ b/domain/src/main/java/tachiyomi/domain/manga/interactor/GetManga.kt @@ -19,7 +19,7 @@ class GetManga( } } - suspend fun subscribe(id: Long): Flow { + fun subscribe(id: Long): Flow { return mangaRepository.getMangaByIdAsFlow(id) } diff --git a/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt b/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt index e1111ec57..68363df03 100644 --- a/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt +++ b/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt @@ -10,7 +10,7 @@ interface MangaRepository { suspend fun getMangaById(id: Long): Manga - suspend fun getMangaByIdAsFlow(id: Long): Flow + fun getMangaByIdAsFlow(id: Long): Flow suspend fun getMangaByUrlAndSourceId(url: String, sourceId: Long): Manga?