Revert "Migrate from Parcelize to kotlinx.serialization" (#2356)

This reverts commit 857b1d9b57.

Reason for revert: https://github.com/FooIbar/EhViewer/issues/2355
This commit is contained in:
FooIbar authored and GitHub committed 2025-05-23 16:21:11 +00:00
1 parent 251b99f76d
commit c2e53cc8b9
27 files changed
+138 -94

No files matched your search

+1
View File
@@ -10,6 +10,7 @@ plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.ksp)
alias(libs.plugins.spotless)
@@ -15,6 +15,7 @@
*/
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
@@ -22,8 +23,10 @@ import androidx.room.PrimaryKey
import androidx.room.TypeConverter
import androidx.room.TypeConverters
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.NOT_FAVORITED
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
@Parcelize
@Serializable
@Entity(tableName = "GALLERIES")
@TypeConverters(SimpleTagsConverter::class)
@@ -85,7 +88,7 @@ data class BaseGalleryInfo(
@Ignore
override var favoriteNote: String? = null,
) : GalleryInfo
) : GalleryInfo, Parcelable
class SimpleTagsConverter {
@TypeConverter
@@ -15,20 +15,21 @@
*/
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.addQueryParameter
import com.hippo.ehviewer.client.addQueryParameterIfNotBlank
import com.hippo.ehviewer.client.ehUrl
import kotlinx.serialization.Serializable
import kotlinx.parcelize.Parcelize
@Serializable
@Parcelize
data class FavListUrlBuilder(
val favCat: Int = FAV_CAT_ALL,
val keyword: String? = null,
var jumpTo: String? = null,
var prev: String? = null,
var next: String? = null,
) {
) : Parcelable {
fun setIndex(index: String?, isNext: Boolean) {
next = index.takeIf { isNext }
prev = index.takeUnless { isNext }
@@ -15,6 +15,10 @@
*/
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class GalleryComment(
val id: Long,
val score: Int,
@@ -29,4 +33,4 @@ data class GalleryComment(
val user: String?,
val comment: String,
val lastEdited: Long,
)
) : Parcelable
@@ -15,7 +15,11 @@
*/
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class GalleryCommentList(
val comments: List<GalleryComment>,
val hasMore: Boolean,
)
) : Parcelable
@@ -15,8 +15,10 @@
*/
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import androidx.compose.ui.util.fastFlatMap
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.S_LANGS
import kotlinx.parcelize.Parcelize
private val LANGUAGES = arrayOf(
"English",
@@ -35,6 +37,7 @@ private val LANGUAGES = arrayOf(
"Dutch",
)
@Parcelize
data class GalleryDetail(
val galleryInfo: BaseGalleryInfo = BaseGalleryInfo(),
var apiUid: Long = -1L,
@@ -52,7 +55,7 @@ data class GalleryDetail(
val tagGroups: List<GalleryTagGroup>,
var comments: GalleryCommentList,
val previewList: List<GalleryPreview>,
) : GalleryInfo by galleryInfo {
) : GalleryInfo by galleryInfo, Parcelable {
fun fillInfo() {
val index = LANGUAGES.indexOf(language)
if (index != -1) simpleLanguage = S_LANGS[index]
@@ -15,14 +15,17 @@
*/
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import com.hippo.ehviewer.client.keyToUrl
import kotlinx.parcelize.Parcelize
sealed interface GalleryPreview {
sealed interface GalleryPreview : Parcelable {
val url: String
val imageKey: String
val position: Int
}
@Parcelize
data class V1GalleryPreview(
override val imageKey: String,
override val position: Int,
@@ -30,6 +33,7 @@ data class V1GalleryPreview(
override val url get() = keyToUrl(imageKey)
}
@Parcelize
data class V2GalleryPreview(
override val url: String,
override val imageKey: String,
@@ -1,5 +1,8 @@
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
enum class VoteStatus(val display: String) {
NONE(""),
UP("+1"),
@@ -12,8 +15,9 @@ enum class PowerStatus {
WEAK,
}
@Parcelize
data class GalleryTag(
val text: String,
val power: PowerStatus,
val vote: VoteStatus,
)
) : Parcelable
@@ -15,7 +15,11 @@
*/
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class GalleryTagGroup(
val nameSpace: TagNamespace,
val tags: List<GalleryTag>,
)
) : Parcelable
@@ -15,6 +15,7 @@
*/
package com.hippo.ehviewer.client.data
import android.os.Parcelable
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.EhUtils
@@ -25,9 +26,9 @@ import com.hippo.ehviewer.dao.QuickSearch
import com.hippo.ehviewer.ui.main.AdvanceTable
import io.ktor.http.Parameters
import kotlin.text.toIntOrNull
import kotlinx.serialization.Serializable
import kotlinx.parcelize.Parcelize
@Serializable
@Parcelize
data class ListUrlBuilder(
var mode: Int = MODE_NORMAL,
private var prev: String? = null,
@@ -43,7 +44,7 @@ data class ListUrlBuilder(
var minRating: Int = -1,
var pageFrom: Int = -1,
var pageTo: Int = -1,
) {
) : Parcelable {
fun setIndex(index: String, isNext: Boolean = true) {
next = index.takeIf { isNext }
@@ -1,6 +1,10 @@
package com.hippo.ehviewer.client.data
sealed class TagNamespace(val value: String, val prefix: String?) {
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
sealed class TagNamespace(val value: String, val prefix: String?) : Parcelable {
object Artist : TagNamespace("artist", "a")
object Cosplayer : TagNamespace("cosplayer", "cos")
object Character : TagNamespace("character", "c")
@@ -1,9 +1,12 @@
package com.hippo.ehviewer.client.parser
import android.os.Parcelable
import com.hippo.ehviewer.client.exception.InsufficientFundsException
import com.hippo.ehviewer.client.exception.ParseException
import java.nio.ByteBuffer
import kotlin.random.Random
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
object HomeParser {
private val TorrentKeyRegex = Regex("Your current key is: <[^>]*>([^<]*)<")
@@ -32,11 +35,15 @@ object HomeParser {
throw ParseException("Parse funds error")
}
data class Result(val limits: Limits, val funds: Funds, private val id: Int = Random.nextInt())
@Parcelize
data class Result(val limits: Limits, val funds: Funds, private val id: Int = Random.nextInt()) : Parcelable
}
data class Funds(val gp: Int, val credit: Int)
@Parcelize
data class Funds(val gp: Int, val credit: Int) : Parcelable
data class Limits(val current: Int, val maximum: Int, val resetCost: Int)
@Parcelize
@Serializable
data class Limits(val current: Int, val maximum: Int, val resetCost: Int) : Parcelable
private external fun parseLimit(body: ByteBuffer, limit: Int = body.limit()): Int
@@ -18,7 +18,6 @@ package com.hippo.ehviewer.download
import android.Manifest
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
@@ -28,9 +27,6 @@ import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.ServiceCompat
import androidx.core.content.ContextCompat
import androidx.savedstate.serialization.decodeFromSavedState
import androidx.savedstate.serialization.encodeToSavedState
import com.hippo.ehviewer.R
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.client.data.BaseGalleryInfo
@@ -38,6 +34,7 @@ import com.hippo.ehviewer.dao.DownloadInfo
import com.hippo.ehviewer.ui.MainActivity
import com.hippo.ehviewer.util.FileUtils
import com.hippo.ehviewer.util.ReadableTime
import com.hippo.ehviewer.util.getParcelableExtraCompat
import com.hippo.ehviewer.util.unsafeLazy
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.CoroutineScope
@@ -98,9 +95,11 @@ class DownloadService :
private suspend fun handleIntent(intent: Intent?) {
when (intent?.action) {
ACTION_START -> {
val gi = intent.getBundleExtra(KEY_GALLERY_INFO) ?: return
val gi = intent.getParcelableExtraCompat<BaseGalleryInfo>(KEY_GALLERY_INFO)
val label = intent.getStringExtra(KEY_LABEL)
deferredMgr.await().startDownload(decodeFromSavedState(gi), label)
if (gi != null) {
deferredMgr.await().startDownload(gi, label)
}
}
ACTION_START_RANGE -> {
@@ -455,23 +454,6 @@ class DownloadService :
private var sFinishedCount = 0
private var sDownloadedCount = 0
context(ctx: Context)
inline fun startService(action: String, intentBuilder: Intent.() -> Unit = {}) {
val intent = Intent(ctx, DownloadService::class.java).setAction(action).apply(intentBuilder)
ContextCompat.startForegroundService(ctx, intent)
}
context(_: Context)
fun startDownload(info: BaseGalleryInfo, label: String? = null) = startService(ACTION_START) {
putExtra(KEY_GALLERY_INFO, encodeToSavedState(info))
label?.let { putExtra(KEY_LABEL, it) }
}
context(_: Context)
fun startRangeDownload(gidList: LongArray) = startService(ACTION_START_RANGE) {
putExtra(KEY_GID_LIST, gidList)
}
fun clear() {
sFailedCount = 0
sFinishedCount = 0
@@ -15,8 +15,10 @@
*/
package com.hippo.ehviewer.shortcuts
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.hippo.ehviewer.download.DownloadService
/**
@@ -25,8 +27,8 @@ import com.hippo.ehviewer.download.DownloadService
class ShortcutsActivity : AppCompatActivity() {
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
when (val action = intent?.action) {
DownloadService.ACTION_START_ALL, DownloadService.ACTION_STOP_ALL -> DownloadService.startService(action)
when (intent?.action) {
DownloadService.ACTION_START_ALL, DownloadService.ACTION_STOP_ALL -> ContextCompat.startForegroundService(this, Intent(this, DownloadService::class.java).setAction(intent.action))
}
finish()
}
@@ -17,6 +17,8 @@ package com.hippo.ehviewer.ui
import android.Manifest
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
@@ -35,6 +37,7 @@ import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
@@ -121,8 +124,11 @@ suspend fun startDownload(forceDefault: Boolean, vararg galleryInfos: BaseGaller
}
val (toStart, toAdd) = galleryInfos.partition { DownloadManager.containDownloadInfo(it.gid) }
if (toStart.isNotEmpty()) {
val intent = Intent(context, DownloadService::class.java)
intent.action = DownloadService.ACTION_START_RANGE
val list = toStart.mapToLongArray(GalleryInfo::gid)
DownloadService.startRangeDownload(list)
intent.putExtra(DownloadService.KEY_GID_LIST, list)
ContextCompat.startForegroundService(context, intent)
}
if (toAdd.isEmpty()) {
return tip(R.string.added_to_download_list)
@@ -142,7 +148,11 @@ suspend fun startDownload(forceDefault: Boolean, vararg galleryInfos: BaseGaller
if (justStart) {
// Got default label
for (gi in toAdd) {
DownloadService.startDownload(gi, label)
val intent = Intent(context, DownloadService::class.java)
intent.action = DownloadService.ACTION_START
intent.putExtra(DownloadService.KEY_LABEL, label)
intent.putExtra(DownloadService.KEY_GALLERY_INFO, gi)
ContextCompat.startForegroundService(context, intent)
}
// Notify
tip(R.string.added_to_download_list)
@@ -163,7 +173,11 @@ suspend fun startDownload(forceDefault: Boolean, vararg galleryInfos: BaseGaller
val label1 = if (selected == 0) null else items[selected].takeIf { DownloadManager.containLabel(it) }
// Start download
for (gi in toAdd) {
DownloadService.startDownload(gi, label1)
val intent = Intent(context, DownloadService::class.java)
intent.action = DownloadService.ACTION_START
intent.putExtra(DownloadService.KEY_LABEL, label1)
intent.putExtra(DownloadService.KEY_GALLERY_INFO, gi)
ContextCompat.startForegroundService(context, intent)
}
// Save settings
if (checked) {
@@ -272,7 +286,7 @@ context(_: DestinationsNavigator)
fun navToReader(info: BaseGalleryInfo, page: Int = -1) = navToReader(ReaderScreenArgs.Gallery(info, page))
context(_: DestinationsNavigator)
fun navToReader(path: String) = navToReader(ReaderScreenArgs.Archive(path))
fun navToReader(uri: Uri) = navToReader(ReaderScreenArgs.Archive(uri))
context(nav: DestinationsNavigator)
private fun navToReader(args: ReaderScreenArgs) = nav.navigate(ReaderScreenDestination(args)) { launchSingleTop = true }
@@ -258,32 +258,32 @@ class MainActivity : EhActivity() {
LaunchedEffect(Unit) {
intentFlow.collect { intent ->
when (intent.action) {
Intent.ACTION_VIEW -> with(navigator) {
Intent.ACTION_VIEW -> {
val uri = intent.data ?: return@collect
when (uri.scheme) {
SCHEME_FILE -> navToReader(uri.path!!)
SCHEME_CONTENT -> navToReader(uri.toString())
SCHEME_CONTENT, SCHEME_FILE -> with(navigator) { navToReader(uri) }
else -> {
val url = uri.toString()
if (!navWithUrl(url)) {
if (!with(navigator) { navWithUrl(url) }) {
val new = awaitInputText(initial = url, title = cannotParse)
addTextToClipboard(new)
}
}
}
}
Intent.ACTION_SEND -> with(navigator) {
Intent.ACTION_SEND -> {
val type = intent.type
if ("text/plain" == type) {
val keyword = intent.getStringExtra(Intent.EXTRA_TEXT)
if (keyword != null && !navWithUrl(keyword)) {
navigate(ListUrlBuilder(mKeyword = keyword).asDst())
if (keyword != null && !with(navigator) { navWithUrl(keyword) }) {
navigator.navigate(ListUrlBuilder(mKeyword = keyword).asDst())
}
} else if (type != null && type.startsWith("image/")) {
val uri = intent.getParcelableExtraCompat<Uri>(Intent.EXTRA_STREAM)
if (null != uri) {
val hash = withIOContext { uri.toOkioPath().sha1() }
navigate(
navigator.navigate(
ListUrlBuilder(
mode = ListUrlBuilder.MODE_IMAGE_SEARCH,
hash = hash,
@@ -1,5 +1,7 @@
package com.hippo.ehviewer.ui.main
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
@@ -11,6 +13,7 @@ object AdvanceTable {
const val SFT = 0x10
}
@Parcelize
@Serializable
data class AdvancedSearchOption(
@Transient
@@ -18,4 +21,4 @@ data class AdvancedSearchOption(
val minRating: Int = 0,
val fromPage: Int = 0,
val toPage: Int = 0,
)
) : Parcelable
@@ -1,6 +1,8 @@
package com.hippo.ehviewer.ui.reader
import android.content.Context
import android.net.Uri
import android.os.Parcelable
import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.background
@@ -81,6 +83,7 @@ import com.hippo.ehviewer.ui.tools.dialog
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.displayString
import com.hippo.ehviewer.util.hasAds
import com.hippo.files.toOkioPath
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
@@ -97,19 +100,17 @@ import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.serialization.Serializable
import kotlinx.parcelize.Parcelize
import moe.tarsin.kt.unreachable
import moe.tarsin.launch
import moe.tarsin.string
import okio.Path.Companion.toPath
@Serializable
sealed interface ReaderScreenArgs {
@Serializable
sealed interface ReaderScreenArgs : Parcelable {
@Parcelize
data class Gallery(val info: BaseGalleryInfo, val page: Int) : ReaderScreenArgs
@Serializable
data class Archive(val path: String) : ReaderScreenArgs
@Parcelize
data class Archive(val uri: Uri) : ReaderScreenArgs
}
@Composable
@@ -381,7 +382,7 @@ suspend inline fun <T> usePageLoader(args: ReaderScreenArgs, crossinline block:
}
}
is ReaderScreenArgs.Archive -> useArchivePageLoader(
args.path.toPath(),
args.uri.toOkioPath(),
passwdProvider = { invalidator ->
awaitInputText(
title = string(R.string.archive_need_passwd),
@@ -1,17 +1,18 @@
package com.hippo.ehviewer.ui.screen
import android.os.Parcelable
import com.hippo.ehviewer.dao.DownloadInfo
import com.hippo.ehviewer.download.DownloadsFilterMode
import com.hippo.ehviewer.util.containsIgnoreCase
import kotlinx.serialization.Serializable
import kotlinx.parcelize.Parcelize
@Serializable
@Parcelize
data class DownloadsFilterState(
val mode: DownloadsFilterMode,
val label: String?,
val state: Int = -1,
val keyword: String = "",
)
) : Parcelable
fun DownloadsFilterState.take(info: DownloadInfo) = mode.take(info, label) &&
(state == -1 || info.state == state) &&
@@ -1,6 +1,8 @@
package com.hippo.ehviewer.ui.screen
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.view.ViewConfiguration
import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.Crossfade
@@ -77,6 +79,7 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import arrow.core.partially1
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.R
@@ -118,7 +121,6 @@ import com.hippo.ehviewer.ui.tools.awaitSelectItemWithCheckBox
import com.hippo.ehviewer.ui.tools.awaitSingleChoice
import com.hippo.ehviewer.ui.tools.rememberHapticFeedback
import com.hippo.ehviewer.ui.tools.rememberInVM
import com.hippo.ehviewer.ui.tools.rememberSerializable
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.mapToLongArray
import com.hippo.ehviewer.util.takeAndClear
@@ -143,7 +145,7 @@ fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) =
var gridView by Settings.gridView.asMutableState()
var sortMode by Settings.downloadSortMode.asMutableState()
val filterMode by Settings.downloadFilterMode.collectAsState { DownloadsFilterMode.from(it) }
var filterState by rememberSerializable { mutableStateOf(DownloadsFilterState(filterMode, Settings.recentDownloadLabel.value)) }
var filterState by rememberSaveable { mutableStateOf(DownloadsFilterState(filterMode, Settings.recentDownloadLabel.value)) }
var invalidateKey by rememberSaveable { mutableStateOf(false) }
var searchBarExpanded by rememberSaveable { mutableStateOf(false) }
var searchBarOffsetY by remember { mutableIntStateOf(0) }
@@ -481,7 +483,9 @@ fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) =
text = { Text(text = stringResource(id = R.string.download_start_all)) },
onClick = {
expanded = false
DownloadService.startService(DownloadService.ACTION_START_ALL)
val intent = Intent(contextOf<Activity>(), DownloadService::class.java)
intent.action = DownloadService.ACTION_START_ALL
ContextCompat.startForegroundService(contextOf<Activity>(), intent)
},
)
DropdownMenuItem(
@@ -513,7 +517,10 @@ fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) =
onClick = {
expanded = false
val gidList = list.filter { it.state != DownloadInfo.STATE_FINISH }.asReversed().mapToLongArray(DownloadInfo::gid)
DownloadService.startRangeDownload(gidList)
val intent = Intent(contextOf<Activity>(), DownloadService::class.java)
intent.action = DownloadService.ACTION_START_RANGE
intent.putExtra(DownloadService.KEY_GID_LIST, gidList)
ContextCompat.startForegroundService(contextOf<Activity>(), intent)
},
)
}
@@ -595,7 +602,10 @@ fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) =
checkedInfoMap[info.gid] = info
},
onStart = {
DownloadService.startDownload(info.galleryInfo)
val intent = Intent(contextOf<Activity>(), DownloadService::class.java)
intent.action = DownloadService.ACTION_START
intent.putExtra(DownloadService.KEY_GALLERY_INFO, info.galleryInfo)
ContextCompat.startForegroundService(contextOf<Activity>(), intent)
},
onStop = { launchIO { DownloadManager.stopDownload(info.gid) } },
info = info,
@@ -686,7 +696,10 @@ fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) =
}
onClick(Icons.Default.PlayArrow) {
val gidList = checkedInfoMap.takeAndClear().mapToLongArray(DownloadInfo::gid)
DownloadService.startRangeDownload(gidList)
val intent = Intent(contextOf<Activity>(), DownloadService::class.java)
intent.action = DownloadService.ACTION_START_RANGE
intent.putExtra(DownloadService.KEY_GID_LIST, gidList)
ContextCompat.startForegroundService(contextOf<Context>(), intent)
}
onClick(Icons.Default.Pause) {
val gidList = checkedInfoMap.takeAndClear().mapToLongArray(DownloadInfo::gid)
@@ -85,7 +85,6 @@ import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.awaitSelectItem
import com.hippo.ehviewer.ui.tools.foldToLoadResult
import com.hippo.ehviewer.ui.tools.rememberInVM
import com.hippo.ehviewer.ui.tools.rememberSerializable
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.mapToLongArray
import com.hippo.ehviewer.util.takeAndClear
@@ -113,7 +112,7 @@ fun AnimatedVisibilityScope.FavouritesScreen(navigator: DestinationsNavigator) =
val hasSignedIn by Settings.hasSignedIn.collectAsState()
// Meta State
var urlBuilder by rememberSerializable { mutableStateOf(FavListUrlBuilder(favCat = Settings.recentFavCat)) }
var urlBuilder by rememberSaveable { mutableStateOf(FavListUrlBuilder(favCat = Settings.recentFavCat)) }
var searchBarExpanded by rememberSaveable { mutableStateOf(false) }
var searchBarOffsetY by remember { mutableIntStateOf(0) }
@@ -186,7 +186,7 @@ fun AnimatedVisibilityScope.GalleryCommentsScreen(gid: Long, navigator: Destinat
val userCommentBackField = remember { mutableStateOf(TextFieldValue()) }
var userComment by userCommentBackField
var commentId by remember { mutableLongStateOf(-1) }
var comments by remember(galleryDetail) { mutableStateOf(galleryDetail.comments) }
var comments by rememberSaveable { mutableStateOf(galleryDetail.comments) }
LaunchedEffect(comments) {
galleryDetail.comments = comments
}
@@ -1,5 +1,6 @@
package com.hippo.ehviewer.ui.screen
import android.os.Parcelable
import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
import androidx.collection.SieveCache
import androidx.compose.animation.AnimatedVisibilityScope
@@ -74,7 +75,7 @@ import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.serialization.Serializable
import kotlinx.parcelize.Parcelize
import moe.tarsin.coroutines.runSuspendCatching
import moe.tarsin.launchIO
import moe.tarsin.snackbar
@@ -84,15 +85,14 @@ typealias VoteTag = suspend GalleryDetail.(String, Int) -> Unit
val detailCache = SieveCache<Long, GalleryDetail>(25)
@Serializable
sealed interface GalleryDetailScreenArgs
sealed interface GalleryDetailScreenArgs : Parcelable
@Serializable
@Parcelize
data class GalleryInfoArgs(
val galleryInfo: BaseGalleryInfo,
) : GalleryDetailScreenArgs
@Serializable
@Parcelize
data class TokenArgs(
val gid: Long,
val token: String,
@@ -121,7 +121,6 @@ import com.hippo.ehviewer.ui.tools.foldToLoadResult
import com.hippo.ehviewer.ui.tools.rememberHapticFeedback
import com.hippo.ehviewer.ui.tools.rememberInVM
import com.hippo.ehviewer.ui.tools.rememberMutableStateInDataStore
import com.hippo.ehviewer.ui.tools.rememberSerializable
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.FavouriteStatusRouter
import com.ramcosta.composedestinations.annotation.Destination
@@ -163,7 +162,7 @@ fun AnimatedVisibilityScope.ToplistScreen(navigator: DestinationsNavigator) = Ga
@Composable
fun AnimatedVisibilityScope.GalleryListScreen(lub: ListUrlBuilder, navigator: DestinationsNavigator) = Screen(navigator) {
val searchFieldState = rememberTextFieldState()
var urlBuilder by rememberSerializable { mutableStateOf(lub) }
var urlBuilder by rememberSaveable { mutableStateOf(lub) }
var searchBarExpanded by rememberSaveable { mutableStateOf(false) }
var searchBarOffsetY by remember { mutableIntStateOf(0) }
val animateItems by Settings.animateItems.collectAsState()
@@ -5,12 +5,8 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.savedstate.serialization.SavedStateConfiguration
import kotlin.reflect.KMutableProperty0
import kotlinx.serialization.KSerializer
import kotlinx.serialization.serializer
val <T> KMutableProperty0<T>.observed: MutableState<T>
@Composable
@@ -33,11 +29,3 @@ val <T> MutableState<T>.rememberedAccessor: KMutableProperty0<T>
var value by this@rememberedAccessor
}::value
}
@Composable
inline fun <reified T : Any> rememberSerializable(
vararg inputs: Any?,
stateSerializer: KSerializer<T> = serializer<T>(),
configuration: SavedStateConfiguration = SavedStateConfiguration.DEFAULT,
noinline init: () -> MutableState<T>,
) = rememberSaveable(inputs = inputs, stateSerializer, configuration, init)
+1
View File
@@ -2,6 +2,7 @@ plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
alias(libs.plugins.kotlin.parcelize) apply false
alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.spotless) apply false
+1
View File
@@ -136,6 +136,7 @@ android-application = { id = "com.android.application", version.ref = "agp" }
composeCompilerReportGenerator = { id = "dev.shreyaspatil.compose-compiler-report-generator", version = "1.4.2" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
spotless = { id = "com.diffplug.spotless", version = "7.0.3" }