Compare commits

..
25 Commits
Author SHA1 Message Date
FooIbar e51d54e346 Prepare changelog for 1.14.3
Releases / build (push) Has been cancelled
2025-09-01 20:42:02 +08:00
renovate[bot] e06b1f0177 Lock file maintenance (#2586)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-01 12:25:48 +00:00
renovate[bot] 178a870608 Update kotlin monorepo to v2.2.20-RC2 (#2585)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-01 12:23:11 +00:00
FooIbar a7d3d7c651 Prepare changelog for 1.14.3 2025-09-01 20:13:28 +08:00
renovate[bot] c13024f1c7 Update AGP to v8.12.2 (#2583)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-30 16:14:02 +00:00
FooIbar c53c0ef727 Fix similar galleries by artist tag 2025-08-31 00:02:06 +08:00
FooIbar cd93fe2646 Revert "Work around crash when dismissing filter settings"
This reverts commit afe638fb90.
2025-08-28 11:12:21 +08:00
renovate[bot] 7b506058a4 Update dependency androidx.compose:compose-bom-alpha to v2025.08.01 (#2580)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-28 00:52:26 +00:00
renovate[bot] f658f74f35 Update androidx.lifecycle to v2.10.0-alpha03 (#2578)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-27 20:41:58 +00:00
renovate[bot] eae5efa69d Update dependency androidx.activity:activity-compose to v1.12.0-alpha07 (#2579)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-27 20:41:22 +00:00
FooIbar 4e6051085e Simplify repository content filtering 2025-08-26 20:01:02 +08:00
FooIbar f174ccfc04 Migrate to the new context menu APIs 2025-08-26 10:02:21 +08:00
FooIbar e1252d0554 Support searching download labels with label: 2025-08-25 21:58:18 +08:00
FooIbar afe638fb90 Work around crash when dismissing filter settings 2025-08-25 18:12:39 +08:00
renovate[bot] 17699ce889 Lock file maintenance (#2572)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-25 01:58:40 +00:00
renovate[bot] 4afa06b7b9 Update actions/setup-java action to v5 (#2568)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-21 06:39:56 +00:00
FooIbar 2d02815aba Extract common UI components part 1/n 2025-08-20 14:45:18 +08:00
renovate[bot] ae1824c6a2 Update dependency com.google.devtools.ksp to v2.2.20-RC-2.0.2 (#2567)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-20 03:40:50 +00:00
renovate[bot] d63cc39478 Update kotlin monorepo to v2.2.20-RC (#2565)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-19 08:38:25 +00:00
FooIbar 51d6775429 Remove unnecessary JNI lib and main thread check
The actual disk I/O will perform in the scope of DataStore.
2025-08-19 12:07:34 +08:00
renovate[bot] 35d92f1386 Update dependency sh.calvin.reorderable:reorderable to v3 (#2562)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 22:27:32 +00:00
renovate[bot] ba0ef6dccc Update AGP to v8.12.1 (#2561)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 17:34:26 +00:00
renovate[bot] 2a325e6700 Lock file maintenance (#2559)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 01:05:47 +00:00
FooIbar 4e7566f06d Fix aboutlibraries.json being out-of-date 2025-08-17 17:06:35 +08:00
FooIbar d95bf4b71d Prepare for next iteration 2025-08-16 22:24:23 +08:00
127 changed files with 647 additions and 666 deletions

No files matched your search

+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
uses: actions/checkout@v5
- name: Setup Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
+11 -3
View File
@@ -15,7 +15,7 @@ jobs:
uses: actions/checkout@v5
- name: Setup Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
@@ -58,7 +58,7 @@ jobs:
uses: actions/checkout@v5
- name: Setup Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
@@ -85,6 +85,10 @@ jobs:
key: cmake-default-${{ hashFiles('rust-toolchain.toml', 'settings.gradle.kts', 'app/src/main/cpp/CMakeLists.txt', 'app/src/main/rust/Cargo.lock') }}
restore-keys: cmake-default-
# https://github.com/mikepenz/AboutLibraries/issues/1225
- name: Generate aboutlibraries.json
run: ./gradlew :app:prepareLibraryDefinitionsDefaultRelease --rerun
- name: Build
run: ./gradlew assembleDefaultRelease
@@ -126,7 +130,7 @@ jobs:
uses: actions/checkout@v5
- name: Setup Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
@@ -153,6 +157,10 @@ jobs:
key: cmake-marshmallow-${{ hashFiles('rust-toolchain.toml', 'settings.gradle.kts', 'app/src/main/cpp/CMakeLists.txt', 'app/src/main/rust/Cargo.lock') }}
restore-keys: cmake-marshmallow-
# https://github.com/mikepenz/AboutLibraries/issues/1225
- name: Generate aboutlibraries.json
run: ./gradlew :app:prepareLibraryDefinitionsMarshmallowRelease --rerun
- name: Build
run: ./gradlew assembleMarshmallowRelease
+7 -1
View File
@@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@v5
- name: Setup Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
@@ -51,6 +51,12 @@ jobs:
run: ./gradlew generateBaselineProfile
-Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
# https://github.com/mikepenz/AboutLibraries/issues/1225
- name: Generate aboutlibraries.json
run: ./gradlew
:app:prepareLibraryDefinitionsDefaultRelease --rerun
:app:prepareLibraryDefinitionsMarshmallowRelease --rerun
- name: Build
run: ./gradlew assembleRelease
+12
View File
@@ -1,5 +1,17 @@
# 变更日志
## [1.14.3] - 2025-09-01
### 新功能
* 支持以 label: 语法搜索下载标签
### Bug 修复
* [阅读器] 关闭滤镜设置时崩溃 [#2573](https://github.com/FooIbar/EhViewer/issues/2573)
* 某些情况下搜索相似画廊时出错
## [1.14.2] - 2025-08-16
### 改进
+5 -1
View File
@@ -56,7 +56,7 @@ android {
defaultConfig {
applicationId = "moe.tarsin.ehviewer"
versionCode = 180063
versionName = "1.14.2"
versionName = "1.14.3"
// versionNameSuffix = "-SNAPSHOT"
buildConfigField("String", "RAW_VERSION_NAME", "\"$versionName${versionNameSuffix.orEmpty()}\"")
buildConfigField("String", "COMMIT_SHA", "\"$commitSha\"")
@@ -97,6 +97,9 @@ android {
dex {
useLegacyPackaging = false
}
jniLibs {
excludes += "**/libdatastore_shared_counter.so" // DataStore multi-process
}
resources {
// Required by Layout Inspector
pickFirsts += "/META-INF/androidx.compose.ui_ui.version"
@@ -168,6 +171,7 @@ baselineProfile {
dependencies {
implementation(projects.core.data)
implementation(projects.core.i18n)
implementation(projects.core.ui)
// https://developer.android.com/jetpack/androidx/releases/activity
implementation(libs.androidx.activity.compose)
@@ -37,6 +37,10 @@ import coil3.request.allowRgb565
import coil3.request.crossfade
import coil3.serviceLoaderEnabled
import coil3.util.DebugLogger
import com.ehviewer.core.ui.util.initSETConnection
import com.ehviewer.core.util.launchIO
import com.ehviewer.core.util.launchUI
import com.ehviewer.core.util.withUIContext
import com.hippo.ehviewer.client.EhTagDatabase
import com.hippo.ehviewer.coil.AnimatedWebPDecoder
import com.hippo.ehviewer.coil.CropBorderInterceptor
@@ -59,7 +63,6 @@ import com.hippo.ehviewer.ui.keepNoMediaFileStatus
import com.hippo.ehviewer.ui.lockObserver
import com.hippo.ehviewer.ui.screen.detailCache
import com.hippo.ehviewer.ui.tools.dataStateFlow
import com.hippo.ehviewer.ui.tools.initSETConnection
import com.hippo.ehviewer.util.AppConfig
import com.hippo.ehviewer.util.CrashHandler
import com.hippo.ehviewer.util.FavouriteStatusRouter
@@ -70,9 +73,6 @@ import com.hippo.ehviewer.util.isAtLeastP
import com.hippo.ehviewer.util.isAtLeastS
import com.hippo.ehviewer.util.isAtLeastSExtension7
import com.hippo.files.deleteContent
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.system.logcat
import io.ktor.client.HttpClient
import io.ktor.client.engine.okhttp.OkHttp
@@ -146,6 +146,8 @@ object EhDB {
dao.fill(raw.position)
}
suspend fun searchDownloadLabel(keyword: String, limit: Int) = db.downloadLabelDao().search("%$keyword%", limit)
suspend fun putDownloadArtist(gid: Long, artists: List<DownloadArtist>) {
if (artists.isNotEmpty()) {
val dao = db.downloadArtistDao()
@@ -4,12 +4,12 @@ import android.app.UiModeManager
import androidx.appcompat.app.AppCompatDelegate
import arrow.core.Either.Companion.catch
import com.ehviewer.core.preferences.PrefDelegate
import com.ehviewer.core.util.withIOContext
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhTagDatabase
import com.hippo.ehviewer.dailycheck.updateDailyCheckWork
import com.hippo.ehviewer.ui.keepNoMediaFileStatus
import com.hippo.ehviewer.util.isAtLeastS
import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -27,6 +27,7 @@ import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.Color
import androidx.core.net.toUri
import arrow.core.memoize
import com.ehviewer.core.util.withUIContext
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.data.GalleryDetail
import com.hippo.ehviewer.client.data.GalleryInfo
@@ -38,7 +39,6 @@ import com.hippo.ehviewer.util.addTextToClipboard
import com.materialkolor.hct.Hct
import com.materialkolor.ktx.from
import com.materialkolor.ktx.toColor
import eu.kanade.tachiyomi.util.lang.withUIContext
import splitties.systemservices.downloadManager
object EhUtils {
@@ -19,10 +19,10 @@ import androidx.work.PeriodicWorkRequest
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import com.ehviewer.core.util.withIOContext
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat
import java.time.Duration
import java.util.concurrent.TimeUnit
@@ -14,6 +14,9 @@ interface DownloadLabelDao {
@Query("SELECT * FROM DOWNLOAD_LABELS ORDER BY POSITION LIMIT :limit OFFSET :offset")
suspend fun list(offset: Int, limit: Int): List<DownloadLabel>
@Query("SELECT LABEL FROM DOWNLOAD_LABELS WHERE LABEL LIKE :pattern ORDER BY POSITION LIMIT :limit")
suspend fun search(pattern: String, limit: Int): List<String>
@Query("UPDATE DOWNLOAD_LABELS SET POSITION = POSITION - 1 WHERE POSITION > :position")
suspend fun fill(position: Int)
@@ -32,6 +32,7 @@ import androidx.core.content.ContextCompat
import androidx.savedstate.serialization.decodeFromSavedState
import androidx.savedstate.serialization.encodeToSavedState
import com.ehviewer.core.i18n.R
import com.ehviewer.core.util.unsafeLazy
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.dao.DownloadInfo
@@ -39,7 +40,6 @@ import com.hippo.ehviewer.ui.MainActivity
import com.hippo.ehviewer.util.FileUtils
import com.hippo.ehviewer.util.ReadableTime
import com.hippo.ehviewer.util.isAtLeastS
import com.hippo.ehviewer.util.unsafeLazy
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -4,6 +4,7 @@ import androidx.collection.SieveCache
import androidx.collection.mutableIntObjectMapOf
import arrow.fx.coroutines.ExitCase
import arrow.fx.coroutines.bracketCase
import com.ehviewer.core.util.withNonCancellableContext
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.image.Image
@@ -13,7 +14,6 @@ import com.hippo.ehviewer.util.OSUtils
import com.hippo.ehviewer.util.detectAds
import com.hippo.ehviewer.util.displayString
import com.hippo.ehviewer.util.isAtLeastO
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.atomics.AtomicInt
import kotlin.concurrent.read
@@ -36,6 +36,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.LabeledCheckbox
import com.ehviewer.core.util.withIOContext
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
@@ -54,7 +56,6 @@ import com.hippo.ehviewer.download.tempDownloadDir
import com.hippo.ehviewer.ui.destinations.ReaderScreenDestination
import com.hippo.ehviewer.ui.reader.ReaderScreenArgs
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.LabeledCheckbox
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.awaitResult
import com.hippo.ehviewer.ui.tools.awaitSelectDate
@@ -75,7 +76,6 @@ import com.hippo.files.exists
import com.hippo.files.isDirectory
import com.hippo.files.write
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.lang.withIOContext
import kotlin.time.Clock
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
@@ -10,11 +10,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import com.ehviewer.core.ui.util.NoopTransitionsVisibilityScope
import com.ehviewer.core.ui.util.TransitionsVisibilityScope
import com.ehviewer.core.ui.util.togetherWith
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.LocalGlobalDialogState
import com.hippo.ehviewer.ui.tools.NoopTransitionsVisibilityScope
import com.hippo.ehviewer.ui.tools.TransitionsVisibilityScope
import com.hippo.ehviewer.ui.tools.togetherWith
import com.hippo.ehviewer.util.findActivity
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.CoroutineScope
@@ -70,7 +70,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.currentCompositeKeyHashCode
@@ -97,7 +96,6 @@ import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.lerp
import androidx.core.net.toUri
@@ -105,6 +103,14 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.compose.LifecycleResumeEffect
import androidx.navigation.compose.rememberNavController
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.LabeledCheckbox
import com.ehviewer.core.ui.component.LocalSideSheetState
import com.ehviewer.core.ui.component.MutableSideSheet
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.filled.Subscriptions
import com.ehviewer.core.ui.util.LocalSnackBarFabPadding
import com.ehviewer.core.ui.util.LocalWindowSizeClass
import com.ehviewer.core.util.withIOContext
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.data.ListUrlBuilder
import com.hippo.ehviewer.client.parser.GalleryDetailUrlParser
@@ -112,8 +118,6 @@ import com.hippo.ehviewer.client.parser.GalleryPageUrlParser
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.download.DownloadService
import com.hippo.ehviewer.download.downloadLocation
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.filled.Subscriptions
import com.hippo.ehviewer.ui.destinations.DownloadScreenDestination
import com.hippo.ehviewer.ui.destinations.DownloadsScreenDestination
import com.hippo.ehviewer.ui.destinations.FavouritesScreenDestination
@@ -130,8 +134,6 @@ import com.hippo.ehviewer.ui.screen.asDstWith
import com.hippo.ehviewer.ui.screen.navWithUrl
import com.hippo.ehviewer.ui.settings.showNewVersion
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.LabeledCheckbox
import com.hippo.ehviewer.ui.tools.LocalWindowSizeClass
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.awaitInputText
import com.hippo.ehviewer.updater.AppUpdater
@@ -150,7 +152,6 @@ import com.ramcosta.composedestinations.DestinationsNavHost
import com.ramcosta.composedestinations.spec.Direction
import com.ramcosta.composedestinations.utils.currentDestinationAsState
import com.ramcosta.composedestinations.utils.rememberDestinationsNavigator
import eu.kanade.tachiyomi.util.lang.withIOContext
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
@@ -532,7 +533,6 @@ val LocalNavDrawerState = compositionLocalOf<DrawerState> { error("CompositionLo
val LocalDrawerHandle = compositionLocalOf<SnapshotStateList<Long>> { error("CompositionLocal LocalDrawerHandle not present!") }
val LocalSnackBarHostState = compositionLocalOf<SnackbarHostState> { error("CompositionLocal LocalSnackBarHostState not present!") }
val LocalSnackBarFabPadding = compositionLocalOf<State<Dp>> { error("CompositionLocal LocalSnackBarFabPadding not present!") }
val LocalSharedTransitionScope = compositionLocalOf<SharedTransitionScope> { error("CompositionLocal LocalSharedTransitionScope not present!") }
@Composable
@@ -59,6 +59,11 @@ import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.util.LocalWindowSizeClass
import com.ehviewer.core.ui.util.isExpanded
import com.ehviewer.core.ui.util.thenIf
import com.ehviewer.core.util.launchIO
import com.ehviewer.core.util.withUIContext
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhUrl
@@ -66,18 +71,13 @@ import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.destinations.WebViewSignInScreenDestination
import com.hippo.ehviewer.ui.openBrowser
import com.hippo.ehviewer.ui.tools.LocalWindowSizeClass
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.isExpanded
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.displayString
import com.jamal.composeprefs3.ui.ifTrueThen
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.lang.withUIContext
import kotlinx.coroutines.Job
import moe.tarsin.launchIO
import moe.tarsin.navigate
@Destination<RootGraph>(start = true)
@@ -44,6 +44,10 @@ import arrow.core.some
import coil3.compose.AsyncImage
import coil3.network.HttpException
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.RollingNumber
import com.ehviewer.core.ui.component.RollingNumberPlaceholder
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.launchIO
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhUtils
@@ -65,8 +69,6 @@ import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import moe.tarsin.coroutines.runSwallowingWithUI
import moe.tarsin.launch
import moe.tarsin.launchIO
private val limitScope = CoroutineScope(Dispatchers.IO)
private val refreshEvent = MutableSharedFlow<Unit>()
@@ -40,14 +40,14 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.CrystalCard
import com.ehviewer.core.ui.util.TransitionsVisibilityScope
import com.ehviewer.core.ui.util.listThumbGenerator
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.dao.DownloadInfo
import com.hippo.ehviewer.download.DownloadManager
import com.hippo.ehviewer.ui.tools.CrystalCard
import com.hippo.ehviewer.ui.tools.GalleryListCardRating
import com.hippo.ehviewer.ui.tools.TransitionsVisibilityScope
import com.hippo.ehviewer.ui.tools.listThumbGenerator
import com.hippo.ehviewer.util.FileUtils
@Composable
@@ -18,13 +18,13 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import coil3.compose.AsyncImagePainter
import coil3.compose.rememberAsyncImagePainter
import com.ehviewer.core.ui.util.SETNodeGenerator
import com.ehviewer.core.ui.util.SharedElementBox
import com.ehviewer.core.ui.util.TransitionsVisibilityScope
import com.ehviewer.core.ui.util.thenIf
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.ktbuilder.imageRequest
import com.hippo.ehviewer.ui.tools.SETNodeGenerator
import com.hippo.ehviewer.ui.tools.SharedElementBox
import com.hippo.ehviewer.ui.tools.TransitionsVisibilityScope
import com.hippo.ehviewer.ui.tools.shouldCrop
import com.hippo.ehviewer.ui.tools.thenIf
@Composable
@NonRestartableComposable
@@ -11,6 +11,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import com.ehviewer.core.ui.component.RollingNumber
@Composable
fun FundsItem(
@@ -33,13 +33,13 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.big.SadAndroid
import com.ehviewer.core.ui.util.TransitionsVisibilityScope
import com.ehviewer.core.ui.util.detailThumbGenerator
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.client.data.GalleryDetail
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.big.SadAndroid
import com.hippo.ehviewer.ui.tools.TransitionsVisibilityScope
import com.hippo.ehviewer.ui.tools.detailThumbGenerator
@Composable
fun GalleryDetailHeaderInfoCard(
@@ -38,17 +38,17 @@ import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import com.ehviewer.core.ui.component.CrystalCard
import com.ehviewer.core.ui.component.ElevatedCard
import com.ehviewer.core.ui.util.SharedElementBox
import com.ehviewer.core.ui.util.TransitionsVisibilityScope
import com.ehviewer.core.ui.util.listThumbGenerator
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.NOT_FAVORITED
import com.hippo.ehviewer.download.DownloadManager
import com.hippo.ehviewer.ui.tools.CrystalCard
import com.hippo.ehviewer.ui.tools.ElevatedCard
import com.hippo.ehviewer.ui.tools.GalleryListCardRating
import com.hippo.ehviewer.ui.tools.SharedElementBox
import com.hippo.ehviewer.ui.tools.TransitionsVisibilityScope
import com.hippo.ehviewer.ui.tools.listThumbGenerator
import com.hippo.ehviewer.util.FavouriteStatusRouter
@Composable
@@ -52,22 +52,22 @@ import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.itemContentType
import androidx.paging.compose.itemKey
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.FastScrollLazyVerticalGrid
import com.ehviewer.core.ui.component.FastScrollLazyVerticalStaggeredGrid
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.big.SadAndroid
import com.ehviewer.core.util.launch
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.exception.NoHitsFoundException
import com.hippo.ehviewer.coil.PrefetchAround
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.big.SadAndroid
import com.hippo.ehviewer.ktbuilder.imageRequest
import com.hippo.ehviewer.ui.screen.collectDetailSizeAsState
import com.hippo.ehviewer.ui.tools.FastScrollLazyVerticalGrid
import com.hippo.ehviewer.ui.tools.FastScrollLazyVerticalStaggeredGrid
import com.hippo.ehviewer.util.displayString
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.first
import moe.tarsin.launch
@Stable
operator fun PaddingValues.plus(r: PaddingValues) = object : PaddingValues {
@@ -23,10 +23,10 @@ import androidx.compose.ui.unit.IntSize
import coil3.BitmapImage
import coil3.compose.AsyncImagePainter.State
import coil3.compose.rememberAsyncImagePainter
import com.ehviewer.core.ui.component.CrystalCard
import com.hippo.ehviewer.client.data.GalleryPreview
import com.hippo.ehviewer.client.data.V2GalleryPreview
import com.hippo.ehviewer.ktbuilder.imageRequest
import com.hippo.ehviewer.ui.tools.CrystalCard
import com.hippo.ehviewer.ui.tools.shouldCrop
@Composable
@@ -34,18 +34,18 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import arrow.core.raise.ensure
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.DropdownFilterChip
import com.ehviewer.core.ui.util.thenIf
import com.ehviewer.core.util.launch
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhTagDatabase
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.S_LANG_TAGS
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.DropdownFilterChip
import com.hippo.ehviewer.ui.tools.awaitResult
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.toIntOrDefault
import kotlinx.coroutines.CoroutineScope
import moe.tarsin.launch
private val categoryTable = arrayOf(
EhUtils.DOUJINSHI to R.string.doujinshi,
@@ -22,9 +22,9 @@ import androidx.core.graphics.blue
import androidx.core.graphics.green
import androidx.core.graphics.red
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.RollingNumber
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.asMutableState
import com.hippo.ehviewer.ui.main.RollingNumber
@Composable
fun ColorFilterSetting() = Column(modifier = Modifier.verticalScroll(rememberScrollState()).navigationBarsPadding()) {
@@ -38,6 +38,7 @@ import coil3.compose.AsyncImagePainter
import coil3.compose.SubcomposeAsyncImage
import coil3.compose.SubcomposeAsyncImageContent
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.util.thenIf
import com.google.accompanist.drawablepainter.DrawablePainter
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.collectAsState
@@ -47,7 +48,6 @@ import com.hippo.ehviewer.gallery.PageStatus
import com.hippo.ehviewer.gallery.progressObserved
import com.hippo.ehviewer.gallery.statusObserved
import com.hippo.ehviewer.image.Image
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.AdsPlaceholderFile
import eu.kanade.tachiyomi.ui.reader.viewer.CombinedCircularProgressIndicator
import kotlinx.coroutines.awaitCancellation
@@ -60,6 +60,11 @@ import arrow.core.Either.Companion.catch
import arrow.core.raise.ensure
import arrow.core.right
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.util.Await
import com.ehviewer.core.ui.util.asyncInVM
import com.ehviewer.core.ui.util.thenIf
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.launchIO
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
@@ -78,12 +83,9 @@ import com.hippo.ehviewer.ui.MainActivity
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.theme.EhTheme
import com.hippo.ehviewer.ui.theme.scrim
import com.hippo.ehviewer.ui.tools.Await
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.asyncInVM
import com.hippo.ehviewer.ui.tools.awaitInputText
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.ramcosta.composedestinations.annotation.Destination
@@ -94,7 +96,6 @@ import eu.kanade.tachiyomi.ui.reader.ReaderAppBars
import eu.kanade.tachiyomi.ui.reader.ReaderContentOverlay
import eu.kanade.tachiyomi.ui.reader.ReaderPageSheetMeta
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import eu.kanade.tachiyomi.util.lang.launchIO
import kotlin.coroutines.resume
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.awaitCancellation
@@ -104,7 +105,6 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.serialization.Serializable
import moe.tarsin.kt.unreachable
import moe.tarsin.launch
import moe.tarsin.string
import okio.Path.Companion.toPath
@@ -25,7 +25,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.hippo.ehviewer.ui.tools.Slider
import com.ehviewer.core.ui.component.Slider
@Composable
fun SpinnerChoice(title: String, entries: Array<String>, values: Array<String>, field: MutableState<Int>) {
@@ -23,6 +23,8 @@ import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEnd
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.DriveFileMove
import androidx.compose.material.icons.automirrored.filled.Sort
@@ -81,6 +83,23 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import arrow.core.partially1
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.FAB_ANIMATE_TIME
import com.ehviewer.core.ui.component.FabLayout
import com.ehviewer.core.ui.component.FastScrollLazyColumn
import com.ehviewer.core.ui.component.FastScrollLazyVerticalStaggeredGrid
import com.ehviewer.core.ui.component.LocalSideSheetState
import com.ehviewer.core.ui.component.ProvideSideSheetContent
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.big.Download
import com.ehviewer.core.ui.util.Await
import com.ehviewer.core.ui.util.asyncState
import com.ehviewer.core.ui.util.rememberInVM
import com.ehviewer.core.ui.util.thenIf
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.launchIO
import com.ehviewer.core.util.onEachLatest
import com.ehviewer.core.util.withNonCancellableContext
import com.ehviewer.core.util.withUIContext
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.asMutableState
@@ -93,47 +112,30 @@ import com.hippo.ehviewer.download.DownloadManager.downloadInfoList
import com.hippo.ehviewer.download.DownloadService
import com.hippo.ehviewer.download.DownloadsFilterMode
import com.hippo.ehviewer.download.SortMode
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.big.Download
import com.hippo.ehviewer.ui.DrawerHandle
import com.hippo.ehviewer.ui.LocalSideSheetState
import com.hippo.ehviewer.ui.ProvideSideSheetContent
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.confirmRemoveDownloadRange
import com.hippo.ehviewer.ui.main.DownloadCard
import com.hippo.ehviewer.ui.main.FAB_ANIMATE_TIME
import com.hippo.ehviewer.ui.main.FabLayout
import com.hippo.ehviewer.ui.main.GalleryInfoGridItem
import com.hippo.ehviewer.ui.main.plus
import com.hippo.ehviewer.ui.navToReader
import com.hippo.ehviewer.ui.showMoveDownloadLabelList
import com.hippo.ehviewer.ui.tools.Await
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.FastScrollLazyColumn
import com.hippo.ehviewer.ui.tools.FastScrollLazyVerticalStaggeredGrid
import com.hippo.ehviewer.ui.tools.HapticFeedbackType
import com.hippo.ehviewer.ui.tools.asyncState
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.awaitInputText
import com.hippo.ehviewer.ui.tools.awaitSelectAction
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.thenIf
import com.hippo.ehviewer.util.mapToLongArray
import com.hippo.ehviewer.util.takeAndClear
import com.jamal.composeprefs3.ui.ifTrueThen
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
import eu.kanade.tachiyomi.util.lang.withUIContext
import kotlin.math.roundToInt
import kotlinx.coroutines.delay
import moe.tarsin.coroutines.onEachLatest
import moe.tarsin.launch
import moe.tarsin.launchIO
import moe.tarsin.navigate
import sh.calvin.reorderable.ReorderableItem
import sh.calvin.reorderable.rememberReorderableLazyListState
@@ -451,6 +453,15 @@ fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) =
}
}
val searchFieldState = rememberTextFieldState()
class DownloadLabelSuggestion(private val label: String) : Suggestion() {
override val keyword = LABEL_PREFIX + label
override fun onClick() {
searchFieldState.setTextAndPlaceCursorAtEnd(keyword)
searchBarExpanded = false
switchLabel(label)
}
}
SearchBarScreen(
onApplySearch = { filterState = filterState.copy(keyword = it) },
expanded = searchBarExpanded,
@@ -461,6 +472,15 @@ fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) =
},
title = title,
searchFieldHint = hint,
searchFieldState = searchFieldState,
suggestionProvider = { query ->
val label = query.substringAfter(LABEL_PREFIX, "")
if (label.isEmpty()) {
emptyList()
} else {
EhDB.searchDownloadLabel(label, 10).map(::DownloadLabelSuggestion)
}
},
searchBarOffsetY = { searchBarOffsetY },
trailingIcon = {
var expanded by remember { mutableStateOf(false) }
@@ -712,3 +732,5 @@ fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) =
}
}
}
private const val LABEL_PREFIX = "label:"
@@ -54,41 +54,41 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.paging.compose.collectAsLazyPagingItems
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.FAB_ANIMATE_TIME
import com.ehviewer.core.ui.component.FabLayout
import com.ehviewer.core.ui.component.LocalSideSheetState
import com.ehviewer.core.ui.component.ProvideSideSheetContent
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.filled.GoTo
import com.ehviewer.core.ui.util.asyncState
import com.ehviewer.core.ui.util.thenIf
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.onEachLatest
import com.ehviewer.core.util.withUIContext
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.FavListUrlBuilder
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.filled.GoTo
import com.hippo.ehviewer.ui.DrawerHandle
import com.hippo.ehviewer.ui.LocalSideSheetState
import com.hippo.ehviewer.ui.ProvideSideSheetContent
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.awaitSelectDate
import com.hippo.ehviewer.ui.main.AvatarIcon
import com.hippo.ehviewer.ui.main.FAB_ANIMATE_TIME
import com.hippo.ehviewer.ui.main.FabLayout
import com.hippo.ehviewer.ui.main.GalleryInfoGridItem
import com.hippo.ehviewer.ui.main.GalleryInfoListItem
import com.hippo.ehviewer.ui.main.GalleryList
import com.hippo.ehviewer.ui.startDownload
import com.hippo.ehviewer.ui.tools.asyncState
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.awaitSelectItem
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.mapToLongArray
import com.hippo.ehviewer.util.takeAndClear
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.lang.withUIContext
import kotlin.math.roundToInt
import kotlinx.coroutines.delay
import moe.tarsin.coroutines.onEachLatest
import moe.tarsin.coroutines.runSwallowingWithUI
import moe.tarsin.launch
import moe.tarsin.navigate
@Destination<RootGraph>
@@ -14,13 +14,13 @@ import androidx.paging.PagingState
import androidx.paging.cachedIn
import androidx.paging.filter
import androidx.savedstate.compose.serialization.serializers.MutableStateSerializer
import com.ehviewer.core.util.withIOContext
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.FavListUrlBuilder
import com.hippo.ehviewer.ui.tools.foldToLoadResult
import eu.kanade.tachiyomi.util.lang.withIOContext
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import moe.tarsin.coroutines.runSuspendCatching
@@ -51,7 +51,6 @@ import androidx.compose.material3.pulltorefresh.PullToRefreshBox
import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf
@@ -70,7 +69,6 @@ import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalTextToolbar
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
@@ -85,6 +83,12 @@ import androidx.core.text.getSpans
import androidx.core.text.inSpans
import androidx.core.text.parseAsHtml
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.util.animateFloatMergePredictiveBackAsState
import com.ehviewer.core.ui.util.snackBarPadding
import com.ehviewer.core.ui.util.thenIf
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.launchIO
import com.ehviewer.core.util.withUIContext
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhFilter.remember
@@ -99,14 +103,11 @@ import com.hippo.ehviewer.ui.jumpToReaderByPage
import com.hippo.ehviewer.ui.main.GalleryCommentCard
import com.hippo.ehviewer.ui.main.NavigationIcon
import com.hippo.ehviewer.ui.openBrowser
import com.hippo.ehviewer.ui.tools.animateFloatMergePredictiveBackAsState
import com.hippo.ehviewer.ui.tools.addBBCodeTextContextMenuItems
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.awaitSelectAction
import com.hippo.ehviewer.ui.tools.normalizeSpan
import com.hippo.ehviewer.ui.tools.rememberBBCodeTextToolbar
import com.hippo.ehviewer.ui.tools.showNoButton
import com.hippo.ehviewer.ui.tools.snackBarPadding
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.ui.tools.toBBCode
import com.hippo.ehviewer.ui.tools.updateSpan
import com.hippo.ehviewer.util.ReadableTime
@@ -115,13 +116,9 @@ import com.hippo.ehviewer.util.displayString
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.system.logcat
import kotlin.collections.forEach
import kotlin.math.roundToInt
import moe.tarsin.coroutines.runSuspendCatching
import moe.tarsin.launch
import moe.tarsin.launchIO
import moe.tarsin.navigate
import moe.tarsin.snackbar
@@ -479,18 +476,15 @@ fun AnimatedVisibilityScope.GalleryCommentsScreen(gid: Long, navigator: Destinat
},
) {
val color = MaterialTheme.colorScheme.onPrimaryContainer
val toolbar = rememberBBCodeTextToolbar(userCommentBackField)
CompositionLocalProvider(LocalTextToolbar provides toolbar) {
BasicTextField(
value = userComment,
onValueChange = { textFieldValue ->
userComment = textFieldValue.updateSpan(userComment)
},
modifier = Modifier.weight(1f).padding(keylineMargin),
textStyle = MaterialTheme.typography.bodyLarge.merge(color = color),
cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
)
}
BasicTextField(
value = userComment,
onValueChange = { textFieldValue ->
userComment = textFieldValue.updateSpan(userComment)
},
modifier = Modifier.weight(1f).padding(keylineMargin).addBBCodeTextContextMenuItems(userCommentBackField),
textStyle = MaterialTheme.typography.bodyLarge.merge(color = color),
cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
)
IconButton(
onClick = { launchIO { sendComment() } },
shapes = IconButtonDefaults.shapes(),
@@ -69,6 +69,22 @@ import arrow.core.partially1
import arrow.fx.coroutines.parMap
import arrow.fx.coroutines.parZip
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.CrystalCard
import com.ehviewer.core.ui.component.FastScrollLazyVerticalGrid
import com.ehviewer.core.ui.component.FilledTertiaryIconButton
import com.ehviewer.core.ui.component.FilledTertiaryIconToggleButton
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.filled.Magnet
import com.ehviewer.core.ui.util.LocalWindowSizeClass
import com.ehviewer.core.ui.util.TransitionsVisibilityScope
import com.ehviewer.core.ui.util.isExpanded
import com.ehviewer.core.ui.util.rememberInVM
import com.ehviewer.core.util.async
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.launchIO
import com.ehviewer.core.util.launchUI
import com.ehviewer.core.util.withIOContext
import com.ehviewer.core.util.withUIContext
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
@@ -96,8 +112,6 @@ import com.hippo.ehviewer.dao.DownloadInfo
import com.hippo.ehviewer.dao.Filter
import com.hippo.ehviewer.dao.FilterMode
import com.hippo.ehviewer.download.DownloadManager
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.filled.Magnet
import com.hippo.ehviewer.ktbuilder.executeIn
import com.hippo.ehviewer.ktbuilder.imageRequest
import com.hippo.ehviewer.ui.GalleryInfoBottomSheet
@@ -117,15 +131,9 @@ import com.hippo.ehviewer.ui.modifyFavorites
import com.hippo.ehviewer.ui.navToReader
import com.hippo.ehviewer.ui.openBrowser
import com.hippo.ehviewer.ui.startDownload
import com.hippo.ehviewer.ui.tools.CrystalCard
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.FastScrollLazyVerticalGrid
import com.hippo.ehviewer.ui.tools.FilledTertiaryIconButton
import com.hippo.ehviewer.ui.tools.FilledTertiaryIconToggleButton
import com.hippo.ehviewer.ui.tools.GalleryDetailRating
import com.hippo.ehviewer.ui.tools.GalleryRatingBar
import com.hippo.ehviewer.ui.tools.LocalWindowSizeClass
import com.hippo.ehviewer.ui.tools.TransitionsVisibilityScope
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.awaitResult
import com.hippo.ehviewer.ui.tools.awaitSelectAction
@@ -135,8 +143,6 @@ import com.hippo.ehviewer.ui.tools.foldToLoadResult
import com.hippo.ehviewer.ui.tools.getClippedRefreshKey
import com.hippo.ehviewer.ui.tools.getLimit
import com.hippo.ehviewer.ui.tools.getOffset
import com.hippo.ehviewer.ui.tools.isExpanded
import com.hippo.ehviewer.ui.tools.rememberInVM
import com.hippo.ehviewer.ui.tools.showNoButton
import com.hippo.ehviewer.util.FavouriteStatusRouter
import com.hippo.ehviewer.util.addTextToClipboard
@@ -144,8 +150,6 @@ import com.hippo.ehviewer.util.bgWork
import com.hippo.ehviewer.util.displayString
import com.hippo.ehviewer.util.flattenForEach
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.system.logcat
import io.ktor.http.encodeURLParameter
import kotlin.coroutines.resume
@@ -154,12 +158,8 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import moe.tarsin.async
import moe.tarsin.coroutines.runSuspendCatching
import moe.tarsin.coroutines.runSwallowingWithUI
import moe.tarsin.launch
import moe.tarsin.launchIO
import moe.tarsin.launchUI
import moe.tarsin.navigate
import moe.tarsin.snackbar
import moe.tarsin.string
@@ -784,7 +784,7 @@ private fun getRatingText(rating: Float): Int = when ((rating * 2).roundToInt())
else -> R.string.rating_none
}
private fun List<GalleryTagGroup>.artistTag() = find { (ns, _) -> ns == TagNamespace.Artist || ns == TagNamespace.Cosplayer }?.let { (ns, tags) -> "$ns:${tags[0].text}" }
private fun List<GalleryTagGroup>.artistTag() = find { (ns, _) -> ns == TagNamespace.Artist || ns == TagNamespace.Cosplayer }?.let { (ns, tags) -> "${ns.value}:${tags[0].text}" }
@Composable
context(_: Context)
@@ -35,6 +35,12 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.util.fastJoinToString
import androidx.lifecycle.viewModelScope
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.util.LocalWindowSizeClass
import com.ehviewer.core.ui.util.isExpanded
import com.ehviewer.core.ui.util.launchInVM
import com.ehviewer.core.ui.util.rememberInVM
import com.ehviewer.core.util.launchIO
import com.ehviewer.core.util.withIOContext
import com.hippo.ehviewer.EhApplication.Companion.imageCache
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
@@ -58,12 +64,8 @@ import com.hippo.ehviewer.ui.main.GalleryDetailErrorTip
import com.hippo.ehviewer.ui.main.NavigationIcon
import com.hippo.ehviewer.ui.navToReader
import com.hippo.ehviewer.ui.openBrowser
import com.hippo.ehviewer.ui.tools.LocalWindowSizeClass
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.awaitSelectTags
import com.hippo.ehviewer.ui.tools.isExpanded
import com.hippo.ehviewer.ui.tools.launchInVM
import com.hippo.ehviewer.ui.tools.rememberInVM
import com.hippo.ehviewer.util.AppHelper
import com.hippo.ehviewer.util.awaitActivityResult
import com.hippo.ehviewer.util.bgWork
@@ -73,11 +75,9 @@ import com.hippo.files.toOkioPath
import com.ramcosta.composedestinations.annotation.Destination
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 moe.tarsin.coroutines.runSuspendCatching
import moe.tarsin.launchIO
import moe.tarsin.snackbar
import moe.tarsin.tip
@@ -70,6 +70,20 @@ import androidx.paging.compose.collectAsLazyPagingItems
import arrow.core.raise.ensure
import arrow.core.raise.ensureNotNull
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.FAB_ANIMATE_TIME
import com.ehviewer.core.ui.component.FabLayout
import com.ehviewer.core.ui.component.FastScrollLazyColumn
import com.ehviewer.core.ui.component.LocalSideSheetState
import com.ehviewer.core.ui.component.ProvideSideSheetContent
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.filled.GoTo
import com.ehviewer.core.ui.util.Await
import com.ehviewer.core.ui.util.asyncState
import com.ehviewer.core.ui.util.thenIf
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.launchIO
import com.ehviewer.core.util.onEachLatest
import com.ehviewer.core.util.withUIContext
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.asMutableState
@@ -87,46 +101,32 @@ import com.hippo.ehviewer.client.parser.GalleryDetailUrlParser
import com.hippo.ehviewer.client.parser.GalleryPageUrlParser
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.dao.QuickSearch
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.filled.GoTo
import com.hippo.ehviewer.ui.DrawerHandle
import com.hippo.ehviewer.ui.LocalSideSheetState
import com.hippo.ehviewer.ui.ProvideSideSheetContent
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.awaitSelectDate
import com.hippo.ehviewer.ui.destinations.ProgressScreenDestination
import com.hippo.ehviewer.ui.doGalleryInfoAction
import com.hippo.ehviewer.ui.main.AdvancedSearchOption
import com.hippo.ehviewer.ui.main.AvatarIcon
import com.hippo.ehviewer.ui.main.FAB_ANIMATE_TIME
import com.hippo.ehviewer.ui.main.FabLayout
import com.hippo.ehviewer.ui.main.GalleryInfoGridItem
import com.hippo.ehviewer.ui.main.GalleryInfoListItem
import com.hippo.ehviewer.ui.main.GalleryList
import com.hippo.ehviewer.ui.main.SearchFilter
import com.hippo.ehviewer.ui.tools.Await
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.FastScrollLazyColumn
import com.hippo.ehviewer.ui.tools.HapticFeedbackType
import com.hippo.ehviewer.ui.tools.asyncState
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.awaitInputText
import com.hippo.ehviewer.ui.tools.awaitInputTextWithCheckBox
import com.hippo.ehviewer.ui.tools.rememberHapticFeedback
import com.hippo.ehviewer.ui.tools.rememberMutableStateInDataStore
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.FavouriteStatusRouter
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.spec.Direction
import eu.kanade.tachiyomi.util.lang.withUIContext
import kotlin.math.roundToInt
import kotlin.random.Random
import kotlinx.coroutines.delay
import moe.tarsin.coroutines.onEachLatest
import moe.tarsin.launch
import moe.tarsin.launchIO
import moe.tarsin.navigate
import moe.tarsin.snackbar
import moe.tarsin.string
@@ -482,10 +482,10 @@ fun AnimatedVisibilityScope.GalleryListScreen(
searchFieldState = searchFieldState,
suggestionProvider = {
GalleryDetailUrlParser.parse(it, false)?.run {
GalleryDetailUrlSuggestion(gid, token)
listOf(GalleryDetailUrlSuggestion(gid, token))
} ?: GalleryPageUrlParser.parse(it, false)?.run {
GalleryPageUrlSuggestion(gid, pToken, page)
}
listOf(GalleryPageUrlSuggestion(gid, pToken, page))
}.orEmpty()
},
localSearch = false,
searchBarOffsetY = { searchBarOffsetY },
@@ -11,12 +11,12 @@ import androidx.paging.PagingSource
import androidx.paging.PagingState
import androidx.paging.cachedIn
import androidx.savedstate.compose.serialization.serializers.MutableStateSerializer
import com.ehviewer.core.util.withIOContext
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.client.data.ListUrlBuilder
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_TOPLIST
import com.hippo.ehviewer.ui.tools.foldToLoadResult
import eu.kanade.tachiyomi.util.lang.withIOContext
import moe.tarsin.coroutines.runSuspendCatching
class GalleryListViewModel(lub: ListUrlBuilder, savedStateHandle: SavedStateHandle) : ViewModel() {
@@ -43,20 +43,21 @@ import androidx.paging.compose.itemContentType
import androidx.paging.compose.itemKey
import androidx.paging.map
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.FastScrollLazyColumn
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.big.History
import com.ehviewer.core.ui.util.Await
import com.ehviewer.core.ui.util.rememberInVM
import com.ehviewer.core.ui.util.thenIf
import com.ehviewer.core.util.launch
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.big.History
import com.hippo.ehviewer.ui.DrawerHandle
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.doGalleryInfoAction
import com.hippo.ehviewer.ui.main.GalleryInfoListItem
import com.hippo.ehviewer.ui.tools.Await
import com.hippo.ehviewer.ui.tools.FastScrollLazyColumn
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.rememberInVM
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.FavouriteStatusRouter
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
@@ -64,7 +65,6 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlin.math.roundToInt
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.map
import moe.tarsin.launch
import moe.tarsin.navigate
@Destination<RootGraph>
@@ -28,21 +28,21 @@ import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.util.snackBarPadding
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.launchUI
import com.ehviewer.core.util.withIOContext
import com.hippo.ehviewer.client.data.ListUrlBuilder
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_IMAGE_SEARCH
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.main.ImageSearch
import com.hippo.ehviewer.ui.main.plus
import com.hippo.ehviewer.ui.tools.snackBarPadding
import com.hippo.ehviewer.util.pickVisualMedia
import com.hippo.ehviewer.util.sha1
import com.hippo.files.toOkioPath
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.lang.withIOContext
import moe.tarsin.launch
import moe.tarsin.launchUI
import moe.tarsin.navigate
import moe.tarsin.snackbar
@@ -22,15 +22,15 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.big.SadAndroid
import com.ehviewer.core.util.withUIContext
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.big.SadAndroid
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.util.displayString
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.lang.withUIContext
import moe.tarsin.coroutines.runSuspendCatching
import moe.tarsin.navigate
@@ -66,6 +66,9 @@ import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.coerceAtMost
import androidx.compose.ui.unit.dp
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.util.thenIf
import com.ehviewer.core.util.launchIO
import com.ehviewer.core.util.launchUI
import com.hippo.ehviewer.EhApplication.Companion.searchDatabase
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhTagDatabase
@@ -79,12 +82,9 @@ import com.hippo.ehviewer.ui.theme.scrim
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.rememberCompositionActiveState
import com.hippo.ehviewer.ui.tools.thenIf
import com.jamal.composeprefs3.ui.ifNotNullThen
import com.jamal.composeprefs3.ui.ifTrueThen
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.launchUI
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
@@ -94,7 +94,7 @@ import kotlinx.coroutines.launch
import moe.tarsin.navigate
fun interface SuggestionProvider {
fun providerSuggestions(text: String): Suggestion?
suspend fun providerSuggestions(text: String): List<Suggestion>
}
abstract class Suggestion {
@@ -164,7 +164,7 @@ fun SearchBarScreen(
fun mergedSuggestionFlow(): Flow<Suggestion> = with(context) {
flow {
val query = searchFieldState.text.toString()
suggestionProvider?.run { providerSuggestions(query)?.let { emit(it) } }
suggestionProvider?.run { providerSuggestions(query).forEach { emit(it) } }
mSearchDatabase.suggestions(query, 128).forEach { emit(KeywordSuggestion(it)) }
val index = if (localSearch) query.lastIndexOf(' ') else query.lastIndexOfAny(TagTerminators)
val keyword = query.substring(index + 1).trimStart()
@@ -22,6 +22,8 @@ import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.fromHtml
import androidx.compose.ui.unit.dp
import com.ehviewer.core.i18n.R
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.withUIContext
import com.hippo.ehviewer.BuildConfig
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
@@ -42,9 +44,7 @@ import com.hippo.files.delete
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.lang.withUIContext
import moe.tarsin.coroutines.runSuspendCatching
import moe.tarsin.launch
import moe.tarsin.navigate
import moe.tarsin.snackbar
import moe.tarsin.string
@@ -31,6 +31,8 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import androidx.core.net.toUri
import com.ehviewer.core.i18n.R
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.withIOContext
import com.hippo.ehviewer.BuildConfig
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
@@ -57,7 +59,6 @@ import com.hippo.files.toOkioPath
import com.ramcosta.composedestinations.annotation.Destination
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 java.io.File
import java.util.zip.ZipEntry
@@ -67,7 +68,6 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.merge
import me.zhanghai.compose.preference.DropdownListPreference
import moe.tarsin.coroutines.runSuspendCatching
import moe.tarsin.launch
import moe.tarsin.snackbar
import moe.tarsin.string
@@ -30,6 +30,8 @@ import androidx.compose.ui.unit.dp
import arrow.fx.coroutines.parMap
import arrow.fx.coroutines.parMapNotNull
import com.ehviewer.core.i18n.R
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.launchIO
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.asMutableState
@@ -73,8 +75,6 @@ import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import eu.kanade.tachiyomi.util.system.logcat
import moe.tarsin.coroutines.runSuspendCatching
import moe.tarsin.launch
import moe.tarsin.launchIO
import moe.tarsin.snackbar
import moe.tarsin.string
import okio.Path
@@ -29,6 +29,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.fromHtml
import com.ehviewer.core.i18n.R
import com.ehviewer.core.util.launch
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.asMutableState
import com.hippo.ehviewer.client.EhCookieStore
@@ -49,7 +50,6 @@ import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.datetime.LocalTime
import moe.tarsin.launch
import moe.tarsin.navigate
import moe.tarsin.snackbar
@@ -54,6 +54,10 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.util.Await
import com.ehviewer.core.ui.util.thenIf
import com.ehviewer.core.util.async
import com.ehviewer.core.util.launch
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhFilter
import com.hippo.ehviewer.client.EhFilter.forget
@@ -64,17 +68,13 @@ import com.hippo.ehviewer.dao.Filter
import com.hippo.ehviewer.dao.FilterMode
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.main.NavigationIcon
import com.hippo.ehviewer.ui.tools.Await
import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.hippo.ehviewer.ui.tools.dialog
import com.hippo.ehviewer.ui.tools.thenIf
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlin.coroutines.resume
import moe.tarsin.async
import moe.tarsin.coroutines.groupByToObserved
import moe.tarsin.launch
@Destination<RootGraph>
@Composable
@@ -21,7 +21,7 @@ import androidx.compose.ui.res.integerArrayResource
import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import com.hippo.ehviewer.ui.main.RollingNumber
import com.ehviewer.core.ui.component.RollingNumber
import com.hippo.ehviewer.ui.openBrowser
import com.hippo.ehviewer.util.ProgressDialog
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
@@ -13,6 +13,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import com.ehviewer.core.i18n.R
import com.ehviewer.core.util.launch
import com.hippo.ehviewer.EhApplication.Companion.searchDatabase
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.asMutableState
@@ -23,7 +24,6 @@ import com.hippo.ehviewer.ui.tools.awaitConfirmationOrCancel
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import moe.tarsin.launch
import moe.tarsin.snackbar
@Destination<RootGraph>
@@ -17,8 +17,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import com.ehviewer.core.i18n.R
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.filled.SadPanda
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.filled.SadPanda
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.destinations.AboutScreenDestination
import com.hippo.ehviewer.ui.destinations.AdvancedScreenDestination
@@ -16,6 +16,7 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import com.ehviewer.core.i18n.R
import com.ehviewer.core.util.launch
import com.google.accompanist.web.WebView
import com.google.accompanist.web.rememberWebViewNavigator
import com.google.accompanist.web.rememberWebViewState
@@ -27,7 +28,6 @@ import com.hippo.ehviewer.util.setDefaultSettings
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import moe.tarsin.launch
import moe.tarsin.snackbar
private const val APPLY_JS = "javascript:(function(){var apply = document.getElementById(\"apply\").children[0];apply.click();})();"
@@ -18,9 +18,9 @@ import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import com.ehviewer.core.ui.component.scrollbarStyle
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.ui.tools.scrollbarStyle
import com.hippo.ehviewer.util.isAtLeastOMR1
import com.hippo.ehviewer.util.isAtLeastS
import com.materialkolor.dynamicColorScheme
@@ -1,18 +1,17 @@
package com.hippo.ehviewer.ui.tools
import android.view.ActionMode
import android.view.Menu
import android.view.MenuItem
import android.content.Context
import androidx.annotation.StringRes
import androidx.compose.foundation.text.contextmenu.builder.item
import androidx.compose.foundation.text.contextmenu.data.TextContextMenuKeys
import androidx.compose.foundation.text.contextmenu.modifier.appendTextContextMenuComponents
import androidx.compose.foundation.text.contextmenu.modifier.filterTextContextMenuComponents
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.platform.TextToolbar
import androidx.compose.ui.platform.TextToolbarStatus
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextRange
@@ -25,8 +24,7 @@ import androidx.compose.ui.text.input.getTextAfterSelection
import androidx.compose.ui.text.input.getTextBeforeSelection
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
import com.hippo.ehviewer.R
import com.hippo.ehviewer.ui.MainActivity
import com.ehviewer.core.i18n.R
import com.hippo.ehviewer.util.toRangeSet
import io.github.petertrr.diffutils.diffInline
import io.github.petertrr.diffutils.patch.ChangeDelta
@@ -36,8 +34,7 @@ import io.github.petertrr.diffutils.patch.InsertDelta
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import moe.tarsin.kt.unreachable
typealias PlatformRect = android.graphics.Rect
import moe.tarsin.string
fun TextFieldValue.updateSpan(origin: TextFieldValue): TextFieldValue {
val oriSpan = origin.annotatedString.spanStyles
@@ -141,118 +138,81 @@ fun AnnotatedString.toBBCode() = buildString {
}
@Composable
context(activity: MainActivity)
fun rememberBBCodeTextToolbar(textFieldValue: MutableState<TextFieldValue>): TextToolbar {
context(_: Context)
fun Modifier.addBBCodeTextContextMenuItems(textFieldValue: MutableState<TextFieldValue>): Modifier {
var tfv by textFieldValue
val view = LocalView.current
val coroutineScope = rememberCoroutineScope()
val toolbar = remember {
object : TextToolbar {
private var actionMode: ActionMode? = null
private val callback = object : TextActionModeCallback() {
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
super.onCreateActionMode(mode, menu)
activity.menuInflater.inflate(R.menu.context_comment, menu)
return true
}
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
super.onPrepareActionMode(mode, menu)
if (tfv.selection.collapsed) {
menu.removeGroup(R.id.bbcode_group)
return appendTextContextMenuComponents {
if (tfv.selection.collapsed) return@appendTextContextMenuComponents
BBCodeFormat.entries.forEach { item ->
item(key = item, label = string(item.id)) {
val capturedTfv = tfv
val start = capturedTfv.selection.min
val end = capturedTfv.selection.max
val annotatedString = buildAnnotatedString {
val len = capturedTfv.text.length
fun addStyle(style: SpanStyle) {
append(capturedTfv.annotatedString)
addStyle(style, start, end)
}
return true
}
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
val handled = super.onActionItemClicked(mode, item)
if (handled) {
return true
}
val capturedTfv = tfv
val start = capturedTfv.selection.min
val end = capturedTfv.selection.max
val annotatedString = buildAnnotatedString {
val len = capturedTfv.text.length
fun addStyle(style: SpanStyle) {
append(capturedTfv.annotatedString)
addStyle(style, start, end)
fun addTextDecoration(decoration: TextDecoration) {
append(capturedTfv.getTextBeforeSelection(len))
val ans = capturedTfv.getSelectedText()
val spans = ans.spanStyles.filter {
it.item.textDecoration == null || it.item.textDecoration == decoration
}
fun addTextDecoration(decoration: TextDecoration) {
withStyle(SpanStyle(textDecoration = decoration)) {
append(AnnotatedString(ans.text, spans))
}
append(capturedTfv.getTextAfterSelection(len))
}
when (item) {
BBCodeFormat.Bold -> addStyle(SpanStyle(fontWeight = FontWeight.Bold))
BBCodeFormat.Italic -> addStyle(SpanStyle(fontStyle = FontStyle.Italic))
BBCodeFormat.Underline -> addTextDecoration(TextDecoration.Underline)
BBCodeFormat.Strikethrough -> addTextDecoration(TextDecoration.LineThrough)
BBCodeFormat.Url -> append(capturedTfv.annotatedString)
BBCodeFormat.Clear -> {
append(capturedTfv.getTextBeforeSelection(len))
val ans = capturedTfv.getSelectedText()
val spans = ans.spanStyles.filter {
it.item.textDecoration == null || it.item.textDecoration == decoration
}
withStyle(SpanStyle(textDecoration = decoration)) {
append(AnnotatedString(ans.text, spans))
}
append(capturedTfv.getSelectedText().text)
append(capturedTfv.getTextAfterSelection(len))
}
when (item.itemId) {
R.id.action_bold -> addStyle(SpanStyle(fontWeight = FontWeight.Bold))
R.id.action_italic -> addStyle(SpanStyle(fontStyle = FontStyle.Italic))
R.id.action_underline -> addTextDecoration(TextDecoration.Underline)
R.id.action_strikethrough -> addTextDecoration(TextDecoration.LineThrough)
R.id.action_url -> append(capturedTfv.annotatedString)
R.id.action_clear -> {
append(capturedTfv.getTextBeforeSelection(len))
append(capturedTfv.getSelectedText().text)
append(capturedTfv.getTextAfterSelection(len))
}
}
}
tfv = TextFieldValue(
annotatedString = buildAnnotatedString {
append(annotatedString)
// Hacky: Trigger recomposition to hide text toolbar
append(Char.MIN_VALUE)
},
selection = TextRange(end),
)
coroutineScope.launch {
// Hacky: Let TextField recompose first
delay(100)
tfv = tfv.copy(annotatedString = annotatedString)
}
mode.finish()
return true
}
override fun onDestroyActionMode(mode: ActionMode) {
actionMode = null
}
}
override var status = TextToolbarStatus.Hidden
override fun hide() {
status = TextToolbarStatus.Hidden
actionMode?.finish()
actionMode = null
}
override fun showMenu(
rect: Rect,
onCopyRequested: (() -> Unit)?,
onPasteRequested: (() -> Unit)?,
onCutRequested: (() -> Unit)?,
onSelectAllRequested: (() -> Unit)?,
) {
callback.rect = rect
callback.onCopyRequested = onCopyRequested
callback.onCutRequested = onCutRequested
callback.onPasteRequested = onPasteRequested
callback.onSelectAllRequested = onSelectAllRequested
if (actionMode == null) {
status = TextToolbarStatus.Shown
actionMode = view.startActionMode(callback, ActionMode.TYPE_FLOATING)
} else {
actionMode?.invalidate()
tfv = TextFieldValue(
annotatedString = buildAnnotatedString {
append(annotatedString)
// Hacky: Trigger recomposition to hide text toolbar
append(Char.MIN_VALUE)
},
selection = TextRange(end),
)
coroutineScope.launch {
// Hacky: Let TextField recompose first
delay(100)
tfv = tfv.copy(annotatedString = annotatedString)
}
close()
}
}
}.filterTextContextMenuComponents {
when (it.key) {
TextContextMenuKeys.CutKey,
TextContextMenuKeys.CopyKey,
TextContextMenuKeys.PasteKey,
TextContextMenuKeys.SelectAllKey,
is BBCodeFormat,
-> true
else -> false
}
}
return toolbar
}
private enum class BBCodeFormat(@StringRes val id: Int) {
Bold(R.string.format_bold),
Italic(R.string.format_italic),
Underline(R.string.format_underline),
Strikethrough(R.string.format_strikethrough),
Url(R.string.format_url),
Clear(R.string.format_plain),
}
@@ -94,6 +94,8 @@ import arrow.core.raise.Raise
import arrow.core.raise.either
import arrow.core.right
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.component.FastScrollLazyColumn
import com.ehviewer.core.ui.component.LabeledCheckbox
import com.hippo.ehviewer.client.EhTagDatabase
import com.hippo.ehviewer.client.EhTagDatabase.suggestion
import com.jamal.composeprefs3.ui.ifNotNullThen
@@ -1,116 +0,0 @@
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.ehviewer.ui.tools
import android.view.ActionMode
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.compose.ui.geometry.Rect
open class TextActionModeCallback(
var rect: Rect = Rect.Zero,
var onCopyRequested: (() -> Unit)? = null,
var onPasteRequested: (() -> Unit)? = null,
var onCutRequested: (() -> Unit)? = null,
var onSelectAllRequested: (() -> Unit)? = null,
) : ActionMode.Callback2() {
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
onCopyRequested?.let {
addMenuItem(menu, MenuItemOption.Copy)
}
onPasteRequested?.let {
addMenuItem(menu, MenuItemOption.Paste)
}
onCutRequested?.let {
addMenuItem(menu, MenuItemOption.Cut)
}
onSelectAllRequested?.let {
addMenuItem(menu, MenuItemOption.SelectAll)
}
return true
}
// this method is called to populate new menu items when the actionMode was invalidated
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
updateMenuItems(menu)
// should return true so that new menu items are populated
return true
}
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
when (item.itemId) {
MenuItemOption.Copy.id -> onCopyRequested?.invoke()
MenuItemOption.Paste.id -> onPasteRequested?.invoke()
MenuItemOption.Cut.id -> onCutRequested?.invoke()
MenuItemOption.SelectAll.id -> onSelectAllRequested?.invoke()
else -> return false
}
mode.finish()
return true
}
override fun onDestroyActionMode(mode: ActionMode) = Unit
override fun onGetContentRect(mode: ActionMode, view: View, outRect: PlatformRect) {
outRect.set(rect.left.toInt(), rect.top.toInt(), rect.right.toInt(), rect.bottom.toInt())
}
private fun updateMenuItems(menu: Menu) {
addOrRemoveMenuItem(menu, MenuItemOption.Copy, onCopyRequested)
addOrRemoveMenuItem(menu, MenuItemOption.Paste, onPasteRequested)
addOrRemoveMenuItem(menu, MenuItemOption.Cut, onCutRequested)
addOrRemoveMenuItem(menu, MenuItemOption.SelectAll, onSelectAllRequested)
}
private fun addMenuItem(menu: Menu, item: MenuItemOption) {
menu.add(0, item.id, item.order, item.titleResource)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
}
private fun addOrRemoveMenuItem(
menu: Menu,
item: MenuItemOption,
callback: (() -> Unit)?,
) {
when {
callback != null && menu.findItem(item.id) == null -> addMenuItem(menu, item)
callback == null && menu.findItem(item.id) != null -> menu.removeItem(item.id)
}
}
}
enum class MenuItemOption(val id: Int) {
Copy(0),
Paste(1),
Cut(2),
SelectAll(3),
;
val titleResource: Int
get() = when (this) {
Copy -> android.R.string.copy
Paste -> android.R.string.paste
Cut -> android.R.string.cut
SelectAll -> android.R.string.selectAll
}
/**
* This item will be shown before all items that have order greater than this value.
*/
val order = id
}
@@ -22,10 +22,10 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.paging.compose.LazyPagingItems
import com.ehviewer.core.ui.util.launchInVM
import com.ehviewer.core.ui.util.rememberUpdatedStateInVM
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.ui.tools.launchInVM
import com.hippo.ehviewer.ui.tools.rememberUpdatedStateInVM
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.FlowCollector
@@ -22,7 +22,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.ehviewer.core.i18n.R
import eu.kanade.tachiyomi.util.lang.withUIContext
import com.ehviewer.core.util.withUIContext
import java.io.File
import kotlin.concurrent.atomics.AtomicInt
import kotlin.concurrent.atomics.fetchAndIncrement
@@ -27,12 +27,12 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.ehviewer.core.i18n.R
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.filled.Crop
import com.ehviewer.core.ui.icons.filled.CropOff
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.asMutableState
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.filled.Crop
import com.hippo.ehviewer.icons.filled.CropOff
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.ui.reader.setting.PreferenceType
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
@@ -19,11 +19,11 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import com.ehviewer.core.ui.component.Slider
import com.ehviewer.core.ui.component.defaultMaxTickCount
import com.ehviewer.core.ui.util.LocalWindowSizeClass
import com.ehviewer.core.ui.util.isExpanded
import com.hippo.ehviewer.ui.tools.HapticFeedbackType
import com.hippo.ehviewer.ui.tools.LocalWindowSizeClass
import com.hippo.ehviewer.ui.tools.Slider
import com.hippo.ehviewer.ui.tools.defaultMaxTickCount
import com.hippo.ehviewer.ui.tools.isExpanded
import com.hippo.ehviewer.ui.tools.rememberHapticFeedback
@Composable
@@ -13,8 +13,8 @@ import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import com.hippo.ehviewer.ui.main.RollingNumber
import com.hippo.ehviewer.ui.main.RollingNumberPlaceholder
import com.ehviewer.core.ui.component.RollingNumber
import com.ehviewer.core.ui.component.RollingNumberPlaceholder
@Composable
fun PageIndicatorText(
@@ -3,12 +3,12 @@ package eu.kanade.tachiyomi.ui.reader.setting
import android.content.pm.ActivityInfo
import androidx.compose.ui.graphics.vector.ImageVector
import com.ehviewer.core.i18n.R
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.reader.Landscape
import com.hippo.ehviewer.icons.reader.LandscapeLocked
import com.hippo.ehviewer.icons.reader.Portrait
import com.hippo.ehviewer.icons.reader.PortraitLocked
import com.hippo.ehviewer.icons.reader.ScreenRotation
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.reader.Landscape
import com.ehviewer.core.ui.icons.reader.LandscapeLocked
import com.ehviewer.core.ui.icons.reader.Portrait
import com.ehviewer.core.ui.icons.reader.PortraitLocked
import com.ehviewer.core.ui.icons.reader.ScreenRotation
enum class OrientationType(
override val prefValue: Int,
@@ -3,13 +3,13 @@ package eu.kanade.tachiyomi.ui.reader.setting
import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.vector.ImageVector
import com.ehviewer.core.i18n.R
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.reader.ContinuousVertical
import com.hippo.ehviewer.icons.reader.Default
import com.hippo.ehviewer.icons.reader.LeftToRight
import com.hippo.ehviewer.icons.reader.RightToLeft
import com.hippo.ehviewer.icons.reader.Vertical
import com.hippo.ehviewer.icons.reader.Webtoon
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.reader.ContinuousVertical
import com.ehviewer.core.ui.icons.reader.Default
import com.ehviewer.core.ui.icons.reader.LeftToRight
import com.ehviewer.core.ui.icons.reader.RightToLeft
import com.ehviewer.core.ui.icons.reader.Vertical
import com.ehviewer.core.ui.icons.reader.Webtoon
@Stable
enum class ReadingModeType(
@@ -30,7 +30,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.hippo.ehviewer.ui.tools.Slider
import com.ehviewer.core.ui.component.Slider
@Composable
fun IntSliderPreference(
@@ -7,25 +7,6 @@ import androidx.compose.material3.SnackbarHostState
import com.hippo.ehviewer.ui.MainActivity
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.spec.Direction
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
context(scope: CoroutineScope)
fun launch(context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit) = scope.launch(context, start, block)
context(scope: CoroutineScope)
fun <T> async(context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> T) = scope.async(context, start, block)
context(_: CoroutineScope)
fun launchIO(block: suspend CoroutineScope.() -> Unit) = launch(Dispatchers.IO, block = block)
context(_: CoroutineScope)
fun launchUI(block: suspend CoroutineScope.() -> Unit) = launch(Dispatchers.Main, block = block)
context(nav: DestinationsNavigator)
fun navigate(direction: Direction) = nav.navigate(direction)
@@ -1,10 +1,10 @@
package moe.tarsin.coroutines
import androidx.compose.material3.SnackbarHostState
import com.ehviewer.core.util.launch
import com.hippo.ehviewer.util.displayString
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import moe.tarsin.launch
import moe.tarsin.snackbar
inline fun <T, reified E : Throwable> Result<T>.except() = onFailure { if (it is E) throw it }
+101 -74
View File
@@ -60,9 +60,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.98"
version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
[[package]]
name = "atomic-waker"
@@ -114,9 +114,9 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
[[package]]
name = "bitflags"
version = "2.9.1"
version = "2.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d"
[[package]]
name = "bumpalo"
@@ -144,10 +144,11 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "cc"
version = "1.2.32"
version = "1.2.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2352e5597e9c544d5e6d9c95190d5d27738ade584fa8db0a16e130e5c2b5296e"
checksum = "590f9024a68a8c40351881787f1934dc11afd69090f5edb6831464694d836ea3"
dependencies = [
"find-msvc-tools",
"shlex",
]
@@ -159,9 +160,9 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
[[package]]
name = "cfg-if"
version = "1.0.1"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "chrono"
@@ -391,6 +392,12 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "find-msvc-tools"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e178e4fba8a2726903f6ba98a6d221e76f9c12c650d5dc0e6afdc50677b49650"
[[package]]
name = "fnv"
version = "1.0.7"
@@ -414,9 +421,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
dependencies = [
"percent-encoding",
]
@@ -480,7 +487,7 @@ dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
"wasi 0.14.3+wasi-0.2.4",
]
[[package]]
@@ -562,19 +569,21 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "hyper"
version = "1.6.0"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e"
dependencies = [
"atomic-waker",
"bytes",
"futures-channel",
"futures-util",
"futures-core",
"h2",
"http",
"http-body",
"httparse",
"itoa",
"pin-project-lite",
"pin-utils",
"smallvec",
"tokio",
"want",
@@ -750,9 +759,9 @@ dependencies = [
[[package]]
name = "idna"
version = "1.0.3"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
dependencies = [
"idna_adapter",
"smallvec",
@@ -771,20 +780,21 @@ dependencies = [
[[package]]
name = "image"
version = "0.25.6"
version = "0.25.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a"
checksum = "1c6a3ce16143778e24df6f95365f12ed105425b22abefd289dd88a64bab59605"
dependencies = [
"bytemuck",
"byteorder-lite",
"moxcms",
"num-traits",
]
[[package]]
name = "indexmap"
version = "2.10.0"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9"
dependencies = [
"equivalent",
"hashbrown",
@@ -792,9 +802,9 @@ dependencies = [
[[package]]
name = "io-uring"
version = "0.7.9"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4"
checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b"
dependencies = [
"bitflags",
"cfg-if",
@@ -874,9 +884,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.174"
version = "0.2.175"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]]
name = "libwebp-sys2"
@@ -940,6 +950,16 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "moxcms"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd32fa8935aeadb8a8a6b6b351e40225570a37c43de67690383d87ef170cd08"
dependencies = [
"num-traits",
"pxfm",
]
[[package]]
name = "multimap"
version = "0.10.1"
@@ -1146,9 +1166,9 @@ dependencies = [
[[package]]
name = "percent-encoding"
version = "2.3.1"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "phf"
@@ -1188,9 +1208,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "potential_utf"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a"
dependencies = [
"zerovec",
]
@@ -1206,18 +1226,27 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.96"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beef09f85ae72cea1ef96ba6870c51e6382ebfa4f0e85b643459331f3daa5be0"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quick-xml"
version = "0.38.1"
name = "pxfm"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9845d9dccf565065824e69f9f235fafba1587031eda353c1f1561cd6a6be78f4"
checksum = "6e790881194f6f6e86945f0a42a6981977323669aeb6c40e9c7ec253133b96f8"
dependencies = [
"num-traits",
]
[[package]]
name = "quick-xml"
version = "0.38.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89"
dependencies = [
"memchr",
]
@@ -1245,9 +1274,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
[[package]]
name = "regex"
version = "1.11.1"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912"
dependencies = [
"aho-corasick",
"memchr",
@@ -1257,9 +1286,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.4.9"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6"
dependencies = [
"aho-corasick",
"memchr",
@@ -1268,21 +1297,21 @@ dependencies = [
[[package]]
name = "regex-lite"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a"
checksum = "943f41321c63ef1c92fd763bfe054d2668f7f225a5c29f0105903dc2fc04ba30"
[[package]]
name = "regex-syntax"
version = "0.8.5"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
[[package]]
name = "reqwest"
version = "0.12.22"
version = "0.12.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531"
checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb"
dependencies = [
"base64",
"bytes",
@@ -1392,9 +1421,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "rxing"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd71c7ac73cb59c313c0a09f07ad0a4f8a29cdd4e025e58ef1f714520450e097"
checksum = "065826c9e75902c67ce057a62d8ccd7adacf7bbc905352d9530ac6178975f584"
dependencies = [
"chrono",
"chrono-tz",
@@ -1406,7 +1435,7 @@ dependencies = [
"once_cell",
"regex",
"rxing-one-d-proc-derive",
"thiserror 2.0.12",
"thiserror 2.0.16",
"unicode-segmentation",
"uriparse",
"urlencoding",
@@ -1501,9 +1530,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.142"
version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7"
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
dependencies = [
"itoa",
"memchr",
@@ -1571,9 +1600,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.104"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
@@ -1623,15 +1652,15 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.20.0"
version = "3.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e"
dependencies = [
"fastrand",
"getrandom 0.3.3",
"once_cell",
"rustix",
"windows-sys 0.59.0",
"windows-sys 0.60.2",
]
[[package]]
@@ -1645,11 +1674,11 @@ dependencies = [
[[package]]
name = "thiserror"
version = "2.0.12"
version = "2.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0"
dependencies = [
"thiserror-impl 2.0.12",
"thiserror-impl 2.0.16",
]
[[package]]
@@ -1665,9 +1694,9 @@ dependencies = [
[[package]]
name = "thiserror-impl"
version = "2.0.12"
version = "2.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960"
dependencies = [
"proc-macro2",
"quote",
@@ -1868,13 +1897,14 @@ dependencies = [
[[package]]
name = "url"
version = "2.5.4"
version = "2.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
"serde",
]
[[package]]
@@ -1922,11 +1952,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
version = "0.14.3+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95"
dependencies = [
"wit-bindgen-rt",
"wit-bindgen",
]
[[package]]
@@ -2012,11 +2042,11 @@ dependencies = [
[[package]]
name = "winapi-util"
version = "0.1.9"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22"
dependencies = [
"windows-sys 0.59.0",
"windows-sys 0.60.2",
]
[[package]]
@@ -2313,21 +2343,18 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winnow"
version = "0.7.12"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
name = "wit-bindgen"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]
checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814"
[[package]]
name = "writeable"
+3 -3
View File
@@ -2,9 +2,9 @@ dependencyResolutionManagement {
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
includeGroupAndSubgroups("androidx")
includeGroupAndSubgroups("com.android")
includeGroupAndSubgroups("com.google")
}
}
mavenCentral()
+21
View File
@@ -0,0 +1,21 @@
plugins {
alias(libs.plugins.ehviewer.multiplatform.library)
}
kotlin {
sourceSets {
commonMain {
dependencies {
api(libs.kotlinx.coroutines.core)
api(libs.logcat)
api(project.dependencies.platform(libs.arrow.stack))
api(libs.bundles.arrow)
}
}
androidMain {
dependencies {
api(libs.kotlinx.coroutines.android)
}
}
}
}
@@ -0,0 +1,21 @@
package com.ehviewer.core.util
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
context(scope: CoroutineScope)
fun launch(context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit) = scope.launch(context, start, block)
context(scope: CoroutineScope)
fun <T> async(context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> T) = scope.async(context, start, block)
context(_: CoroutineScope)
fun launchIO(block: suspend CoroutineScope.() -> Unit) = launch(Dispatchers.IO, block = block)
context(_: CoroutineScope)
fun launchUI(block: suspend CoroutineScope.() -> Unit) = launch(Dispatchers.Main, block = block)
@@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.util.lang
package com.ehviewer.core.util
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -1,4 +1,4 @@
package moe.tarsin.coroutines
package com.ehviewer.core.util
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.transformLatest
@@ -1,3 +1,3 @@
package com.hippo.ehviewer.util
package com.ehviewer.core.util
fun <T> unsafeLazy(initializer: () -> T) = lazy(LazyThreadSafetyMode.NONE, initializer)
+1 -2
View File
@@ -6,14 +6,13 @@ kotlin {
sourceSets {
commonMain {
dependencies {
api(projects.core.common)
api(project.dependencies.platform(libs.okio.bom))
api(libs.androidx.datastore)
api(libs.kotlinx.coroutines.core)
}
}
androidMain {
dependencies {
api(libs.kotlinx.coroutines.android)
api(libs.splitties.appctx)
}
}
@@ -5,11 +5,9 @@ import androidx.datastore.preferences.SharedPreferencesMigration
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStoreFile
import com.ehviewer.core.mainthread.checkNotMainThread
import splitties.init.appCtx
internal actual fun getDateStore(name: String?): DataStore<Preferences> {
checkNotMainThread()
val context = appCtx
val actualName = name ?: "${context.packageName}_preferences"
return PreferenceDataStoreFactory.create(
+29
View File
@@ -0,0 +1,29 @@
import org.jetbrains.compose.compose
plugins {
alias(libs.plugins.ehviewer.multiplatform.library.compose)
}
kotlin {
sourceSets {
commonMain {
dependencies {
api(projects.core.common)
api(compose.material3)
api(compose.materialIconsExtended)
api(libs.compose.material3.adaptive)
api(libs.androidx.lifecycle.compose)
api(libs.androidx.lifecycle.viewmodel.compose)
implementation(compose("org.jetbrains.compose.ui:ui-backhandler"))
implementation(compose.preview)
}
}
androidMain {
dependencies {
api(project.dependencies.platform(libs.compose.bom))
implementation(libs.androidx.activity.compose)
}
}
}
}
@@ -47,7 +47,7 @@ import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.lerp
import com.hippo.ehviewer.ui.tools.animateFloatMergeOneWayPredictiveBackAsState
import com.ehviewer.core.ui.util.animateFloatMergeOneWayPredictiveBackAsState
import kotlin.math.roundToInt
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.launch
@@ -1,4 +1,4 @@
package com.hippo.ehviewer.ui.tools
package com.ehviewer.core.ui.component
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.material3.FilledIconButton
@@ -1,4 +1,4 @@
package com.hippo.ehviewer.ui.tools
package com.ehviewer.core.ui.component
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -1,4 +1,4 @@
package com.hippo.ehviewer.ui.tools
package com.ehviewer.core.ui.component
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExposedDropdownMenuAnchorType
@@ -1,4 +1,4 @@
package com.hippo.ehviewer.ui.tools
package com.ehviewer.core.ui.component
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.combinedClickable
@@ -1,4 +1,4 @@
package com.hippo.ehviewer.ui.main
package com.ehviewer.core.ui.component
import androidx.activity.compose.PredictiveBackHandler
import androidx.compose.animation.core.Animatable
@@ -35,15 +35,15 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.lerp
import arrow.resilience.Schedule
import arrow.resilience.retry
import com.hippo.ehviewer.ui.tools.PredictiveBackEasing
import com.hippo.ehviewer.ui.tools.asyncState
import com.hippo.ehviewer.ui.tools.snackBarPadding
import com.ehviewer.core.ui.util.PredictiveBackEasing
import com.ehviewer.core.ui.util.asyncState
import com.ehviewer.core.ui.util.snackBarPadding
import com.ehviewer.core.util.launch
import com.ehviewer.core.util.onEachLatest
import kotlin.time.Duration.Companion.microseconds
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import moe.tarsin.coroutines.onEachLatest
import moe.tarsin.launch
@Stable
enum class FabLayoutValue { Hidden, Primary, Expand }
@@ -1,4 +1,4 @@
package com.hippo.ehviewer.ui.tools
package com.ehviewer.core.ui.component
import androidx.compose.foundation.Indication
import androidx.compose.foundation.LocalIndication
@@ -1,4 +1,4 @@
package com.hippo.ehviewer.ui.tools
package com.ehviewer.core.ui.component
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -1,4 +1,4 @@
package com.hippo.ehviewer.ui.tools
package com.ehviewer.core.ui.component
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
@@ -1,4 +1,4 @@
package com.hippo.ehviewer.ui
package com.ehviewer.core.ui.component
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.WindowInsets
@@ -1,4 +1,4 @@
package com.hippo.ehviewer.ui.main
package com.ehviewer.core.ui.component
import androidx.compose.animation.core.animateOffset
import androidx.compose.animation.core.updateTransition
@@ -1,4 +1,4 @@
package com.hippo.ehviewer.ui.tools
package com.ehviewer.core.ui.component
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.material3.Slider
@@ -1,6 +1,5 @@
package com.hippo.ehviewer.ui.tools
package com.ehviewer.core.ui.component
import android.view.ViewConfiguration
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.tween
import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -80,9 +79,10 @@ private val ThumbLength = 48.dp
private val ThumbThickness = 8.dp
private val ThumbShape = RoundedCornerShape(ThumbThickness / 2)
private val FadeOutAnimationSpec = tween<Float>(
durationMillis = ViewConfiguration.getScrollBarFadeDuration(),
durationMillis = SCROLL_BAR_FADE_DURATION,
delayMillis = 2000,
)
private val FadeInAnimationSpec = tween<Float>(
durationMillis = ViewConfiguration.getScrollBarFadeDuration(),
durationMillis = SCROLL_BAR_FADE_DURATION,
)
private const val SCROLL_BAR_FADE_DURATION = 250
@@ -1,6 +1,6 @@
@file:Suppress("ktlint:standard:property-naming")
package com.hippo.ehviewer.icons
package com.ehviewer.core.ui.icons
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
@@ -1,9 +1,9 @@
package com.hippo.ehviewer.icons.big
package com.ehviewer.core.ui.icons.big
import androidx.compose.material.icons.materialPath
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.bigIcon
import com.hippo.ehviewer.util.unsafeLazy
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.bigIcon
import com.ehviewer.core.util.unsafeLazy
val EhIcons.Big.Filled.Download by unsafeLazy {
bigIcon(name = "Download") {
@@ -1,9 +1,9 @@
package com.hippo.ehviewer.icons.big
package com.ehviewer.core.ui.icons.big
import androidx.compose.material.icons.materialPath
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.bigIcon
import com.hippo.ehviewer.util.unsafeLazy
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.bigIcon
import com.ehviewer.core.util.unsafeLazy
val EhIcons.Big.Filled.History by unsafeLazy {
bigIcon(name = "History") {
@@ -1,9 +1,9 @@
package com.hippo.ehviewer.icons.big
package com.ehviewer.core.ui.icons.big
import androidx.compose.material.icons.materialPath
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.bigIcon
import com.hippo.ehviewer.util.unsafeLazy
import com.ehviewer.core.ui.icons.EhIcons
import com.ehviewer.core.ui.icons.bigIcon
import com.ehviewer.core.util.unsafeLazy
val EhIcons.Big.Filled.SadAndroid by unsafeLazy {
bigIcon(name = "SadAndroid") {
Loaded 100 of 127 files, more files were not shown because too many files have changed in this diff. Show more