Add stable marker to Manga data class

Co-authored-by: ivan <12537387+ivaniskandar@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
This commit is contained in:
Secozzi 2024-10-28 11:57:58 +01:00
parent 2abb7be491
commit dd17832428
No known key found for this signature in database
GPG key ID: DD93E0B3A962AA86
12 changed files with 93 additions and 120 deletions

View file

@ -427,13 +427,9 @@ private fun AnimeScreenSmallImpl(
AnimeInfoBox( AnimeInfoBox(
isTabletUi = false, isTabletUi = false,
appBarPadding = topPadding, appBarPadding = topPadding,
title = state.anime.title, anime = state.anime,
author = state.anime.author,
artist = state.anime.artist,
sourceName = remember { state.source.getNameForAnimeInfo() }, sourceName = remember { state.source.getNameForAnimeInfo() },
isStubSource = remember { state.source is StubAnimeSource }, isStubSource = remember { state.source is StubAnimeSource },
coverDataProvider = { state.anime },
status = state.anime.status,
onCoverClick = onCoverClicked, onCoverClick = onCoverClicked,
doSearch = onSearch, doSearch = onSearch,
) )
@ -708,13 +704,9 @@ fun AnimeScreenLargeImpl(
AnimeInfoBox( AnimeInfoBox(
isTabletUi = true, isTabletUi = true,
appBarPadding = contentPadding.calculateTopPadding(), appBarPadding = contentPadding.calculateTopPadding(),
title = state.anime.title, anime = state.anime,
author = state.anime.author,
artist = state.anime.artist,
sourceName = remember { state.source.getNameForAnimeInfo() }, sourceName = remember { state.source.getNameForAnimeInfo() },
isStubSource = remember { state.source is StubAnimeSource }, isStubSource = remember { state.source is StubAnimeSource },
coverDataProvider = { state.anime },
status = state.anime.status,
onCoverClick = onCoverClicked, onCoverClick = onCoverClicked,
doSearch = onSearch, doSearch = onSearch,
) )

View file

@ -56,7 +56,7 @@ import tachiyomi.presentation.core.util.clickableNoIndication
@Composable @Composable
fun AnimeCoverDialog( fun AnimeCoverDialog(
coverDataProvider: () -> Anime, anime: Anime,
isCustomCover: Boolean, isCustomCover: Boolean,
snackbarHostState: SnackbarHostState, snackbarHostState: SnackbarHostState,
onShareClick: () -> Unit, onShareClick: () -> Unit,
@ -168,7 +168,7 @@ fun AnimeCoverDialog(
}, },
update = { view -> update = { view ->
val request = ImageRequest.Builder(view.context) val request = ImageRequest.Builder(view.context)
.data(coverDataProvider()) .data(anime)
.size(Size.ORIGINAL) .size(Size.ORIGINAL)
.memoryCachePolicy(CachePolicy.DISABLED) .memoryCachePolicy(CachePolicy.DISABLED)
.target { image -> .target { image ->

View file

@ -75,6 +75,8 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import coil3.request.crossfade
import eu.kanade.presentation.components.DropdownMenu import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.entries.components.DotSeparatorText import eu.kanade.presentation.entries.components.DotSeparatorText
import eu.kanade.presentation.entries.components.ItemCover import eu.kanade.presentation.entries.components.ItemCover
@ -100,13 +102,9 @@ private val whitespaceLineRegex = Regex("[\\r\\n]{2,}", setOf(RegexOption.MULTIL
fun AnimeInfoBox( fun AnimeInfoBox(
isTabletUi: Boolean, isTabletUi: Boolean,
appBarPadding: Dp, appBarPadding: Dp,
title: String, anime: Anime,
author: String?,
artist: String?,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
coverDataProvider: () -> Anime,
status: Long,
onCoverClick: () -> Unit, onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit, doSearch: (query: String, global: Boolean) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ -118,7 +116,10 @@ fun AnimeInfoBox(
MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.background,
) )
AsyncImage( AsyncImage(
model = coverDataProvider(), model = ImageRequest.Builder(LocalContext.current)
.data(anime)
.crossfade(true)
.build(),
contentDescription = null, contentDescription = null,
contentScale = ContentScale.Crop, contentScale = ContentScale.Crop,
modifier = Modifier modifier = Modifier
@ -138,28 +139,20 @@ fun AnimeInfoBox(
if (!isTabletUi) { if (!isTabletUi) {
AnimeAndSourceTitlesSmall( AnimeAndSourceTitlesSmall(
appBarPadding = appBarPadding, appBarPadding = appBarPadding,
coverDataProvider = coverDataProvider, anime = anime,
onCoverClick = onCoverClick,
title = title,
doSearch = doSearch,
author = author,
artist = artist,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
onCoverClick = onCoverClick,
doSearch = doSearch,
) )
} else { } else {
AnimeAndSourceTitlesLarge( AnimeAndSourceTitlesLarge(
appBarPadding = appBarPadding, appBarPadding = appBarPadding,
coverDataProvider = coverDataProvider, anime = anime,
onCoverClick = onCoverClick,
title = title,
doSearch = doSearch,
author = author,
artist = artist,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
onCoverClick = onCoverClick,
doSearch = doSearch,
) )
} }
} }
@ -343,15 +336,11 @@ fun ExpandableAnimeDescription(
@Composable @Composable
private fun AnimeAndSourceTitlesLarge( private fun AnimeAndSourceTitlesLarge(
appBarPadding: Dp, appBarPadding: Dp,
coverDataProvider: () -> Anime, anime: Anime,
onCoverClick: () -> Unit,
title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?,
artist: String?,
status: Long,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit,
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier
@ -361,19 +350,22 @@ private fun AnimeAndSourceTitlesLarge(
) { ) {
ItemCover.Book( ItemCover.Book(
modifier = Modifier.fillMaxWidth(0.65f), modifier = Modifier.fillMaxWidth(0.65f),
data = coverDataProvider(), data = ImageRequest.Builder(LocalContext.current)
.data(anime)
.crossfade(true)
.build(),
contentDescription = stringResource(MR.strings.manga_cover), contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick, onClick = onCoverClick,
) )
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
AnimeContentInfo( AnimeContentInfo(
title = title, title = anime.title,
doSearch = doSearch, author = anime.author,
author = author, artist = anime.artist,
artist = artist, status = anime.status,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
doSearch = doSearch,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
) )
} }
@ -382,15 +374,11 @@ private fun AnimeAndSourceTitlesLarge(
@Composable @Composable
private fun AnimeAndSourceTitlesSmall( private fun AnimeAndSourceTitlesSmall(
appBarPadding: Dp, appBarPadding: Dp,
coverDataProvider: () -> Anime, anime: Anime,
onCoverClick: () -> Unit,
title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?,
artist: String?,
status: Long,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit,
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
@ -403,7 +391,10 @@ private fun AnimeAndSourceTitlesSmall(
modifier = Modifier modifier = Modifier
.sizeIn(maxWidth = 100.dp) .sizeIn(maxWidth = 100.dp)
.align(Alignment.Top), .align(Alignment.Top),
data = coverDataProvider(), data = ImageRequest.Builder(LocalContext.current)
.data(anime)
.crossfade(true)
.build(),
contentDescription = stringResource(MR.strings.manga_cover), contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick, onClick = onCoverClick,
) )
@ -411,13 +402,13 @@ private fun AnimeAndSourceTitlesSmall(
verticalArrangement = Arrangement.spacedBy(2.dp), verticalArrangement = Arrangement.spacedBy(2.dp),
) { ) {
AnimeContentInfo( AnimeContentInfo(
title = title, title = anime.title,
doSearch = doSearch, author = anime.author,
author = author, artist = anime.artist,
artist = artist, status = anime.status,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
doSearch = doSearch,
) )
} }
} }
@ -426,12 +417,12 @@ private fun AnimeAndSourceTitlesSmall(
@Composable @Composable
private fun ColumnScope.AnimeContentInfo( private fun ColumnScope.AnimeContentInfo(
title: String, title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?, author: String?,
artist: String?, artist: String?,
status: Long, status: Long,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
doSearch: (query: String, global: Boolean) -> Unit,
textAlign: TextAlign? = LocalTextStyle.current.textAlign, textAlign: TextAlign? = LocalTextStyle.current.textAlign,
) { ) {
val context = LocalContext.current val context = LocalContext.current

View file

@ -397,13 +397,9 @@ private fun MangaScreenSmallImpl(
MangaInfoBox( MangaInfoBox(
isTabletUi = false, isTabletUi = false,
appBarPadding = topPadding, appBarPadding = topPadding,
title = state.manga.title, manga = state.manga,
author = state.manga.author,
artist = state.manga.artist,
sourceName = remember { state.source.getNameForMangaInfo() }, sourceName = remember { state.source.getNameForMangaInfo() },
isStubSource = remember { state.source is StubMangaSource }, isStubSource = remember { state.source is StubMangaSource },
coverDataProvider = { state.manga },
status = state.manga.status,
onCoverClick = onCoverClicked, onCoverClick = onCoverClicked,
doSearch = onSearch, doSearch = onSearch,
) )
@ -644,13 +640,9 @@ fun MangaScreenLargeImpl(
MangaInfoBox( MangaInfoBox(
isTabletUi = true, isTabletUi = true,
appBarPadding = contentPadding.calculateTopPadding(), appBarPadding = contentPadding.calculateTopPadding(),
title = state.manga.title, manga = state.manga,
author = state.manga.author,
artist = state.manga.artist,
sourceName = remember { state.source.getNameForMangaInfo() }, sourceName = remember { state.source.getNameForMangaInfo() },
isStubSource = remember { state.source is StubMangaSource }, isStubSource = remember { state.source is StubMangaSource },
coverDataProvider = { state.manga },
status = state.manga.status,
onCoverClick = onCoverClicked, onCoverClick = onCoverClicked,
doSearch = onSearch, doSearch = onSearch,
) )

View file

@ -56,7 +56,7 @@ import tachiyomi.presentation.core.util.clickableNoIndication
@Composable @Composable
fun MangaCoverDialog( fun MangaCoverDialog(
coverDataProvider: () -> Manga, manga: Manga,
isCustomCover: Boolean, isCustomCover: Boolean,
snackbarHostState: SnackbarHostState, snackbarHostState: SnackbarHostState,
onShareClick: () -> Unit, onShareClick: () -> Unit,
@ -168,7 +168,7 @@ fun MangaCoverDialog(
}, },
update = { view -> update = { view ->
val request = ImageRequest.Builder(view.context) val request = ImageRequest.Builder(view.context)
.data(coverDataProvider()) .data(manga)
.size(Size.ORIGINAL) .size(Size.ORIGINAL)
.memoryCachePolicy(CachePolicy.DISABLED) .memoryCachePolicy(CachePolicy.DISABLED)
.target { image -> .target { image ->

View file

@ -75,6 +75,8 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import coil3.request.crossfade
import eu.kanade.presentation.components.DropdownMenu import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.entries.components.DotSeparatorText import eu.kanade.presentation.entries.components.DotSeparatorText
import eu.kanade.presentation.entries.components.ItemCover import eu.kanade.presentation.entries.components.ItemCover
@ -100,13 +102,9 @@ private val whitespaceLineRegex = Regex("[\\r\\n]{2,}", setOf(RegexOption.MULTIL
fun MangaInfoBox( fun MangaInfoBox(
isTabletUi: Boolean, isTabletUi: Boolean,
appBarPadding: Dp, appBarPadding: Dp,
title: String, manga: Manga,
author: String?,
artist: String?,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
coverDataProvider: () -> Manga,
status: Long,
onCoverClick: () -> Unit, onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit, doSearch: (query: String, global: Boolean) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ -118,7 +116,10 @@ fun MangaInfoBox(
MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.background,
) )
AsyncImage( AsyncImage(
model = coverDataProvider(), model = ImageRequest.Builder(LocalContext.current)
.data(manga)
.crossfade(true)
.build(),
contentDescription = null, contentDescription = null,
contentScale = ContentScale.Crop, contentScale = ContentScale.Crop,
modifier = Modifier modifier = Modifier
@ -138,28 +139,20 @@ fun MangaInfoBox(
if (!isTabletUi) { if (!isTabletUi) {
MangaAndSourceTitlesSmall( MangaAndSourceTitlesSmall(
appBarPadding = appBarPadding, appBarPadding = appBarPadding,
coverDataProvider = coverDataProvider, manga = manga,
onCoverClick = onCoverClick,
title = title,
doSearch = doSearch,
author = author,
artist = artist,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
onCoverClick = onCoverClick,
doSearch = doSearch,
) )
} else { } else {
MangaAndSourceTitlesLarge( MangaAndSourceTitlesLarge(
appBarPadding = appBarPadding, appBarPadding = appBarPadding,
coverDataProvider = coverDataProvider, manga = manga,
onCoverClick = onCoverClick,
title = title,
doSearch = doSearch,
author = author,
artist = artist,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
onCoverClick = onCoverClick,
doSearch = doSearch,
) )
} }
} }
@ -342,15 +335,11 @@ fun ExpandableMangaDescription(
@Composable @Composable
private fun MangaAndSourceTitlesLarge( private fun MangaAndSourceTitlesLarge(
appBarPadding: Dp, appBarPadding: Dp,
coverDataProvider: () -> Manga, manga: Manga,
onCoverClick: () -> Unit,
title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?,
artist: String?,
status: Long,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit,
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier
@ -360,19 +349,22 @@ private fun MangaAndSourceTitlesLarge(
) { ) {
ItemCover.Book( ItemCover.Book(
modifier = Modifier.fillMaxWidth(0.65f), modifier = Modifier.fillMaxWidth(0.65f),
data = coverDataProvider(), data = ImageRequest.Builder(LocalContext.current)
.data(manga)
.crossfade(true)
.build(),
contentDescription = stringResource(MR.strings.manga_cover), contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick, onClick = onCoverClick,
) )
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
MangaContentInfo( MangaContentInfo(
title = title, title = manga.title,
doSearch = doSearch, author = manga.author,
author = author, artist = manga.artist,
artist = artist, status = manga.status,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
doSearch = doSearch,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
) )
} }
@ -381,15 +373,11 @@ private fun MangaAndSourceTitlesLarge(
@Composable @Composable
private fun MangaAndSourceTitlesSmall( private fun MangaAndSourceTitlesSmall(
appBarPadding: Dp, appBarPadding: Dp,
coverDataProvider: () -> Manga, manga: Manga,
onCoverClick: () -> Unit,
title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?,
artist: String?,
status: Long,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit,
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
@ -402,7 +390,10 @@ private fun MangaAndSourceTitlesSmall(
modifier = Modifier modifier = Modifier
.sizeIn(maxWidth = 100.dp) .sizeIn(maxWidth = 100.dp)
.align(Alignment.Top), .align(Alignment.Top),
data = coverDataProvider(), data = ImageRequest.Builder(LocalContext.current)
.data(manga)
.crossfade(true)
.build(),
contentDescription = stringResource(MR.strings.manga_cover), contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick, onClick = onCoverClick,
) )
@ -410,13 +401,13 @@ private fun MangaAndSourceTitlesSmall(
verticalArrangement = Arrangement.spacedBy(2.dp), verticalArrangement = Arrangement.spacedBy(2.dp),
) { ) {
MangaContentInfo( MangaContentInfo(
title = title, title = manga.title,
doSearch = doSearch, author = manga.author,
author = author, artist = manga.artist,
artist = artist, status = manga.status,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
doSearch = doSearch,
) )
} }
} }
@ -425,12 +416,12 @@ private fun MangaAndSourceTitlesSmall(
@Composable @Composable
private fun ColumnScope.MangaContentInfo( private fun ColumnScope.MangaContentInfo(
title: String, title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?, author: String?,
artist: String?, artist: String?,
status: Long, status: Long,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
doSearch: (query: String, global: Boolean) -> Unit,
textAlign: TextAlign? = LocalTextStyle.current.textAlign, textAlign: TextAlign? = LocalTextStyle.current.textAlign,
) { ) {
val context = LocalContext.current val context = LocalContext.current

View file

@ -277,7 +277,7 @@ class AnimeScreen(
sm.editCover(context, it) sm.editCover(context, it)
} }
AnimeCoverDialog( AnimeCoverDialog(
coverDataProvider = { anime!! }, anime = anime!!,
snackbarHostState = sm.snackbarHostState, snackbarHostState = sm.snackbarHostState,
isCustomCover = remember(anime) { anime!!.hasCustomCover() }, isCustomCover = remember(anime) { anime!!.hasCustomCover() },
onShareClick = { sm.shareCover(context) }, onShareClick = { sm.shareCover(context) },

View file

@ -261,7 +261,7 @@ class MangaScreen(
sm.editCover(context, it) sm.editCover(context, it)
} }
MangaCoverDialog( MangaCoverDialog(
coverDataProvider = { manga!! }, manga = manga!!,
snackbarHostState = sm.snackbarHostState, snackbarHostState = sm.snackbarHostState,
isCustomCover = remember(manga) { manga!!.hasCustomCover() }, isCustomCover = remember(manga) { manga!!.hasCustomCover() },
onShareClick = { sm.shareCover(context) }, onShareClick = { sm.shareCover(context) },

View file

@ -25,6 +25,8 @@ dependencies {
api(libs.sqldelight.android.paging) api(libs.sqldelight.android.paging)
compileOnly(libs.compose.stablemarker)
testImplementation(libs.bundles.test) testImplementation(libs.bundles.test)
testImplementation(kotlinx.coroutines.test) testImplementation(kotlinx.coroutines.test)
} }

View file

@ -1,5 +1,6 @@
package tachiyomi.domain.entries.anime.model package tachiyomi.domain.entries.anime.model
import androidx.compose.runtime.Immutable
import eu.kanade.tachiyomi.animesource.model.AnimeUpdateStrategy import eu.kanade.tachiyomi.animesource.model.AnimeUpdateStrategy
import eu.kanade.tachiyomi.animesource.model.SAnime import eu.kanade.tachiyomi.animesource.model.SAnime
import tachiyomi.core.common.preference.TriState import tachiyomi.core.common.preference.TriState
@ -7,6 +8,7 @@ import java.io.Serializable
import java.time.Instant import java.time.Instant
import kotlin.math.pow import kotlin.math.pow
@Immutable
data class Anime( data class Anime(
val id: Long, val id: Long,
val source: Long, val source: Long,

View file

@ -1,11 +1,13 @@
package tachiyomi.domain.entries.manga.model package tachiyomi.domain.entries.manga.model
import androidx.compose.runtime.Immutable
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.UpdateStrategy import eu.kanade.tachiyomi.source.model.UpdateStrategy
import tachiyomi.core.common.preference.TriState import tachiyomi.core.common.preference.TriState
import java.io.Serializable import java.io.Serializable
import java.time.Instant import java.time.Instant
@Immutable
data class Manga( data class Manga(
val id: Long, val id: Long,
val source: Long, val source: Long,

View file

@ -63,6 +63,7 @@ insetter = "dev.chrisbanes.insetter:insetter:0.6.1"
compose-materialmotion = "io.github.fornewid:material-motion-compose-core:2.0.1" compose-materialmotion = "io.github.fornewid:material-motion-compose-core:2.0.1"
compose-webview = "io.github.kevinnzou:compose-webview:0.33.6" compose-webview = "io.github.kevinnzou:compose-webview:0.33.6"
compose-grid = "io.woong.compose.grid:grid:1.2.2" compose-grid = "io.woong.compose.grid:grid:1.2.2"
compose-stablemarker = "com.github.skydoves:compose-stable-marker:1.0.5"
swipe = "me.saket.swipe:swipe:1.3.0" swipe = "me.saket.swipe:swipe:1.3.0"