mirror of
https://github.com/Suwayomi/TachideskJUI.git
synced 2025-12-10 14:52:03 +01:00
Multiple module changes and rewrites
- Strings are now in a separate module - Strings are now using Moko resources - Rename common module to core
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="-PdebugApp" />
|
||||
<option name="scriptParameters" value="-PdebugApp --stacktrace" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
@@ -14,6 +14,7 @@
|
||||
<option value="run" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
|
||||
@@ -2,8 +2,11 @@ plugins {
|
||||
kotlin("multiplatform") version "1.6.10" apply false
|
||||
kotlin("kapt") version "1.6.10" apply false
|
||||
kotlin("plugin.serialization") version "1.6.10" apply false
|
||||
id("com.android.library") version "7.0.4" apply false
|
||||
id("com.android.application") version "7.0.4" apply false
|
||||
id("org.jetbrains.compose") version "1.0.1" apply false
|
||||
id("com.github.gmazzo.buildconfig") version "3.0.3" apply false
|
||||
id("dev.icerock.mobile.multiplatform-resources") version "0.18.0" apply false
|
||||
id("org.jmailen.kotlinter") version "3.8.0" apply false
|
||||
id("com.github.ben-manes.versions") version "0.41.0"
|
||||
}
|
||||
@@ -29,3 +32,36 @@ allprojects {
|
||||
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
plugins.withType<com.android.build.gradle.BasePlugin> {
|
||||
configure<com.android.build.gradle.BaseExtension> {
|
||||
compileSdkVersion(31)
|
||||
defaultConfig {
|
||||
minSdk = 21
|
||||
targetSdk = 31
|
||||
/*versionCode(Config.versionCode)
|
||||
versionName(Config.versionName)
|
||||
ndk {
|
||||
version = Config.ndk
|
||||
}*/
|
||||
}
|
||||
compileOptions {
|
||||
//isCoreLibraryDesugaringEnabled = true
|
||||
sourceCompatibility(JavaVersion.VERSION_11)
|
||||
targetCompatibility(JavaVersion.VERSION_11)
|
||||
}
|
||||
sourceSets {
|
||||
named("main") {
|
||||
val altManifest = file("src/androidMain/AndroidManifest.xml")
|
||||
if (altManifest.exists()) {
|
||||
manifest.srcFile(altManifest.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
//add("coreLibraryDesugaring", Deps.desugarJdkLibs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
91
core/build.gradle.kts
Normal file
91
core/build.gradle.kts
Normal file
@@ -0,0 +1,91 @@
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile as KotlinJvmCompile
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
kotlin("kapt")
|
||||
id("com.android.library")
|
||||
}
|
||||
|
||||
group = "ca.gosyer"
|
||||
version = "1.2.1"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
android()
|
||||
jvm("desktop")
|
||||
|
||||
sourceSets {
|
||||
all {
|
||||
languageSettings {
|
||||
optIn("kotlin.RequiresOptIn")
|
||||
optIn("kotlinx.serialization.ExperimentalSerializationApi")
|
||||
optIn("com.russhwolf.settings.ExperimentalSettingsApi")
|
||||
optIn("com.russhwolf.settings.ExperimentalSettingsImplementation")
|
||||
}
|
||||
}
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
api(kotlin("stdlib-common"))
|
||||
api(libs.coroutinesCore)
|
||||
api(libs.json)
|
||||
api(libs.toothpickKsp)
|
||||
api(libs.ktorCore)
|
||||
api(libs.ktorSerialization)
|
||||
api(libs.okio)
|
||||
api(libs.multiplatformSettingsCore)
|
||||
api(libs.multiplatformSettingsCoroutines)
|
||||
api(libs.multiplatformSettingsSerialization)
|
||||
}
|
||||
}
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-common"))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
}
|
||||
}
|
||||
|
||||
val desktopMain by getting {
|
||||
kotlin.srcDir("src/jvmMain/kotlin")
|
||||
dependencies {
|
||||
api(kotlin("stdlib-jdk8"))
|
||||
}
|
||||
}
|
||||
val desktopTest by getting {
|
||||
kotlin.srcDir("src/jvmTest/kotlin")
|
||||
}
|
||||
|
||||
val androidMain by getting {
|
||||
kotlin.srcDir("src/jvmMain/kotlin")
|
||||
dependencies {
|
||||
api(kotlin("stdlib-jdk8"))
|
||||
}
|
||||
}
|
||||
val androidTest by getting {
|
||||
kotlin.srcDir("src/jvmTest/kotlin")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
add("kapt", libs.toothpickCompiler)
|
||||
}
|
||||
|
||||
tasks {
|
||||
withType<KotlinJvmCompile> {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = listOf("-Xjvm-default=compatibility")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk = 31
|
||||
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
|
||||
defaultConfig {
|
||||
minSdk = 21
|
||||
targetSdk = 31
|
||||
}
|
||||
}
|
||||
2
core/src/androidMain/AndroidManifest.xml
Normal file
2
core/src/androidMain/AndroidManifest.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="ca.gosyer.core"/>
|
||||
@@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.common.prefs
|
||||
package ca.gosyer.core.prefs
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
@@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.common.prefs
|
||||
package ca.gosyer.core.prefs
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.common.prefs
|
||||
package ca.gosyer.core.prefs
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.modules.EmptySerializersModule
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
package ca.gosyer.core.prefs
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import com.russhwolf.settings.ObservableSettings
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
package ca.gosyer.core.prefs
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import com.russhwolf.settings.ObservableSettings
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
package ca.gosyer.core.prefs
|
||||
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import com.russhwolf.settings.JvmPreferencesSettings
|
||||
import java.util.prefs.Preferences
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.common.di
|
||||
package ca.gosyer.core.di
|
||||
|
||||
import toothpick.Scope
|
||||
import toothpick.ktp.KTP
|
||||
@@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.common.di
|
||||
package ca.gosyer.core.di
|
||||
|
||||
import toothpick.Scope
|
||||
import javax.inject.Provider
|
||||
@@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.common.di
|
||||
package ca.gosyer.core.di
|
||||
|
||||
import toothpick.config.Module
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.common.io
|
||||
package ca.gosyer.core.io
|
||||
|
||||
import ca.gosyer.common.util.decodeBase64
|
||||
import ca.gosyer.core.util.decodeBase64
|
||||
import okio.Buffer
|
||||
import okio.Source
|
||||
import okio.Timeout
|
||||
@@ -4,13 +4,14 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.common.io
|
||||
package ca.gosyer.core.io
|
||||
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import okio.BufferedSink
|
||||
import okio.Source
|
||||
import okio.buffer
|
||||
import okio.sink
|
||||
import okio.use
|
||||
import java.nio.file.Path
|
||||
|
||||
suspend fun Source.saveTo(path: Path) {
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.core.lang
|
||||
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@DelicateCoroutinesApi
|
||||
fun launch(
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> Unit
|
||||
) = GlobalScope.launch(Dispatchers.Default, start, block)
|
||||
|
||||
@DelicateCoroutinesApi
|
||||
fun launchUI(
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> Unit
|
||||
) = GlobalScope.launch(Dispatchers.Main, start, block)
|
||||
|
||||
@DelicateCoroutinesApi
|
||||
fun launchIO(
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> Unit
|
||||
) = GlobalScope.launch(Dispatchers.IO, start, block)
|
||||
|
||||
fun CoroutineScope.launchDefault(
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> Unit
|
||||
) = launch(Dispatchers.Default, start, block)
|
||||
|
||||
fun CoroutineScope.launchUI(
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> Unit
|
||||
) = launch(Dispatchers.Main, start, block)
|
||||
|
||||
fun CoroutineScope.launchIO(
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> Unit
|
||||
) = launch(Dispatchers.IO, start, block)
|
||||
|
||||
suspend fun <T> withDefaultContext(
|
||||
block: suspend CoroutineScope.() -> T
|
||||
): T = withContext(Dispatchers.Default, block)
|
||||
|
||||
suspend fun <T> withUIContext(
|
||||
block: suspend CoroutineScope.() -> T
|
||||
): T = withContext(Dispatchers.Main, block)
|
||||
|
||||
suspend fun <T> withIOContext(
|
||||
block: suspend CoroutineScope.() -> T
|
||||
): T = withContext(Dispatchers.IO, block)
|
||||
|
||||
fun Throwable.throwIfCancellation() { if (this is CancellationException) throw this }
|
||||
|
||||
fun <T> Result<T>.throwIfCancellation(): Result<T> {
|
||||
if (isFailure) {
|
||||
val exception = exceptionOrNull()
|
||||
if (exception is CancellationException) throw exception
|
||||
}
|
||||
return this
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.util.lang
|
||||
package ca.gosyer.core.lang
|
||||
|
||||
import java.util.Locale
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.common.util
|
||||
package ca.gosyer.core.util
|
||||
|
||||
import okio.ByteString.Companion.decodeBase64
|
||||
import okio.ByteString.Companion.encode
|
||||
@@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.common.util
|
||||
package ca.gosyer.core.util
|
||||
|
||||
/**
|
||||
* Returns a new list that replaces the item at the given [position] with [newItem].
|
||||
@@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.common.util
|
||||
package ca.gosyer.core.util
|
||||
|
||||
object ImageUtil {
|
||||
|
||||
@@ -8,6 +8,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jmailen.gradle.kotlinter.tasks.FormatTask
|
||||
import org.jmailen.gradle.kotlinter.tasks.LintTask
|
||||
import proguard.gradle.ProGuardTask
|
||||
import java.nio.file.Files
|
||||
import kotlin.streams.asSequence
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
@@ -19,6 +21,9 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":core"))
|
||||
implementation(project(":i18n"))
|
||||
|
||||
// UI (Compose)
|
||||
implementation(compose.desktop.currentOs)
|
||||
implementation(compose.uiTooling)
|
||||
@@ -63,7 +68,8 @@ dependencies {
|
||||
implementation(libs.log4jSlf4j)
|
||||
implementation(libs.ktlogging)
|
||||
|
||||
// User storage
|
||||
// Storage
|
||||
implementation(libs.okio)
|
||||
implementation(libs.appDirs)
|
||||
|
||||
// Preferences
|
||||
@@ -74,6 +80,10 @@ dependencies {
|
||||
// Utility
|
||||
implementation(libs.krokiCoroutines)
|
||||
|
||||
// Localization
|
||||
implementation(libs.mokoCore)
|
||||
implementation(libs.mokoCompose)
|
||||
|
||||
// Testing
|
||||
testImplementation(kotlin("test-junit"))
|
||||
testImplementation(compose("org.jetbrains.compose.ui:ui-test-junit4"))
|
||||
@@ -126,14 +136,13 @@ tasks {
|
||||
registerTachideskTasks(project)
|
||||
|
||||
task("generateResourceConstants") {
|
||||
val buildResources = buildConfig.forClass(project.group.toString()+ ".build", "BuildResources")
|
||||
val buildResources = buildConfig.forClass("${project.group}.build", "BuildResources")
|
||||
|
||||
doFirst {
|
||||
val langs = listOf("en") + sourceSets["main"].resources
|
||||
.filter { it.name == "strings.xml" }
|
||||
.drop(1)
|
||||
.map { it.absolutePath.substringAfter("values-").substringBefore(File.separatorChar) }
|
||||
buildResources.buildConfigField("Array<String>", "LANGUAGES", langs.joinToString(prefix = "arrayOf(", postfix = ")") { it.wrap() })
|
||||
val langs = listOf("en") + Files.list(rootDir.toPath().resolve("i18n/src/commonMain/resources/MR/values")).asSequence()
|
||||
.map { it.fileName.toString().replace("-r", "-") }
|
||||
.toList()
|
||||
buildResources.buildConfigField("ca.gosyer.i18n.StringList", "LANGUAGES", langs.joinToString(prefix = "listOf(", postfix = ")") { it.wrap() })
|
||||
}
|
||||
|
||||
generateBuildConfig {
|
||||
@@ -176,6 +185,8 @@ compose.desktop {
|
||||
mainClass = "ca.gosyer.ui.main.MainKt"
|
||||
nativeDistributions {
|
||||
targetFormats(
|
||||
// All
|
||||
TargetFormat.AppImage,
|
||||
// Windows
|
||||
TargetFormat.Msi,
|
||||
TargetFormat.Exe,
|
||||
@@ -228,7 +239,7 @@ buildConfig {
|
||||
packageName(project.group.toString() + ".build")
|
||||
useKotlinOutput { internalVisibility = true }
|
||||
|
||||
buildConfigField("String", "NAME", project.name.wrap())
|
||||
buildConfigField("String", "NAME", rootProject.name.wrap())
|
||||
buildConfigField("String", "VERSION", project.version.toString().wrap())
|
||||
buildConfigField("int", "MIGRATION_CODE", migrationCode.toString())
|
||||
buildConfigField("boolean", "DEBUG", project.hasProperty("debugApp").toString())
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
package ca.gosyer.core.service
|
||||
|
||||
import ca.gosyer.build.BuildConfig
|
||||
import ca.gosyer.core.lang.throwIfCancellation
|
||||
import ca.gosyer.data.server.Http
|
||||
import ca.gosyer.data.server.ServerPreferences
|
||||
import ca.gosyer.util.lang.throwIfCancellation
|
||||
import ca.gosyer.util.system.CKLogger
|
||||
import io.ktor.client.features.websocket.ws
|
||||
import io.ktor.http.cio.websocket.Frame
|
||||
|
||||
@@ -29,8 +29,6 @@ import ca.gosyer.data.server.interactions.ExtensionInteractionHandler
|
||||
import ca.gosyer.data.server.interactions.LibraryInteractionHandler
|
||||
import ca.gosyer.data.server.interactions.MangaInteractionHandler
|
||||
import ca.gosyer.data.server.interactions.SourceInteractionHandler
|
||||
import ca.gosyer.data.translation.ResourceProvider
|
||||
import ca.gosyer.data.translation.XmlResourceBundle
|
||||
import ca.gosyer.data.ui.UiPreferences
|
||||
import ca.gosyer.data.update.UpdateChecker
|
||||
import ca.gosyer.data.update.UpdatePreferences
|
||||
@@ -85,10 +83,6 @@ val DataModule = module {
|
||||
.toProvider(KamelConfigProvider::class)
|
||||
.providesSingleton()
|
||||
|
||||
bind<XmlResourceBundle>()
|
||||
.toProvider(ResourceProvider::class)
|
||||
.providesSingleton()
|
||||
|
||||
bind<BackupInteractionHandler>()
|
||||
.toClass<BackupInteractionHandler>()
|
||||
bind<CategoryInteractionHandler>()
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
package ca.gosyer.data.catalog
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.core.prefs.PreferenceStore
|
||||
import java.util.Locale
|
||||
|
||||
class CatalogPreferences(private val preferenceStore: PreferenceStore) {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
package ca.gosyer.data.extension
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.core.prefs.PreferenceStore
|
||||
import java.util.Locale
|
||||
|
||||
class ExtensionPreferences(private val preferenceStore: PreferenceStore) {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
package ca.gosyer.data.library
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.core.prefs.PreferenceStore
|
||||
import ca.gosyer.data.library.model.DisplayMode
|
||||
|
||||
class LibraryPreferences(private val preferenceStore: PreferenceStore) {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
package ca.gosyer.data.migration
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.core.prefs.PreferenceStore
|
||||
|
||||
class MigrationPreferences(private val preferenceStore: PreferenceStore) {
|
||||
fun version(): Preference<Int> {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
package ca.gosyer.data.reader
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.core.prefs.PreferenceStore
|
||||
import ca.gosyer.data.reader.model.DefaultReaderMode
|
||||
import ca.gosyer.data.reader.model.Direction
|
||||
import ca.gosyer.data.reader.model.ImageScale
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
package ca.gosyer.data.reader
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.core.prefs.PreferenceStore
|
||||
import ca.gosyer.data.reader.model.DefaultReaderMode
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
@@ -6,12 +6,15 @@
|
||||
|
||||
package ca.gosyer.data.reader.model
|
||||
|
||||
import ca.gosyer.i18n.MR
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
|
||||
@Serializable
|
||||
enum class Direction(val res: String) {
|
||||
Down("dir_down"),
|
||||
Left("dir_rtl"),
|
||||
Right("dir_ltr"),
|
||||
Up("dir_up")
|
||||
enum class Direction(@Transient val res: StringResource) {
|
||||
Down(MR.strings.dir_down),
|
||||
Left(MR.strings.dir_rtl),
|
||||
Right(MR.strings.dir_ltr),
|
||||
Up(MR.strings.dir_up)
|
||||
}
|
||||
|
||||
@@ -6,14 +6,17 @@
|
||||
|
||||
package ca.gosyer.data.reader.model
|
||||
|
||||
import ca.gosyer.i18n.MR
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
|
||||
@Serializable
|
||||
enum class ImageScale(val res: String) {
|
||||
FitScreen("scale_fit_screen"),
|
||||
Stretch("scale_stretch"),
|
||||
FitWidth("scale_fit_width"),
|
||||
FitHeight("scale_fit_height"),
|
||||
OriginalSize("scale_original"),
|
||||
SmartFit("scale_smart"),
|
||||
enum class ImageScale(@Transient val res: StringResource) {
|
||||
FitScreen(MR.strings.scale_fit_screen),
|
||||
Stretch(MR.strings.scale_stretch),
|
||||
FitWidth(MR.strings.scale_fit_width),
|
||||
FitHeight(MR.strings.scale_fit_height),
|
||||
OriginalSize(MR.strings.scale_original),
|
||||
SmartFit(MR.strings.scale_smart),
|
||||
}
|
||||
|
||||
@@ -6,12 +6,15 @@
|
||||
|
||||
package ca.gosyer.data.reader.model
|
||||
|
||||
import ca.gosyer.i18n.MR
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
|
||||
@Serializable
|
||||
enum class NavigationMode(val res: String) {
|
||||
LNavigation("nav_l_shaped"),
|
||||
KindlishNavigation("nav_kindle_ish"),
|
||||
EdgeNavigation("nav_edge"),
|
||||
RightAndLeftNavigation("nav_left_right"),
|
||||
enum class NavigationMode(@Transient val res: StringResource) {
|
||||
LNavigation(MR.strings.nav_l_shaped),
|
||||
KindlishNavigation(MR.strings.nav_kindle_ish),
|
||||
EdgeNavigation(MR.strings.nav_edge),
|
||||
RightAndLeftNavigation(MR.strings.nav_left_right),
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
package ca.gosyer.data.server
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.core.prefs.PreferenceStore
|
||||
import ca.gosyer.data.server.host.ServerHostPreference
|
||||
|
||||
class ServerHostPreferences(preferenceStore: PreferenceStore) {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
package ca.gosyer.data.server
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.core.prefs.PreferenceStore
|
||||
import ca.gosyer.data.server.model.Auth
|
||||
import ca.gosyer.data.server.model.Proxy
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
package ca.gosyer.data.server
|
||||
|
||||
import ca.gosyer.build.BuildConfig
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.util.system.CKLogger
|
||||
import ca.gosyer.util.system.userDataDir
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
package ca.gosyer.data.server
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
package ca.gosyer.data.server.host
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.core.prefs.PreferenceStore
|
||||
|
||||
sealed class ServerHostPreference<T : Any> {
|
||||
protected abstract val propertyName: String
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
package ca.gosyer.data.server.interactions
|
||||
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.data.models.BackupValidationResult
|
||||
import ca.gosyer.data.server.Http
|
||||
import ca.gosyer.data.server.ServerPreferences
|
||||
import ca.gosyer.data.server.requests.backupFileExportRequest
|
||||
import ca.gosyer.data.server.requests.backupFileImportRequest
|
||||
import ca.gosyer.data.server.requests.validateBackupFileRequest
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import io.ktor.client.request.HttpRequestBuilder
|
||||
import io.ktor.client.request.forms.formData
|
||||
import io.ktor.client.request.forms.submitFormWithBinaryData
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
package ca.gosyer.data.server.interactions
|
||||
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.data.models.Category
|
||||
import ca.gosyer.data.models.Manga
|
||||
import ca.gosyer.data.server.Http
|
||||
@@ -19,7 +20,6 @@ import ca.gosyer.data.server.requests.getCategoriesQuery
|
||||
import ca.gosyer.data.server.requests.getMangaCategoriesQuery
|
||||
import ca.gosyer.data.server.requests.getMangaInCategoryQuery
|
||||
import ca.gosyer.data.server.requests.removeMangaFromCategoryRequest
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.forms.submitForm
|
||||
import io.ktor.client.request.get
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
package ca.gosyer.data.server.interactions
|
||||
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.data.models.Chapter
|
||||
import ca.gosyer.data.models.Manga
|
||||
import ca.gosyer.data.server.Http
|
||||
@@ -19,7 +20,6 @@ import ca.gosyer.data.server.requests.stopDownloadingChapterRequest
|
||||
import ca.gosyer.data.server.requests.updateChapterMetaRequest
|
||||
import ca.gosyer.data.server.requests.updateChapterRequest
|
||||
import ca.gosyer.util.compose.imageFromUrl
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import io.ktor.client.request.HttpRequestBuilder
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.forms.submitForm
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
package ca.gosyer.data.server.interactions
|
||||
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.data.server.Http
|
||||
import ca.gosyer.data.server.ServerPreferences
|
||||
import ca.gosyer.data.server.requests.downloadsClearRequest
|
||||
import ca.gosyer.data.server.requests.downloadsStartRequest
|
||||
import ca.gosyer.data.server.requests.downloadsStopRequest
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
package ca.gosyer.data.server.interactions
|
||||
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.data.models.Extension
|
||||
import ca.gosyer.data.server.Http
|
||||
import ca.gosyer.data.server.ServerPreferences
|
||||
@@ -15,7 +16,6 @@ import ca.gosyer.data.server.requests.apkUninstallQuery
|
||||
import ca.gosyer.data.server.requests.apkUpdateQuery
|
||||
import ca.gosyer.data.server.requests.extensionListQuery
|
||||
import ca.gosyer.util.compose.imageFromUrl
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import io.ktor.client.request.HttpRequestBuilder
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
package ca.gosyer.data.server.interactions
|
||||
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.data.models.Manga
|
||||
import ca.gosyer.data.server.Http
|
||||
import ca.gosyer.data.server.ServerPreferences
|
||||
import ca.gosyer.data.server.requests.addMangaToLibraryQuery
|
||||
import ca.gosyer.data.server.requests.removeMangaFromLibraryRequest
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
package ca.gosyer.data.server.interactions
|
||||
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.data.models.Manga
|
||||
import ca.gosyer.data.server.Http
|
||||
import ca.gosyer.data.server.ServerPreferences
|
||||
@@ -13,7 +14,6 @@ import ca.gosyer.data.server.requests.mangaQuery
|
||||
import ca.gosyer.data.server.requests.mangaThumbnailQuery
|
||||
import ca.gosyer.data.server.requests.updateMangaMetaRequest
|
||||
import ca.gosyer.util.compose.imageFromUrl
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import io.ktor.client.request.HttpRequestBuilder
|
||||
import io.ktor.client.request.forms.submitForm
|
||||
import io.ktor.client.request.get
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
package ca.gosyer.data.server.interactions
|
||||
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.data.models.MangaPage
|
||||
import ca.gosyer.data.models.Source
|
||||
import ca.gosyer.data.models.sourcefilters.SourceFilter
|
||||
@@ -24,7 +25,6 @@ import ca.gosyer.data.server.requests.sourceListQuery
|
||||
import ca.gosyer.data.server.requests.sourcePopularQuery
|
||||
import ca.gosyer.data.server.requests.sourceSearchQuery
|
||||
import ca.gosyer.data.server.requests.updateSourceSettingQuery
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.parameter
|
||||
import io.ktor.client.request.post
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
package ca.gosyer.data.server.interactions
|
||||
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.data.models.Category
|
||||
import ca.gosyer.data.models.Updates
|
||||
import ca.gosyer.data.server.Http
|
||||
import ca.gosyer.data.server.ServerPreferences
|
||||
import ca.gosyer.data.server.requests.fetchUpdatesRequest
|
||||
import ca.gosyer.data.server.requests.recentUpdatesQuery
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import io.ktor.client.request.forms.submitForm
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.post
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.data.translation
|
||||
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
||||
class ResourceProvider @Inject constructor() : Provider<XmlResourceBundle> {
|
||||
override fun get(): XmlResourceBundle {
|
||||
return XmlResourceBundle.forLocale(Locale.getDefault())
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.data.translation
|
||||
|
||||
import ca.gosyer.data.translation.xml.Resources
|
||||
import nl.adaptivity.xmlutil.StAXReader
|
||||
import nl.adaptivity.xmlutil.serialization.XML
|
||||
import java.io.InputStream
|
||||
import java.io.Reader
|
||||
import java.nio.charset.Charset
|
||||
import java.util.Collections
|
||||
import java.util.Enumeration
|
||||
import java.util.Formatter
|
||||
import java.util.Locale
|
||||
import java.util.ResourceBundle
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class XmlResourceBundle internal constructor(internal val lookup: ConcurrentHashMap<String, Any>) : ResourceBundle() {
|
||||
|
||||
constructor(stream: InputStream, charset: Charset = Charsets.UTF_8) : this(
|
||||
stream.reader(charset)
|
||||
)
|
||||
|
||||
constructor(reader: Reader) : this(
|
||||
ConcurrentHashMap(
|
||||
format.decodeFromReader<Resources>(
|
||||
StAXReader(reader)
|
||||
).values.associate { it.name to it.value }
|
||||
)
|
||||
)
|
||||
|
||||
public override fun handleGetObject(key: String): Any? {
|
||||
return lookup[key]
|
||||
}
|
||||
|
||||
override fun getKeys(): Enumeration<String> {
|
||||
return Collections.enumeration(keySet())
|
||||
}
|
||||
|
||||
override fun handleKeySet(): Set<String> {
|
||||
return lookup.keys
|
||||
}
|
||||
|
||||
operator fun plus(other: XmlResourceBundle): XmlResourceBundle {
|
||||
return XmlResourceBundle(ConcurrentHashMap(lookup + other.lookup))
|
||||
}
|
||||
|
||||
private fun String.replaceAndroid() = replace("\\n", "%n")
|
||||
|
||||
fun getStringA(key: String): String {
|
||||
return Formatter().use {
|
||||
it.format(getString(key).replaceAndroid())
|
||||
.toString()
|
||||
}
|
||||
}
|
||||
|
||||
fun getString(key: String, vararg replacements: Any?): String {
|
||||
return Formatter().use {
|
||||
it.format(getString(key).replaceAndroid(), *replacements)
|
||||
.toString()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val format by lazy {
|
||||
XML {
|
||||
autoPolymorphic = true
|
||||
indentString = "\t"
|
||||
}
|
||||
}
|
||||
|
||||
fun forLocale(locale: Locale): XmlResourceBundle {
|
||||
val classLoader = this::class.java.classLoader
|
||||
val rootBundle = classLoader.getResourceAsStream("values/values/strings.xml")!!
|
||||
.use { XmlResourceBundle(it) }
|
||||
|
||||
val languageBundle = classLoader.getResourceAsStream("values/values-${locale.toLanguageTag()}/strings.xml")
|
||||
?.use { XmlResourceBundle(it) }
|
||||
|
||||
return if (languageBundle != null) {
|
||||
rootBundle + languageBundle
|
||||
} else {
|
||||
rootBundle
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.data.translation.xml
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import nl.adaptivity.xmlutil.serialization.XmlSerialName
|
||||
|
||||
@Serializable
|
||||
@XmlSerialName("resources", "", "")
|
||||
data class Resources(val values: List<XmlString>)
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.data.translation.xml
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import nl.adaptivity.xmlutil.serialization.XmlElement
|
||||
import nl.adaptivity.xmlutil.serialization.XmlSerialName
|
||||
import nl.adaptivity.xmlutil.serialization.XmlValue
|
||||
|
||||
@Serializable
|
||||
@XmlSerialName("string", "", "")
|
||||
data class XmlString(
|
||||
@XmlElement(false)
|
||||
val name: String,
|
||||
@XmlValue(true)
|
||||
val value: String
|
||||
)
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
package ca.gosyer.data.ui
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.core.prefs.PreferenceStore
|
||||
import ca.gosyer.data.ui.model.StartScreen
|
||||
import ca.gosyer.data.ui.model.ThemeMode
|
||||
import ca.gosyer.data.ui.model.WindowSettings
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
package ca.gosyer.data.update
|
||||
|
||||
import ca.gosyer.build.BuildConfig
|
||||
import ca.gosyer.core.lang.launch
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.data.server.Http
|
||||
import ca.gosyer.data.update.model.GithubRelease
|
||||
import ca.gosyer.util.lang.launch
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import io.ktor.client.request.get
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
package ca.gosyer.data.update
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.common.prefs.PreferenceStore
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.core.prefs.PreferenceStore
|
||||
|
||||
class UpdatePreferences(private val preferenceStore: PreferenceStore) {
|
||||
fun enabled(): Preference<Boolean> {
|
||||
|
||||
@@ -35,9 +35,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.WindowPosition
|
||||
import androidx.compose.ui.window.rememberWindowState
|
||||
import ca.gosyer.common.di.AppScope
|
||||
import ca.gosyer.data.translation.XmlResourceBundle
|
||||
import ca.gosyer.ui.base.resources.LocalResources
|
||||
import ca.gosyer.core.di.AppScope
|
||||
import ca.gosyer.ui.base.theme.AppTheme
|
||||
import ca.gosyer.util.lang.launchApplication
|
||||
import io.kamel.core.config.KamelConfig
|
||||
@@ -71,7 +69,6 @@ fun WindowDialog(
|
||||
}
|
||||
|
||||
val icon = painterResource("icon.png")
|
||||
val resources = remember { AppScope.getInstance<XmlResourceBundle>() }
|
||||
val kamelConfig = remember { AppScope.getInstance<KamelConfig>() }
|
||||
val windowState = rememberWindowState(size = size, position = WindowPosition(Alignment.Center))
|
||||
|
||||
@@ -99,7 +96,6 @@ fun WindowDialog(
|
||||
alwaysOnTop = forceFocus
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
LocalResources provides resources,
|
||||
LocalKamelConfig provides kamelConfig
|
||||
) {
|
||||
AppTheme {
|
||||
@@ -149,7 +145,6 @@ fun WindowDialog(
|
||||
}
|
||||
|
||||
val icon = painterResource("icon.png")
|
||||
val resources = remember { AppScope.getInstance<XmlResourceBundle>() }
|
||||
val kamelConfig = remember { AppScope.getInstance<KamelConfig>() }
|
||||
val windowState = rememberWindowState(size = size, position = WindowPosition.Aligned(Alignment.Center))
|
||||
|
||||
@@ -169,7 +164,6 @@ fun WindowDialog(
|
||||
alwaysOnTop = forceFocus,
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
LocalResources provides resources,
|
||||
LocalKamelConfig provides kamelConfig
|
||||
) {
|
||||
AppTheme {
|
||||
|
||||
@@ -37,7 +37,8 @@ import ca.gosyer.data.download.model.DownloadState
|
||||
import ca.gosyer.data.models.Chapter
|
||||
import ca.gosyer.data.models.Manga
|
||||
import ca.gosyer.data.server.interactions.ChapterInteractionHandler
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
@@ -143,7 +144,7 @@ private fun DownloadingIconButton(downloadChapter: DownloadChapter?, onClick: ()
|
||||
downloadChapter?.mangaId to downloadChapter?.chapterIndex,
|
||||
{
|
||||
DropdownMenuItem(onClick = onClick) {
|
||||
Text(stringResource("action_cancel"))
|
||||
Text(stringResource(MR.strings.action_cancel))
|
||||
}
|
||||
}
|
||||
) {
|
||||
@@ -215,7 +216,7 @@ private fun DownloadedIconButton(chapter: Pair<Long, Int?>, onClick: () -> Unit)
|
||||
chapter,
|
||||
{
|
||||
DropdownMenuItem(onClick = onClick) {
|
||||
Text(stringResource("action_delete"))
|
||||
Text(stringResource(MR.strings.action_delete))
|
||||
}
|
||||
}
|
||||
) {
|
||||
|
||||
@@ -15,7 +15,8 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
|
||||
@Composable
|
||||
fun LoadingScreen(
|
||||
@@ -24,7 +25,7 @@ fun LoadingScreen(
|
||||
/*@FloatRange(from = 0.0, to = 1.0)*/
|
||||
progress: Float = 0.0F,
|
||||
errorMessage: String? = null,
|
||||
retryMessage: String = stringResource("action_retry"),
|
||||
retryMessage: String = stringResource(MR.strings.action_retry),
|
||||
retry: (() -> Unit)? = null
|
||||
) {
|
||||
BoxWithConstraints(modifier) {
|
||||
|
||||
@@ -63,7 +63,8 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
|
||||
@Composable
|
||||
fun Toolbar(
|
||||
@@ -120,7 +121,7 @@ fun Toolbar(
|
||||
Row {
|
||||
actions()
|
||||
if (closable) {
|
||||
TextActionIcon(onClick = onClose, stringResource("action_close"), Icons.Rounded.Close)
|
||||
TextActionIcon(onClick = onClose, stringResource(MR.strings.action_close), Icons.Rounded.Close)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ package ca.gosyer.ui.base.prefs
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
package ca.gosyer.ui.base.prefs
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
package ca.gosyer.ui.base.prefs
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ca.gosyer.ui.base.resources
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ProvidableCompositionLocal
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import ca.gosyer.data.translation.XmlResourceBundle
|
||||
|
||||
val LocalResources: ProvidableCompositionLocal<XmlResourceBundle> =
|
||||
compositionLocalOf { throw IllegalStateException("resources have not been not initialized") }
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
fun stringResource(key: String): String {
|
||||
val resources = LocalResources.current
|
||||
return resources.getStringA(key)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
fun stringResource(key: String, vararg replacements: Any): String {
|
||||
val resources = LocalResources.current
|
||||
return resources.getString(key, *replacements)
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package dev.icerock.moko.resources.compose
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.icerock.moko.resources.PluralsResource
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import dev.icerock.moko.resources.desc.Plural
|
||||
import dev.icerock.moko.resources.desc.PluralFormatted
|
||||
import dev.icerock.moko.resources.desc.Resource
|
||||
import dev.icerock.moko.resources.desc.ResourceFormatted
|
||||
import dev.icerock.moko.resources.desc.StringDesc
|
||||
|
||||
@Composable
|
||||
fun stringResource(resource: StringResource): String =
|
||||
StringDesc.Resource(resource).localized()
|
||||
|
||||
@Composable
|
||||
fun stringResource(resource: StringResource, vararg args: Any): String =
|
||||
StringDesc.ResourceFormatted(resource, *args).localized()
|
||||
|
||||
@Composable
|
||||
fun stringResource(resource: PluralsResource, quantity: Int): String =
|
||||
StringDesc.Plural(resource, quantity).localized()
|
||||
|
||||
@Composable
|
||||
fun stringResource(resource: PluralsResource, quantity: Int, vararg args: Any): String =
|
||||
StringDesc.PluralFormatted(resource, quantity, *args).localized()
|
||||
@@ -7,7 +7,7 @@
|
||||
package ca.gosyer.ui.base.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.data.ui.UiPreferences
|
||||
import ca.gosyer.ui.base.prefs.PreferenceMutableStateFlow
|
||||
import ca.gosyer.ui.base.prefs.asColor
|
||||
|
||||
@@ -10,7 +10,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisallowComposableCalls
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import ca.gosyer.common.di.AppScope
|
||||
import ca.gosyer.core.di.AppScope
|
||||
import toothpick.Toothpick
|
||||
import toothpick.ktp.binding.module
|
||||
import toothpick.ktp.extension.getInstance
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
package ca.gosyer.ui.base.vm
|
||||
|
||||
import ca.gosyer.common.prefs.Preference
|
||||
import ca.gosyer.core.prefs.Preference
|
||||
import ca.gosyer.ui.base.prefs.PreferenceMutableStateFlow
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.cancel
|
||||
|
||||
@@ -12,8 +12,9 @@ import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import ca.gosyer.build.BuildConfig
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.WindowDialog
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
fun openRenameDialog(
|
||||
@@ -54,7 +55,7 @@ fun openDeleteDialog(
|
||||
},
|
||||
negativeButtonText = "No"
|
||||
) {
|
||||
Text(stringResource("categories_delete_confirm", category.name))
|
||||
Text(stringResource(MR.strings.categories_delete_confirm, category.name))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.build.BuildConfig
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.util.compose.ThemedWindow
|
||||
import ca.gosyer.util.lang.launchApplication
|
||||
@@ -114,7 +115,7 @@ fun CategoriesMenu(notifyFinished: (() -> Unit)? = null) {
|
||||
}
|
||||
}
|
||||
ExtendedFloatingActionButton(
|
||||
text = { Text(text = stringResource("action_add")) },
|
||||
text = { Text(text = stringResource(MR.strings.action_add)) },
|
||||
icon = { Icon(imageVector = Icons.Rounded.Add, contentDescription = null) },
|
||||
modifier = Modifier.align(Alignment.BottomEnd).padding(16.dp),
|
||||
onClick = {
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
package ca.gosyer.ui.categories
|
||||
|
||||
import ca.gosyer.core.lang.throwIfCancellation
|
||||
import ca.gosyer.data.models.Category
|
||||
import ca.gosyer.data.server.interactions.CategoryInteractionHandler
|
||||
import ca.gosyer.ui.base.vm.ViewModel
|
||||
import ca.gosyer.util.lang.throwIfCancellation
|
||||
import ca.gosyer.util.system.CKLogger
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
@@ -57,7 +57,8 @@ import ca.gosyer.ui.base.components.MangaListItemSubtitle
|
||||
import ca.gosyer.ui.base.components.MangaListItemTitle
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.components.mangaAspectRatio
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.ui.manga.openMangaMenu
|
||||
import ca.gosyer.util.compose.ThemedWindow
|
||||
@@ -83,16 +84,16 @@ fun DownloadsMenu(onMangaClick: (Long) -> Unit) {
|
||||
|
||||
Column {
|
||||
Toolbar(
|
||||
stringResource("location_downloads"),
|
||||
stringResource(MR.strings.location_downloads),
|
||||
closable = false,
|
||||
actions = {
|
||||
val downloadStatus by vm.downloaderStatus.collectAsState()
|
||||
if (downloadStatus == DownloaderStatus.Started) {
|
||||
ActionIcon(onClick = vm::pause, stringResource("action_pause"), Icons.Rounded.Pause)
|
||||
ActionIcon(onClick = vm::pause, stringResource(MR.strings.action_pause), Icons.Rounded.Pause)
|
||||
} else {
|
||||
ActionIcon(onClick = vm::start, stringResource("action_continue"), Icons.Rounded.PlayArrow)
|
||||
ActionIcon(onClick = vm::start, stringResource(MR.strings.action_continue), Icons.Rounded.PlayArrow)
|
||||
}
|
||||
ActionIcon(onClick = vm::clear, stringResource("action_clear_queue"), Icons.Rounded.ClearAll)
|
||||
ActionIcon(onClick = vm::clear, stringResource(MR.strings.action_clear_queue), Icons.Rounded.ClearAll)
|
||||
}
|
||||
)
|
||||
Box {
|
||||
@@ -170,10 +171,10 @@ fun DownloadsItem(
|
||||
item.mangaId to item.chapterIndex,
|
||||
{
|
||||
DropdownMenuItem(onClick = { onClickCancel(item.chapter) }) {
|
||||
Text(stringResource("action_cancel"))
|
||||
Text(stringResource(MR.strings.action_cancel))
|
||||
}
|
||||
DropdownMenuItem(onClick = { onClickMoveToBottom(item.chapter) }) {
|
||||
Text(stringResource("action_move_to_bottom"))
|
||||
Text(stringResource(MR.strings.action_move_to_bottom))
|
||||
}
|
||||
}
|
||||
) {
|
||||
|
||||
@@ -53,7 +53,8 @@ import ca.gosyer.ui.base.components.KamelImage
|
||||
import ca.gosyer.ui.base.components.LoadingScreen
|
||||
import ca.gosyer.ui.base.components.TextActionIcon
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.util.compose.ThemedWindow
|
||||
import ca.gosyer.util.compose.persistentLazyListState
|
||||
@@ -146,7 +147,7 @@ fun ExtensionsToolbar(
|
||||
setEnabledLanguages: (Set<String>) -> Unit
|
||||
) {
|
||||
Toolbar(
|
||||
stringResource("location_extensions"),
|
||||
stringResource(MR.strings.location_extensions),
|
||||
closable = false,
|
||||
searchText = searchText,
|
||||
search = search,
|
||||
@@ -158,7 +159,7 @@ fun ExtensionsToolbar(
|
||||
setEnabledLanguages(enabledLangs.value)
|
||||
}
|
||||
},
|
||||
stringResource("enabled_languages"),
|
||||
stringResource(MR.strings.enabled_languages),
|
||||
Icons.Rounded.Translate
|
||||
)
|
||||
}
|
||||
@@ -209,9 +210,9 @@ fun ExtensionItem(
|
||||
) {
|
||||
Text(
|
||||
when {
|
||||
extension.hasUpdate -> stringResource("action_update")
|
||||
extension.installed -> stringResource("action_uninstall")
|
||||
else -> stringResource("action_install")
|
||||
extension.hasUpdate -> stringResource(MR.strings.action_update)
|
||||
extension.installed -> stringResource(MR.strings.action_uninstall)
|
||||
else -> stringResource(MR.strings.action_install)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
package ca.gosyer.ui.extensions
|
||||
|
||||
import ca.gosyer.core.lang.throwIfCancellation
|
||||
import ca.gosyer.data.extension.ExtensionPreferences
|
||||
import ca.gosyer.data.models.Extension
|
||||
import ca.gosyer.data.server.interactions.ExtensionInteractionHandler
|
||||
import ca.gosyer.data.translation.XmlResourceBundle
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.vm.ViewModel
|
||||
import ca.gosyer.util.lang.throwIfCancellation
|
||||
import ca.gosyer.util.system.CKLogger
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
@@ -24,7 +24,6 @@ import javax.inject.Inject
|
||||
|
||||
class ExtensionsMenuViewModel @Inject constructor(
|
||||
private val extensionHandler: ExtensionInteractionHandler,
|
||||
private val resources: XmlResourceBundle,
|
||||
extensionPreferences: ExtensionPreferences
|
||||
) : ViewModel() {
|
||||
private val _enabledLangs = extensionPreferences.languages().asStateFlow()
|
||||
@@ -129,10 +128,10 @@ class ExtensionsMenuViewModel @Inject constructor(
|
||||
val available = filter { !it.installed }.sortedWith(comparator)
|
||||
|
||||
return mapOf(
|
||||
resources.getStringA("installed") to (obsolete + updates + installed),
|
||||
MR.strings.installed.localized() to (obsolete + updates + installed),
|
||||
).filterNot { it.value.isEmpty() } + available.groupBy { it.lang }.mapKeys {
|
||||
if (it.key == "all") {
|
||||
resources.getStringA("all")
|
||||
MR.strings.all.localized()
|
||||
} else {
|
||||
Locale.forLanguageTag(it.key).displayName
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ import ca.gosyer.data.models.Category
|
||||
import ca.gosyer.data.models.Manga
|
||||
import ca.gosyer.ui.base.components.LoadingScreen
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.ui.manga.openMangaMenu
|
||||
import ca.gosyer.util.compose.ThemedWindow
|
||||
@@ -100,7 +101,7 @@ fun LibraryScreen(bundle: Bundle, onClickManga: (Long) -> Unit = ::openMangaMenu
|
||||
}
|
||||
)*/
|
||||
Toolbar(
|
||||
stringResource("location_library"),
|
||||
stringResource(MR.strings.location_library),
|
||||
closable = false,
|
||||
searchText = query,
|
||||
search = vm::updateQuery
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
package ca.gosyer.ui.library
|
||||
|
||||
import ca.gosyer.core.lang.throwIfCancellation
|
||||
import ca.gosyer.core.lang.withDefaultContext
|
||||
import ca.gosyer.data.library.LibraryPreferences
|
||||
import ca.gosyer.data.models.Category
|
||||
import ca.gosyer.data.models.Manga
|
||||
@@ -15,8 +17,6 @@ import ca.gosyer.data.server.interactions.UpdatesInteractionHandler
|
||||
import ca.gosyer.ui.base.vm.ViewModel
|
||||
import ca.gosyer.util.compose.saveIntInBundle
|
||||
import ca.gosyer.util.compose.saveStringInBundle
|
||||
import ca.gosyer.util.lang.throwIfCancellation
|
||||
import ca.gosyer.util.lang.withDefaultContext
|
||||
import com.github.zsoltk.compose.savedinstancestate.Bundle
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
|
||||
@@ -21,14 +21,16 @@ import androidx.compose.material.icons.rounded.Settings
|
||||
import androidx.compose.material.icons.rounded.Store
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.extensions.openExtensionsMenu
|
||||
import ca.gosyer.ui.library.openLibraryMenu
|
||||
import ca.gosyer.ui.main.components.DownloadsExtraInfo
|
||||
import ca.gosyer.ui.sources.openSourcesMenu
|
||||
import com.github.zsoltk.compose.router.BackStack
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
|
||||
enum class TopLevelMenus(
|
||||
val textKey: String,
|
||||
val textKey: StringResource,
|
||||
val unselectedIcon: ImageVector,
|
||||
val selectedIcon: ImageVector,
|
||||
val menu: Routes,
|
||||
@@ -36,12 +38,12 @@ enum class TopLevelMenus(
|
||||
val openInNewWindow: () -> Unit = {},
|
||||
val extraInfo: (@Composable () -> Unit)? = null
|
||||
) {
|
||||
Library("location_library", Icons.Outlined.Book, Icons.Rounded.Book, Routes.Library, true, ::openLibraryMenu),
|
||||
Updates("location_updates", Icons.Outlined.NewReleases, Icons.Rounded.NewReleases, Routes.Updates, true, ::openLibraryMenu),
|
||||
Sources("location_sources", Icons.Outlined.Explore, Icons.Rounded.Explore, Routes.Sources, true, ::openSourcesMenu),
|
||||
Extensions("location_extensions", Icons.Outlined.Store, Icons.Rounded.Store, Routes.Extensions, true, ::openExtensionsMenu),
|
||||
Downloads("location_downloads", Icons.Outlined.Download, Icons.Rounded.Download, Routes.Downloads, false, extraInfo = { DownloadsExtraInfo() }),
|
||||
Settings("location_settings", Icons.Outlined.Settings, Icons.Rounded.Settings, Routes.Settings, false);
|
||||
Library(MR.strings.location_library, Icons.Outlined.Book, Icons.Rounded.Book, Routes.Library, true, ::openLibraryMenu),
|
||||
Updates(MR.strings.location_updates, Icons.Outlined.NewReleases, Icons.Rounded.NewReleases, Routes.Updates, true, ::openLibraryMenu),
|
||||
Sources(MR.strings.location_sources, Icons.Outlined.Explore, Icons.Rounded.Explore, Routes.Sources, true, ::openSourcesMenu),
|
||||
Extensions(MR.strings.location_extensions, Icons.Outlined.Store, Icons.Rounded.Store, Routes.Extensions, true, ::openExtensionsMenu),
|
||||
Downloads(MR.strings.location_downloads, Icons.Outlined.Download, Icons.Rounded.Download, Routes.Downloads, false, extraInfo = { DownloadsExtraInfo() }),
|
||||
Settings(MR.strings.location_settings, Icons.Outlined.Settings, Icons.Rounded.Settings, Routes.Settings, false);
|
||||
|
||||
fun isSelected(backStack: BackStack<Routes>) = backStack.elements.first() == menu
|
||||
}
|
||||
|
||||
@@ -18,9 +18,10 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.core.service.WebsocketService
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.ui.downloads.DownloadsMenuViewModel
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
|
||||
@Composable
|
||||
fun DownloadsExtraInfo() {
|
||||
@@ -28,10 +29,10 @@ fun DownloadsExtraInfo() {
|
||||
val status by vm.serviceStatus.collectAsState()
|
||||
val list by vm.downloadQueue.collectAsState()
|
||||
val text = when (status) {
|
||||
WebsocketService.Status.STARTING -> stringResource("downloads_loading")
|
||||
WebsocketService.Status.STARTING -> stringResource(MR.strings.downloads_loading)
|
||||
WebsocketService.Status.RUNNING -> {
|
||||
if (list.isNotEmpty()) {
|
||||
stringResource("downloads_remaining", list.size)
|
||||
stringResource(MR.strings.downloads_remaining, list.size)
|
||||
} else null
|
||||
}
|
||||
WebsocketService.Status.STOPPED -> null
|
||||
@@ -45,7 +46,7 @@ fun DownloadsExtraInfo() {
|
||||
} else if (status == WebsocketService.Status.STOPPED) {
|
||||
Surface(onClick = vm::restartDownloader, shape = RoundedCornerShape(4.dp)) {
|
||||
Text(
|
||||
stringResource("downloads_stopped"),
|
||||
stringResource(MR.strings.downloads_stopped),
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = Color.Red.copy(alpha = ContentAlpha.disabled)
|
||||
)
|
||||
|
||||
@@ -26,7 +26,8 @@ import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.ui.base.components.combinedMouseClickable
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.main.Routes
|
||||
import ca.gosyer.ui.main.TopLevelMenus
|
||||
|
||||
|
||||
@@ -14,12 +14,13 @@ import androidx.compose.ui.window.Notification
|
||||
import androidx.compose.ui.window.Tray
|
||||
import androidx.compose.ui.window.rememberTrayState
|
||||
import ca.gosyer.build.BuildConfig
|
||||
import ca.gosyer.data.translation.XmlResourceBundle
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Locale
|
||||
|
||||
@Composable
|
||||
fun ApplicationScope.Tray(icon: Painter, resources: XmlResourceBundle) {
|
||||
fun ApplicationScope.Tray(icon: Painter) {
|
||||
val vm = viewModel<TrayViewModel>()
|
||||
val trayState = rememberTrayState()
|
||||
Tray(
|
||||
@@ -27,7 +28,7 @@ fun ApplicationScope.Tray(icon: Painter, resources: XmlResourceBundle) {
|
||||
trayState,
|
||||
tooltip = BuildConfig.NAME,
|
||||
menu = {
|
||||
Item(resources.getStringA("action_close"), onClick = ::exitApplication)
|
||||
Item(MR.strings.action_close.localized(), onClick = ::exitApplication)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -36,8 +37,8 @@ fun ApplicationScope.Tray(icon: Painter, resources: XmlResourceBundle) {
|
||||
vm.updateFound.collect {
|
||||
trayState.sendNotification(
|
||||
Notification(
|
||||
resources.getStringA("new_update_title"),
|
||||
resources.getString("new_update_message", it.version),
|
||||
MR.strings.new_update_title.localized(),
|
||||
MR.strings.new_update_message.localized(Locale.getDefault(), it.version),
|
||||
Notification.Type.Info
|
||||
)
|
||||
)
|
||||
|
||||
@@ -25,22 +25,20 @@ import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.awaitApplication
|
||||
import androidx.compose.ui.window.rememberWindowState
|
||||
import ca.gosyer.build.BuildConfig
|
||||
import ca.gosyer.core.lang.withUIContext
|
||||
import ca.gosyer.core.logging.initializeLogger
|
||||
import ca.gosyer.data.DataModule
|
||||
import ca.gosyer.data.migration.Migrations
|
||||
import ca.gosyer.data.server.ServerService
|
||||
import ca.gosyer.data.server.ServerService.ServerResult
|
||||
import ca.gosyer.data.translation.XmlResourceBundle
|
||||
import ca.gosyer.data.ui.UiPreferences
|
||||
import ca.gosyer.data.ui.model.ThemeMode
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.WindowDialog
|
||||
import ca.gosyer.ui.base.components.LoadingScreen
|
||||
import ca.gosyer.ui.base.prefs.asStateIn
|
||||
import ca.gosyer.ui.base.resources.LocalResources
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import ca.gosyer.ui.base.theme.AppTheme
|
||||
import ca.gosyer.ui.main.components.Tray
|
||||
import ca.gosyer.util.lang.withUIContext
|
||||
import ca.gosyer.util.system.getAsFlow
|
||||
import ca.gosyer.util.system.userDataDir
|
||||
import com.github.weisj.darklaf.LafManager
|
||||
@@ -49,6 +47,7 @@ import com.github.weisj.darklaf.theme.IntelliJTheme
|
||||
import com.github.zsoltk.compose.backpress.BackPressHandler
|
||||
import com.github.zsoltk.compose.backpress.LocalBackPressHandler
|
||||
import com.github.zsoltk.compose.savedinstancestate.Bundle
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import io.kamel.core.config.KamelConfig
|
||||
import io.kamel.image.config.LocalKamelConfig
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
@@ -98,7 +97,6 @@ suspend fun main() {
|
||||
}
|
||||
}
|
||||
|
||||
val resources = scope.getInstance<XmlResourceBundle>()
|
||||
val kamelConfig = scope.getInstance<KamelConfig>()
|
||||
|
||||
// Set the Compose constants before any
|
||||
@@ -154,16 +152,16 @@ suspend fun main() {
|
||||
|
||||
val icon = painterResource("icon.png")
|
||||
|
||||
Tray(icon, resources)
|
||||
Tray(icon)
|
||||
|
||||
Window(
|
||||
onCloseRequest = {
|
||||
if (confirmExit.value) {
|
||||
WindowDialog(
|
||||
title = resources.getStringA("confirm_exit"),
|
||||
title = MR.strings.confirm_exit.localized(),
|
||||
onPositiveButton = ::exitApplication
|
||||
) {
|
||||
Text(stringResource("confirm_exit_message"))
|
||||
Text(stringResource(MR.strings.confirm_exit_message))
|
||||
}
|
||||
} else {
|
||||
exitApplication()
|
||||
@@ -190,7 +188,6 @@ suspend fun main() {
|
||||
AppTheme {
|
||||
CompositionLocalProvider(
|
||||
LocalBackPressHandler provides backPressHandler,
|
||||
LocalResources provides resources,
|
||||
LocalKamelConfig provides kamelConfig
|
||||
) {
|
||||
Crossfade(serverService.initialized.collectAsState().value) { initialized ->
|
||||
@@ -208,8 +205,8 @@ suspend fun main() {
|
||||
Surface {
|
||||
LoadingScreen(
|
||||
initialized == ServerResult.STARTING,
|
||||
errorMessage = stringResource("unable_to_start_server"),
|
||||
retryMessage = stringResource("action_start_anyway"),
|
||||
errorMessage = stringResource(MR.strings.unable_to_start_server),
|
||||
retryMessage = stringResource(MR.strings.action_start_anyway),
|
||||
retry = serverService::startAnyway
|
||||
)
|
||||
}
|
||||
|
||||
@@ -29,10 +29,11 @@ import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.components.ChapterDownloadIcon
|
||||
import ca.gosyer.ui.base.components.ChapterDownloadItem
|
||||
import ca.gosyer.ui.base.components.contextMenuClickable
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import java.time.Instant
|
||||
|
||||
@Composable
|
||||
@@ -90,7 +91,7 @@ fun ChapterItem(
|
||||
if (length > 0) append(" • ")
|
||||
append(
|
||||
AnnotatedString(
|
||||
stringResource("page_progress", (chapter.lastPageRead + 1)),
|
||||
stringResource(MR.strings.page_progress, (chapter.lastPageRead + 1)),
|
||||
SpanStyle(color = LocalContentColor.current.copy(alpha = ContentAlpha.disabled))
|
||||
)
|
||||
)
|
||||
|
||||
@@ -51,6 +51,7 @@ import androidx.compose.ui.util.fastForEach
|
||||
import ca.gosyer.build.BuildConfig
|
||||
import ca.gosyer.data.models.Category
|
||||
import ca.gosyer.data.models.Manga
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.WindowDialog
|
||||
import ca.gosyer.ui.base.components.ErrorScreen
|
||||
import ca.gosyer.ui.base.components.KamelImage
|
||||
@@ -59,12 +60,12 @@ import ca.gosyer.ui.base.components.LocalMenuController
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.TextActionIcon
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.ui.reader.openReaderMenu
|
||||
import ca.gosyer.util.compose.ThemedWindow
|
||||
import ca.gosyer.util.lang.launchApplication
|
||||
import com.google.accompanist.flowlayout.FlowRow
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import io.kamel.image.lazyPainterResource
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -100,20 +101,20 @@ fun MangaMenu(mangaId: Long, menuController: MenuController? = LocalMenuControll
|
||||
Box {
|
||||
Column {
|
||||
Toolbar(
|
||||
stringResource("location_manga"),
|
||||
stringResource(MR.strings.location_manga),
|
||||
menuController,
|
||||
menuController != null,
|
||||
actions = {
|
||||
AnimatedVisibility(categoriesExist && manga?.inLibrary == true) {
|
||||
TextActionIcon(
|
||||
vm::setCategories,
|
||||
stringResource("edit_categories"),
|
||||
stringResource(MR.strings.edit_categories),
|
||||
Icons.Rounded.Label
|
||||
)
|
||||
}
|
||||
TextActionIcon(
|
||||
vm::toggleFavorite,
|
||||
stringResource(if (manga?.inLibrary == true) "action_remove_favorite" else "action_favorite"),
|
||||
stringResource(if (manga?.inLibrary == true) MR.strings.action_remove_favorite else MR.strings.action_favorite),
|
||||
if (manga?.inLibrary == true) {
|
||||
Icons.Rounded.Favorite
|
||||
} else {
|
||||
@@ -123,7 +124,7 @@ fun MangaMenu(mangaId: Long, menuController: MenuController? = LocalMenuControll
|
||||
)
|
||||
TextActionIcon(
|
||||
vm::refreshManga,
|
||||
stringResource("action_refresh_manga"),
|
||||
stringResource(MR.strings.action_refresh_manga),
|
||||
Icons.Rounded.Refresh,
|
||||
!isLoading
|
||||
)
|
||||
@@ -155,7 +156,7 @@ fun MangaMenu(mangaId: Long, menuController: MenuController? = LocalMenuControll
|
||||
} else if (!isLoading) {
|
||||
item {
|
||||
ErrorScreen(
|
||||
stringResource("no_chapters_found"),
|
||||
stringResource(MR.strings.no_chapters_found),
|
||||
Modifier.height(400.dp).fillMaxWidth(),
|
||||
retry = vm::loadChapters
|
||||
)
|
||||
@@ -170,7 +171,7 @@ fun MangaMenu(mangaId: Long, menuController: MenuController? = LocalMenuControll
|
||||
)
|
||||
}
|
||||
} else if (!isLoading) {
|
||||
ErrorScreen(stringResource("failed_manga_fetch"), retry = vm::loadManga)
|
||||
ErrorScreen(stringResource(MR.strings.failed_manga_fetch), retry = vm::loadManga)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
package ca.gosyer.ui.manga
|
||||
|
||||
import ca.gosyer.core.lang.throwIfCancellation
|
||||
import ca.gosyer.core.lang.withIOContext
|
||||
import ca.gosyer.data.download.DownloadService
|
||||
import ca.gosyer.data.models.Category
|
||||
import ca.gosyer.data.models.Chapter
|
||||
@@ -17,8 +19,6 @@ import ca.gosyer.data.server.interactions.MangaInteractionHandler
|
||||
import ca.gosyer.data.ui.UiPreferences
|
||||
import ca.gosyer.ui.base.components.ChapterDownloadItem
|
||||
import ca.gosyer.ui.base.vm.ViewModel
|
||||
import ca.gosyer.util.lang.throwIfCancellation
|
||||
import ca.gosyer.util.lang.withIOContext
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
@@ -54,18 +54,16 @@ import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.WindowPlacement
|
||||
import androidx.compose.ui.window.rememberWindowState
|
||||
import ca.gosyer.build.BuildConfig
|
||||
import ca.gosyer.common.di.AppScope
|
||||
import ca.gosyer.core.di.AppScope
|
||||
import ca.gosyer.data.reader.model.Direction
|
||||
import ca.gosyer.data.reader.model.ImageScale
|
||||
import ca.gosyer.data.reader.model.NavigationMode
|
||||
import ca.gosyer.data.translation.XmlResourceBundle
|
||||
import ca.gosyer.data.ui.UiPreferences
|
||||
import ca.gosyer.data.ui.model.WindowSettings
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.components.ErrorScreen
|
||||
import ca.gosyer.ui.base.components.LoadingScreen
|
||||
import ca.gosyer.ui.base.components.mangaAspectRatio
|
||||
import ca.gosyer.ui.base.resources.LocalResources
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import ca.gosyer.ui.base.theme.AppTheme
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.ui.reader.model.Navigation
|
||||
@@ -79,6 +77,7 @@ import ca.gosyer.ui.reader.navigation.navigationClickable
|
||||
import ca.gosyer.ui.reader.viewer.ContinuousReader
|
||||
import ca.gosyer.ui.reader.viewer.PagerReader
|
||||
import ca.gosyer.util.lang.launchApplication
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import io.kamel.core.config.KamelConfig
|
||||
import io.kamel.image.config.LocalKamelConfig
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
@@ -108,7 +107,6 @@ fun openReaderMenu(chapterIndex: Int, mangaId: Long) {
|
||||
placement
|
||||
) = windowSettings.get().get()
|
||||
|
||||
val resources = AppScope.getInstance<XmlResourceBundle>()
|
||||
val kamelConfig = AppScope.getInstance<KamelConfig>()
|
||||
|
||||
launchApplication {
|
||||
@@ -144,7 +142,6 @@ fun openReaderMenu(chapterIndex: Int, mangaId: Long) {
|
||||
}
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
LocalResources provides resources,
|
||||
LocalKamelConfig provides kamelConfig
|
||||
) {
|
||||
AppTheme {
|
||||
@@ -292,7 +289,7 @@ fun ReaderMenu(
|
||||
SideMenuButton(sideMenuOpen, onOpenSideMenuClicked = { sideMenuOpen = true })
|
||||
}
|
||||
} else {
|
||||
ErrorScreen(stringResource("no_pages_found"))
|
||||
ErrorScreen(stringResource(MR.strings.no_pages_found))
|
||||
}
|
||||
} else {
|
||||
LoadingScreen(
|
||||
@@ -354,15 +351,15 @@ fun ChapterSeparator(
|
||||
Column {
|
||||
when {
|
||||
previousChapter == null && nextChapter != null -> {
|
||||
Text(stringResource("no_previous_chapter"))
|
||||
Text(stringResource(MR.strings.no_previous_chapter))
|
||||
}
|
||||
previousChapter != null && nextChapter != null -> {
|
||||
Text(stringResource("previous_chapter", previousChapter.chapter.name))
|
||||
Text(stringResource(MR.strings.previous_chapter, previousChapter.chapter.name))
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text(stringResource("next_chapter", nextChapter.chapter.name))
|
||||
Text(stringResource(MR.strings.next_chapter, nextChapter.chapter.name))
|
||||
}
|
||||
previousChapter != null && nextChapter == null -> {
|
||||
Text(stringResource("no_next_chapter"))
|
||||
Text(stringResource(MR.strings.no_next_chapter))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
package ca.gosyer.ui.reader
|
||||
|
||||
import ca.gosyer.core.lang.throwIfCancellation
|
||||
import ca.gosyer.data.models.Chapter
|
||||
import ca.gosyer.data.models.Manga
|
||||
import ca.gosyer.data.models.MangaMeta
|
||||
@@ -22,7 +23,6 @@ import ca.gosyer.ui.reader.model.PageMove
|
||||
import ca.gosyer.ui.reader.model.ReaderChapter
|
||||
import ca.gosyer.ui.reader.model.ReaderPage
|
||||
import ca.gosyer.ui.reader.model.ViewerChapters
|
||||
import ca.gosyer.util.lang.throwIfCancellation
|
||||
import ca.gosyer.util.system.CKLogger
|
||||
import ca.gosyer.util.system.getAsFlow
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
|
||||
@@ -39,12 +39,13 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import ca.gosyer.common.util.replace
|
||||
import ca.gosyer.core.util.replace
|
||||
import ca.gosyer.data.models.Chapter
|
||||
import ca.gosyer.data.models.ChapterMeta
|
||||
import ca.gosyer.data.models.MangaMeta
|
||||
import ca.gosyer.ui.base.components.Spinner
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.reader.model.ReaderChapter
|
||||
import ca.gosyer.util.system.kLogger
|
||||
import kotlin.math.roundToInt
|
||||
@@ -78,7 +79,7 @@ fun ReaderSideMenu(
|
||||
@Composable
|
||||
fun ReaderModeSetting(readerModes: List<String>, selectedMode: String, onSetReaderMode: (String) -> Unit) {
|
||||
val modes = remember(readerModes) { listOf(MangaMeta.DEFAULT_READER_MODE) + readerModes }
|
||||
val defaultModeString = stringResource("default_reader_mode")
|
||||
val defaultModeString = stringResource(MR.strings.default_reader_mode)
|
||||
val displayModes = remember(modes, defaultModeString) { modes.replace(0, defaultModeString) }
|
||||
val selectedModeIndex = remember(modes, selectedMode) { modes.indexOf(selectedMode) }
|
||||
Row(
|
||||
@@ -88,7 +89,7 @@ fun ReaderModeSetting(readerModes: List<String>, selectedMode: String, onSetRead
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text(stringResource("reader_mode"), Modifier.weight(0.25f), maxLines = 2, fontSize = 14.sp)
|
||||
Text(stringResource(MR.strings.reader_mode), Modifier.weight(0.25f), maxLines = 2, fontSize = 14.sp)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Spinner(
|
||||
modifier = Modifier.weight(0.75f),
|
||||
@@ -144,14 +145,14 @@ private fun NavigateChapters(loadPrevChapter: () -> Unit, loadNextChapter: () ->
|
||||
Row(horizontalArrangement = Arrangement.SpaceBetween,) {
|
||||
OutlinedButton(loadPrevChapter, Modifier.weight(0.5F)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
val nextChapter = stringResource("nav_prev_chapter")
|
||||
val nextChapter = stringResource(MR.strings.nav_prev_chapter)
|
||||
Icon(Icons.Rounded.NavigateBefore, nextChapter)
|
||||
Text(nextChapter, fontSize = 10.sp)
|
||||
}
|
||||
}
|
||||
OutlinedButton(loadNextChapter, Modifier.weight(0.5F)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
val nextChapter = stringResource("nav_next_chapter")
|
||||
val nextChapter = stringResource(MR.strings.nav_next_chapter)
|
||||
Text(nextChapter, fontSize = 10.sp)
|
||||
Icon(Icons.Rounded.NavigateNext, nextChapter)
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
package ca.gosyer.ui.reader.loader
|
||||
|
||||
import ca.gosyer.core.lang.throwIfCancellation
|
||||
import ca.gosyer.data.reader.ReaderPreferences
|
||||
import ca.gosyer.data.server.interactions.ChapterInteractionHandler
|
||||
import ca.gosyer.ui.reader.model.ReaderChapter
|
||||
import ca.gosyer.ui.reader.model.ReaderPage
|
||||
import ca.gosyer.util.lang.throwIfCancellation
|
||||
import ca.gosyer.util.system.CKLogger
|
||||
import io.github.kerubistan.kroki.coroutines.priorityChannel
|
||||
import io.ktor.client.features.onDownload
|
||||
|
||||
@@ -23,7 +23,8 @@ import ca.gosyer.data.update.UpdatePreferences
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.prefs.SwitchPreference
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.vm.ViewModel
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import javax.inject.Inject
|
||||
@@ -38,12 +39,12 @@ class SettingsAdvancedViewModel @Inject constructor(
|
||||
fun SettingsAdvancedScreen(menuController: MenuController) {
|
||||
val vm = viewModel<SettingsAdvancedViewModel>()
|
||||
Column {
|
||||
Toolbar(stringResource("settings_advanced_screen"), menuController, true)
|
||||
Toolbar(stringResource(MR.strings.settings_advanced_screen), menuController, true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
item {
|
||||
SwitchPreference(preference = vm.updatesEnabled, title = stringResource("update_checker"))
|
||||
SwitchPreference(preference = vm.updatesEnabled, title = stringResource(MR.strings.update_checker))
|
||||
}
|
||||
}
|
||||
VerticalScrollbar(
|
||||
|
||||
@@ -41,7 +41,8 @@ import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.prefs.ChoicePreference
|
||||
import ca.gosyer.ui.base.prefs.ColorPreference
|
||||
import ca.gosyer.ui.base.prefs.SwitchPreference
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.theme.AppColorsPreferenceState
|
||||
import ca.gosyer.ui.base.theme.Theme
|
||||
import ca.gosyer.ui.base.theme.asStateFlow
|
||||
@@ -81,7 +82,7 @@ fun SettingsAppearance(menuController: MenuController) {
|
||||
}
|
||||
|
||||
Column {
|
||||
Toolbar(stringResource("settings_appearance_screen"), menuController, true)
|
||||
Toolbar(stringResource(MR.strings.settings_appearance_screen), menuController, true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
@@ -89,16 +90,16 @@ fun SettingsAppearance(menuController: MenuController) {
|
||||
ChoicePreference(
|
||||
preference = vm.themeMode,
|
||||
choices = mapOf(
|
||||
ThemeMode.System to stringResource("theme_follow_system"),
|
||||
ThemeMode.Light to stringResource("theme_light"),
|
||||
ThemeMode.Dark to stringResource("theme_dark")
|
||||
ThemeMode.System to stringResource(MR.strings.theme_follow_system),
|
||||
ThemeMode.Light to stringResource(MR.strings.theme_light),
|
||||
ThemeMode.Dark to stringResource(MR.strings.theme_dark)
|
||||
),
|
||||
title = stringResource("theme")
|
||||
title = stringResource(MR.strings.theme)
|
||||
)
|
||||
}
|
||||
item {
|
||||
Text(
|
||||
stringResource("preset_themes"),
|
||||
stringResource(MR.strings.preset_themes),
|
||||
modifier = Modifier.padding(start = 16.dp, top = 16.dp, bottom = 4.dp)
|
||||
)
|
||||
LazyRow(modifier = Modifier.padding(horizontal = 8.dp)) {
|
||||
@@ -117,24 +118,24 @@ fun SettingsAppearance(menuController: MenuController) {
|
||||
item {
|
||||
ColorPreference(
|
||||
preference = activeColors.primaryStateFlow,
|
||||
title = stringResource("color_primary"),
|
||||
subtitle = stringResource("color_primary_sub"),
|
||||
title = stringResource(MR.strings.color_primary),
|
||||
subtitle = stringResource(MR.strings.color_primary_sub),
|
||||
unsetColor = MaterialTheme.colors.primary
|
||||
)
|
||||
}
|
||||
item {
|
||||
ColorPreference(
|
||||
preference = activeColors.secondaryStateFlow,
|
||||
title = stringResource("color_secondary"),
|
||||
subtitle = stringResource("color_secondary_sub"),
|
||||
title = stringResource(MR.strings.color_secondary),
|
||||
subtitle = stringResource(MR.strings.color_secondary_sub),
|
||||
unsetColor = MaterialTheme.colors.secondary
|
||||
)
|
||||
}
|
||||
item {
|
||||
SwitchPreference(
|
||||
vm.windowDecorations,
|
||||
stringResource("window_decorations"),
|
||||
stringResource("window_decorations_sub")
|
||||
stringResource(MR.strings.window_decorations),
|
||||
stringResource(MR.strings.window_decorations_sub)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -176,7 +177,7 @@ private fun ThemeItem(
|
||||
.weight(1f)
|
||||
.padding(6.dp)
|
||||
) {
|
||||
Text(stringResource("theme_text"), fontSize = 11.sp)
|
||||
Text(stringResource(MR.strings.theme_text), fontSize = 11.sp)
|
||||
Button(
|
||||
onClick = {},
|
||||
enabled = false,
|
||||
|
||||
@@ -32,15 +32,16 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.core.lang.throwIfCancellation
|
||||
import ca.gosyer.data.server.interactions.BackupInteractionHandler
|
||||
import ca.gosyer.ui.base.WindowDialog
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.prefs.PreferenceRow
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.vm.ViewModel
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.util.lang.throwIfCancellation
|
||||
import ca.gosyer.util.system.CKLogger
|
||||
import ca.gosyer.util.system.filePicker
|
||||
import ca.gosyer.util.system.fileSaver
|
||||
@@ -205,14 +206,14 @@ fun SettingsBackupScreen(menuController: MenuController) {
|
||||
}
|
||||
|
||||
Column {
|
||||
Toolbar(stringResource("settings_backup_screen"), menuController, true)
|
||||
Toolbar(stringResource(MR.strings.settings_backup_screen), menuController, true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
item {
|
||||
PreferenceFile(
|
||||
stringResource("backup_restore"),
|
||||
stringResource("backup_restore_sub"),
|
||||
stringResource(MR.strings.backup_restore),
|
||||
stringResource(MR.strings.backup_restore_sub),
|
||||
restoring,
|
||||
restoringProgress,
|
||||
restoreStatus
|
||||
@@ -222,8 +223,8 @@ fun SettingsBackupScreen(menuController: MenuController) {
|
||||
}
|
||||
}
|
||||
PreferenceFile(
|
||||
stringResource("backup_create"),
|
||||
stringResource("backup_create_sub"),
|
||||
stringResource(MR.strings.backup_create),
|
||||
stringResource(MR.strings.backup_create_sub),
|
||||
creating,
|
||||
creatingProgress,
|
||||
creatingStatus,
|
||||
@@ -249,7 +250,7 @@ private fun openMissingSourcesDialog(missingSources: List<String>, onPositiveCli
|
||||
) {
|
||||
LazyColumn {
|
||||
item {
|
||||
Text(stringResource("missing_sources"), style = MaterialTheme.typography.subtitle2)
|
||||
Text(stringResource(MR.strings.missing_sources), style = MaterialTheme.typography.subtitle2)
|
||||
}
|
||||
items(missingSources) {
|
||||
Text(it)
|
||||
|
||||
@@ -19,14 +19,15 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
|
||||
@Composable
|
||||
fun SettingsBrowseScreen(menuController: MenuController) {
|
||||
Column {
|
||||
Toolbar(stringResource("settings_browse_screen"), menuController, true)
|
||||
Toolbar(stringResource(MR.strings.settings_browse_screen), menuController, true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
|
||||
@@ -21,12 +21,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
|
||||
@Composable
|
||||
fun SettingsDownloadsScreen(menuController: MenuController) {
|
||||
Column {
|
||||
Toolbar(stringResource("settings_download_screen"), menuController, true)
|
||||
Toolbar(stringResource(MR.strings.settings_download_screen), menuController, true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
|
||||
@@ -23,13 +23,14 @@ import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.build.BuildResources
|
||||
import ca.gosyer.data.ui.UiPreferences
|
||||
import ca.gosyer.data.ui.model.StartScreen
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.prefs.ChoicePreference
|
||||
import ca.gosyer.ui.base.prefs.SwitchPreference
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import ca.gosyer.ui.base.vm.ViewModel
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import java.time.Instant
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
@@ -51,16 +52,16 @@ class SettingsGeneralViewModel @Inject constructor(
|
||||
|
||||
@Composable
|
||||
fun getStartScreenChoices() = mapOf(
|
||||
StartScreen.Library to stringResource("location_library"),
|
||||
StartScreen.Updates to stringResource("location_updates"),
|
||||
StartScreen.Sources to stringResource("location_sources"),
|
||||
StartScreen.Extensions to stringResource("location_extensions")
|
||||
StartScreen.Library to stringResource(MR.strings.location_library),
|
||||
StartScreen.Updates to stringResource(MR.strings.location_updates),
|
||||
StartScreen.Sources to stringResource(MR.strings.location_sources),
|
||||
StartScreen.Extensions to stringResource(MR.strings.location_extensions)
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun getLanguageChoices(): Map<String, String> = (
|
||||
mapOf(
|
||||
"" to stringResource("language_system_default", currentLocale.getDisplayName(currentLocale))
|
||||
"" to stringResource(MR.strings.language_system_default, currentLocale.getDisplayName(currentLocale))
|
||||
) + BuildResources.LANGUAGES
|
||||
.associateWith { Locale.forLanguageTag(it).getDisplayName(currentLocale) }
|
||||
)
|
||||
@@ -69,7 +70,7 @@ class SettingsGeneralViewModel @Inject constructor(
|
||||
@Composable
|
||||
fun getDateChoices(): Map<String, String> {
|
||||
return mapOf(
|
||||
"" to stringResource("date_system_default"),
|
||||
"" to stringResource(MR.strings.date_system_default),
|
||||
"MM/dd/yy" to "MM/dd/yy",
|
||||
"dd/MM/yy" to "dd/MM/yy",
|
||||
"yyyy-MM-dd" to "yyyy-MM-dd"
|
||||
@@ -91,21 +92,21 @@ class SettingsGeneralViewModel @Inject constructor(
|
||||
fun SettingsGeneralScreen(menuController: MenuController) {
|
||||
val vm = viewModel<SettingsGeneralViewModel>()
|
||||
Column {
|
||||
Toolbar(stringResource("settings_general_screen"), menuController, closable = true)
|
||||
Toolbar(stringResource(MR.strings.settings_general_screen), menuController, closable = true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
item {
|
||||
ChoicePreference(
|
||||
preference = vm.startScreen,
|
||||
title = stringResource("start_screen"),
|
||||
title = stringResource(MR.strings.start_screen),
|
||||
choices = vm.getStartScreenChoices()
|
||||
)
|
||||
}
|
||||
item {
|
||||
SwitchPreference(
|
||||
preference = vm.confirmExit,
|
||||
title = stringResource("confirm_exit")
|
||||
title = stringResource(MR.strings.confirm_exit)
|
||||
)
|
||||
}
|
||||
item {
|
||||
@@ -114,14 +115,14 @@ fun SettingsGeneralScreen(menuController: MenuController) {
|
||||
item {
|
||||
ChoicePreference(
|
||||
preference = vm.language,
|
||||
title = stringResource("language"),
|
||||
title = stringResource(MR.strings.language),
|
||||
choices = vm.getLanguageChoices(),
|
||||
)
|
||||
}
|
||||
item {
|
||||
ChoicePreference(
|
||||
preference = vm.dateFormat,
|
||||
title = stringResource("date_format"),
|
||||
title = stringResource(MR.strings.date_format),
|
||||
choices = vm.getDateChoices()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.prefs.PreferenceRow
|
||||
import ca.gosyer.ui.base.prefs.SwitchPreference
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.vm.ViewModel
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.ui.categories.openCategoriesMenu
|
||||
@@ -60,19 +61,19 @@ fun SettingsLibraryScreen(menuController: MenuController) {
|
||||
val vm = viewModel<SettingsLibraryViewModel>()
|
||||
|
||||
Column {
|
||||
Toolbar(stringResource("settings_library_screen"), menuController, true)
|
||||
Toolbar(stringResource(MR.strings.settings_library_screen), menuController, true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
item {
|
||||
SwitchPreference(
|
||||
preference = vm.showAllCategory,
|
||||
title = stringResource("show_all_category")
|
||||
title = stringResource(MR.strings.show_all_category)
|
||||
)
|
||||
}
|
||||
item {
|
||||
PreferenceRow(
|
||||
stringResource("location_categories"),
|
||||
stringResource(MR.strings.location_categories),
|
||||
onClick = { openCategoriesMenu(vm::refreshCategoryCount) },
|
||||
subtitle = vm.categories.collectAsState().value.toString()
|
||||
)
|
||||
|
||||
@@ -21,12 +21,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
|
||||
@Composable
|
||||
fun SettingsParentalControlsScreen(menuController: MenuController) {
|
||||
Column {
|
||||
Toolbar(stringResource("settings_parental_control_screen"), menuController, true)
|
||||
Toolbar(stringResource(MR.strings.settings_parental_control_screen), menuController, true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
|
||||
@@ -28,7 +28,7 @@ import ca.gosyer.data.reader.ReaderPreferences
|
||||
import ca.gosyer.data.reader.model.Direction
|
||||
import ca.gosyer.data.reader.model.ImageScale
|
||||
import ca.gosyer.data.reader.model.NavigationMode
|
||||
import ca.gosyer.data.translation.XmlResourceBundle
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.prefs.ChoicePreference
|
||||
@@ -36,9 +36,9 @@ import ca.gosyer.ui.base.prefs.ExpandablePreference
|
||||
import ca.gosyer.ui.base.prefs.PreferenceMutableStateFlow
|
||||
import ca.gosyer.ui.base.prefs.SwitchPreference
|
||||
import ca.gosyer.ui.base.prefs.asStateIn
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import ca.gosyer.ui.base.vm.ViewModel
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
@@ -47,7 +47,6 @@ import kotlinx.coroutines.flow.onEach
|
||||
import javax.inject.Inject
|
||||
|
||||
class SettingsReaderViewModel @Inject constructor(
|
||||
private val resources: XmlResourceBundle,
|
||||
readerPreferences: ReaderPreferences
|
||||
) : ViewModel() {
|
||||
val modes = readerPreferences.modes().asStateFlow()
|
||||
@@ -68,10 +67,10 @@ class SettingsReaderViewModel @Inject constructor(
|
||||
}.launchIn(scope)
|
||||
}
|
||||
|
||||
fun getDirectionChoices() = Direction.values().associate { it to resources.getStringA(it.res) }
|
||||
fun getDirectionChoices() = Direction.values().associateWith { it.res.localized() }
|
||||
|
||||
fun getPaddingChoices() = mapOf(
|
||||
0 to resources.getStringA("page_padding_none"),
|
||||
0 to MR.strings.page_padding_none.localized(),
|
||||
8 to "8 Dp",
|
||||
16 to "16 Dp",
|
||||
32 to "32 Dp"
|
||||
@@ -79,23 +78,23 @@ class SettingsReaderViewModel @Inject constructor(
|
||||
|
||||
fun getMaxSizeChoices(direction: Direction) = if (direction == Direction.Right || direction == Direction.Left) {
|
||||
mapOf(
|
||||
0 to resources.getStringA("max_size_unrestricted"),
|
||||
0 to MR.strings.max_size_unrestricted.localized(),
|
||||
700 to "700 Dp",
|
||||
900 to "900 Dp",
|
||||
1100 to "1100 Dp"
|
||||
)
|
||||
} else {
|
||||
mapOf(
|
||||
0 to resources.getStringA("max_size_unrestricted"),
|
||||
0 to MR.strings.max_size_unrestricted.localized(),
|
||||
500 to "500 Dp",
|
||||
700 to "700 Dp",
|
||||
900 to "900 Dp"
|
||||
)
|
||||
}
|
||||
|
||||
fun getImageScaleChoices() = ImageScale.values().associate { it to resources.getStringA(it.res) }
|
||||
fun getImageScaleChoices() = ImageScale.values().associateWith { it.res.localized() }
|
||||
|
||||
fun getNavigationModeChoices() = NavigationMode.values().associate { it to resources.getStringA(it.res) }
|
||||
fun getNavigationModeChoices() = NavigationMode.values().associateWith { it.res.localized() }
|
||||
}
|
||||
|
||||
data class ReaderModePreference(
|
||||
@@ -130,7 +129,7 @@ fun SettingsReaderScreen(menuController: MenuController) {
|
||||
val vm = viewModel<SettingsReaderViewModel>()
|
||||
val modeSettings by vm.modeSettings.collectAsState()
|
||||
Column {
|
||||
Toolbar(stringResource("settings_reader"), menuController, true)
|
||||
Toolbar(stringResource(MR.strings.settings_reader), menuController, true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
@@ -138,7 +137,7 @@ fun SettingsReaderScreen(menuController: MenuController) {
|
||||
ChoicePreference(
|
||||
vm.selectedMode,
|
||||
vm.modes.collectAsState().value.associateWith { it },
|
||||
stringResource("reader_mode")
|
||||
stringResource(MR.strings.reader_mode)
|
||||
)
|
||||
}
|
||||
item {
|
||||
@@ -150,13 +149,13 @@ fun SettingsReaderScreen(menuController: MenuController) {
|
||||
ChoicePreference(
|
||||
it.direction,
|
||||
vm.getDirectionChoices(),
|
||||
stringResource("direction"),
|
||||
stringResource(MR.strings.direction),
|
||||
enabled = !it.defaultMode
|
||||
)
|
||||
SwitchPreference(
|
||||
it.continuous,
|
||||
stringResource("continuous"),
|
||||
stringResource("continuous_sub"),
|
||||
stringResource(MR.strings.continuous),
|
||||
stringResource(MR.strings.continuous_sub),
|
||||
enabled = !it.defaultMode
|
||||
)
|
||||
val continuous by it.continuous.collectAsState()
|
||||
@@ -164,13 +163,13 @@ fun SettingsReaderScreen(menuController: MenuController) {
|
||||
ChoicePreference(
|
||||
it.padding,
|
||||
vm.getPaddingChoices(),
|
||||
stringResource("page_padding")
|
||||
stringResource(MR.strings.page_padding)
|
||||
)
|
||||
val direction by it.direction.collectAsState()
|
||||
val (title, subtitle) = if (direction == Direction.Up || direction == Direction.Down) {
|
||||
stringResource("force_fit_width") to stringResource("force_fit_width_sub")
|
||||
stringResource(MR.strings.force_fit_width) to stringResource(MR.strings.force_fit_width_sub)
|
||||
} else {
|
||||
stringResource("force_fit_height") to stringResource("force_fit_height_sub")
|
||||
stringResource(MR.strings.force_fit_height) to stringResource(MR.strings.force_fit_height_sub)
|
||||
}
|
||||
SwitchPreference(
|
||||
it.fitSize,
|
||||
@@ -179,13 +178,13 @@ fun SettingsReaderScreen(menuController: MenuController) {
|
||||
)
|
||||
val maxSize by it.maxSize.collectAsState()
|
||||
val (maxSizeTitle, maxSizeSubtitle) = if (direction == Direction.Up || direction == Direction.Down) {
|
||||
stringResource("max_width") to stringResource(
|
||||
"max_width_sub",
|
||||
stringResource(MR.strings.max_width) to stringResource(
|
||||
MR.strings.max_width_sub,
|
||||
maxSize
|
||||
)
|
||||
} else {
|
||||
stringResource("max_height") to stringResource(
|
||||
"max_height_sub",
|
||||
stringResource(MR.strings.max_height) to stringResource(
|
||||
MR.strings.max_height_sub,
|
||||
maxSize
|
||||
)
|
||||
}
|
||||
@@ -199,13 +198,13 @@ fun SettingsReaderScreen(menuController: MenuController) {
|
||||
ChoicePreference(
|
||||
it.imageScale,
|
||||
vm.getImageScaleChoices(),
|
||||
stringResource("image_scale")
|
||||
stringResource(MR.strings.image_scale)
|
||||
)
|
||||
}
|
||||
ChoicePreference(
|
||||
it.navigationMode,
|
||||
vm.getNavigationModeChoices(),
|
||||
stringResource("navigation_mode")
|
||||
stringResource(MR.strings.navigation_mode)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,96 +31,97 @@ import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.prefs.PreferenceRow
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.main.Routes
|
||||
|
||||
@Composable
|
||||
fun SettingsScreen(menuController: MenuController) {
|
||||
Column {
|
||||
Toolbar(stringResource("location_settings"), closable = false)
|
||||
Toolbar(stringResource(MR.strings.location_settings), closable = false)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
item {
|
||||
PreferenceRow(
|
||||
title = stringResource("settings_general"),
|
||||
title = stringResource(MR.strings.settings_general),
|
||||
icon = Icons.Rounded.Tune,
|
||||
onClick = { menuController.push(Routes.SettingsGeneral) }
|
||||
)
|
||||
}
|
||||
item {
|
||||
PreferenceRow(
|
||||
title = stringResource("settings_appearance"),
|
||||
title = stringResource(MR.strings.settings_appearance),
|
||||
icon = Icons.Rounded.Palette,
|
||||
onClick = { menuController.push(Routes.SettingsAppearance) }
|
||||
)
|
||||
}
|
||||
item {
|
||||
PreferenceRow(
|
||||
title = stringResource("settings_server"),
|
||||
title = stringResource(MR.strings.settings_server),
|
||||
icon = Icons.Rounded.Computer,
|
||||
onClick = { menuController.push(Routes.SettingsServer) }
|
||||
)
|
||||
}
|
||||
item {
|
||||
PreferenceRow(
|
||||
title = stringResource("settings_library"),
|
||||
title = stringResource(MR.strings.settings_library),
|
||||
icon = Icons.Rounded.CollectionsBookmark,
|
||||
onClick = { menuController.push(Routes.SettingsLibrary) }
|
||||
)
|
||||
}
|
||||
item {
|
||||
PreferenceRow(
|
||||
title = stringResource("settings_reader"),
|
||||
title = stringResource(MR.strings.settings_reader),
|
||||
icon = Icons.Rounded.ChromeReaderMode,
|
||||
onClick = { menuController.push(Routes.SettingsReader) }
|
||||
)
|
||||
}
|
||||
/*item {
|
||||
Pref(
|
||||
title = stringResource("settings_download"),
|
||||
title = stringResource(MR.strings.settings_download),
|
||||
icon = Icons.Rounded.GetApp,
|
||||
onClick = { navController.push(Route.SettingsDownloads) }
|
||||
)
|
||||
}
|
||||
item {
|
||||
Pref(
|
||||
title = stringResource("settings_tracking"),
|
||||
title = stringResource(MR.strings.settings_tracking),
|
||||
icon = Icons.Rounded.Sync,
|
||||
onClick = { navController.push(Route.SettingsTracking) }
|
||||
)
|
||||
}*/
|
||||
item {
|
||||
PreferenceRow(
|
||||
title = stringResource("settings_browse"),
|
||||
title = stringResource(MR.strings.settings_browse),
|
||||
icon = Icons.Rounded.Explore,
|
||||
onClick = { menuController.push(Routes.SettingsBrowse) }
|
||||
)
|
||||
}
|
||||
item {
|
||||
PreferenceRow(
|
||||
title = stringResource("settings_backup"),
|
||||
title = stringResource(MR.strings.settings_backup),
|
||||
icon = Icons.Rounded.Backup,
|
||||
onClick = { menuController.push(Routes.SettingsBackup) }
|
||||
)
|
||||
}
|
||||
/*item {
|
||||
Pref(
|
||||
title = stringResource("settings_security"),
|
||||
title = stringResource(MR.strings.settings_security),
|
||||
icon = Icons.Rounded.Security,
|
||||
onClick = { navController.push(Route.SettingsSecurity) }
|
||||
)
|
||||
}
|
||||
item {
|
||||
Pref(
|
||||
title = stringResource("settings_parental_controls"),
|
||||
title = stringResource(MR.strings.settings_parental_controls),
|
||||
icon = Icons.Rounded.PeopleOutline,
|
||||
onClick = { navController.push(Route.SettingsParentalControls) }
|
||||
)
|
||||
}*/
|
||||
item {
|
||||
PreferenceRow(
|
||||
title = stringResource("settings_advanced"),
|
||||
title = stringResource(MR.strings.settings_advanced),
|
||||
icon = Icons.Rounded.Code,
|
||||
onClick = { menuController.push(Routes.SettingsAdvanced) }
|
||||
)
|
||||
|
||||
@@ -21,12 +21,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
|
||||
@Composable
|
||||
fun SettingsSecurityScreen(menuController: MenuController) {
|
||||
Column {
|
||||
Toolbar(stringResource("settings_security_screen"), menuController, true)
|
||||
Toolbar(stringResource(MR.strings.settings_security_screen), menuController, true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import ca.gosyer.data.server.ServerPreferences
|
||||
import ca.gosyer.data.server.ServerService
|
||||
import ca.gosyer.data.server.model.Auth
|
||||
import ca.gosyer.data.server.model.Proxy
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.prefs.ChoicePreference
|
||||
@@ -40,10 +41,10 @@ import ca.gosyer.ui.base.prefs.PreferenceRow
|
||||
import ca.gosyer.ui.base.prefs.SwitchPreference
|
||||
import ca.gosyer.ui.base.prefs.asStateIn
|
||||
import ca.gosyer.ui.base.prefs.asStringStateIn
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import ca.gosyer.ui.base.vm.ViewModel
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.util.system.CKLogger
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@@ -85,9 +86,9 @@ class SettingsServerViewModel @Inject constructor(
|
||||
|
||||
@Composable
|
||||
fun getProxyChoices() = mapOf(
|
||||
Proxy.NO_PROXY to stringResource("no_proxy"),
|
||||
Proxy.HTTP_PROXY to stringResource("http_proxy"),
|
||||
Proxy.SOCKS_PROXY to stringResource("socks_proxy")
|
||||
Proxy.NO_PROXY to stringResource(MR.strings.no_proxy),
|
||||
Proxy.HTTP_PROXY to stringResource(MR.strings.http_proxy),
|
||||
Proxy.SOCKS_PROXY to stringResource(MR.strings.socks_proxy)
|
||||
)
|
||||
|
||||
val httpHost = serverPreferences.proxyHttpHost().asStateIn(scope)
|
||||
@@ -99,9 +100,9 @@ class SettingsServerViewModel @Inject constructor(
|
||||
|
||||
@Composable
|
||||
fun getAuthChoices() = mapOf(
|
||||
Auth.NONE to stringResource("no_auth"),
|
||||
Auth.BASIC to stringResource("basic_auth"),
|
||||
Auth.DIGEST to stringResource("digest_auth")
|
||||
Auth.NONE to stringResource(MR.strings.no_auth),
|
||||
Auth.BASIC to stringResource(MR.strings.basic_auth),
|
||||
Auth.DIGEST to stringResource(MR.strings.digest_auth)
|
||||
)
|
||||
val authUsername = serverPreferences.authUsername().asStateIn(scope)
|
||||
val authPassword = serverPreferences.authPassword().asStateIn(scope)
|
||||
@@ -147,27 +148,27 @@ fun SettingsServerScreen(menuController: MenuController) {
|
||||
}
|
||||
}
|
||||
Column {
|
||||
Toolbar(stringResource("settings_server_screen"), menuController, true)
|
||||
Toolbar(stringResource(MR.strings.settings_server_screen), menuController, true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
item {
|
||||
SwitchPreference(preference = vm.host, title = stringResource("host_server"))
|
||||
SwitchPreference(preference = vm.host, title = stringResource(MR.strings.host_server))
|
||||
}
|
||||
if (host) {
|
||||
item {
|
||||
PreferenceRow(
|
||||
stringResource("host_settings"),
|
||||
stringResource(MR.strings.host_settings),
|
||||
Icons.Rounded.Info,
|
||||
subtitle = stringResource("host_settings_sub")
|
||||
subtitle = stringResource(MR.strings.host_settings_sub)
|
||||
)
|
||||
}
|
||||
item {
|
||||
val ip by vm.ip.collectAsState()
|
||||
EditTextPreference(
|
||||
preference = vm.ip,
|
||||
title = stringResource("host_ip"),
|
||||
subtitle = stringResource("host_ip_sub", ip),
|
||||
title = stringResource(MR.strings.host_ip),
|
||||
subtitle = stringResource(MR.strings.host_ip_sub, ip),
|
||||
changeListener = vm::serverSettingChanged
|
||||
)
|
||||
}
|
||||
@@ -175,15 +176,15 @@ fun SettingsServerScreen(menuController: MenuController) {
|
||||
val port by vm.port.collectAsState()
|
||||
EditTextPreference(
|
||||
preference = vm.port,
|
||||
title = stringResource("host_port"),
|
||||
subtitle = stringResource("host_port_sub", port),
|
||||
title = stringResource(MR.strings.host_port),
|
||||
subtitle = stringResource(MR.strings.host_port_sub, port),
|
||||
changeListener = vm::serverSettingChanged
|
||||
)
|
||||
}
|
||||
item {
|
||||
SwitchPreference(
|
||||
preference = vm.socksProxyEnabled,
|
||||
title = stringResource("host_socks_enabled"),
|
||||
title = stringResource(MR.strings.host_socks_enabled),
|
||||
changeListener = vm::serverSettingChanged
|
||||
)
|
||||
}
|
||||
@@ -191,8 +192,8 @@ fun SettingsServerScreen(menuController: MenuController) {
|
||||
val proxyHost by vm.socksProxyHost.collectAsState()
|
||||
EditTextPreference(
|
||||
preference = vm.socksProxyHost,
|
||||
title = stringResource("host_socks_host"),
|
||||
subtitle = stringResource("host_socks_host_sub", proxyHost),
|
||||
title = stringResource(MR.strings.host_socks_host),
|
||||
subtitle = stringResource(MR.strings.host_socks_host_sub, proxyHost),
|
||||
changeListener = vm::serverSettingChanged
|
||||
)
|
||||
}
|
||||
@@ -200,32 +201,32 @@ fun SettingsServerScreen(menuController: MenuController) {
|
||||
val proxyPort by vm.socksProxyPort.collectAsState()
|
||||
EditTextPreference(
|
||||
preference = vm.socksProxyPort,
|
||||
title = stringResource("host_socks_port"),
|
||||
subtitle = stringResource("host_socks_port_sub", proxyPort),
|
||||
title = stringResource(MR.strings.host_socks_port),
|
||||
subtitle = stringResource(MR.strings.host_socks_port_sub, proxyPort),
|
||||
changeListener = vm::serverSettingChanged
|
||||
)
|
||||
}
|
||||
item {
|
||||
SwitchPreference(
|
||||
preference = vm.debugLogsEnabled,
|
||||
title = stringResource("host_debug_logging"),
|
||||
subtitle = stringResource("host_debug_logging_sub"),
|
||||
title = stringResource(MR.strings.host_debug_logging),
|
||||
subtitle = stringResource(MR.strings.host_debug_logging_sub),
|
||||
changeListener = vm::serverSettingChanged
|
||||
)
|
||||
}
|
||||
item {
|
||||
SwitchPreference(
|
||||
preference = vm.systemTrayEnabled,
|
||||
title = stringResource("host_system_tray"),
|
||||
subtitle = stringResource("host_system_tray_sub"),
|
||||
title = stringResource(MR.strings.host_system_tray),
|
||||
subtitle = stringResource(MR.strings.host_system_tray_sub),
|
||||
changeListener = vm::serverSettingChanged
|
||||
)
|
||||
}
|
||||
item {
|
||||
SwitchPreference(
|
||||
preference = vm.webUIEnabled,
|
||||
title = stringResource("host_webui"),
|
||||
subtitle = stringResource("host_webui_sub"),
|
||||
title = stringResource(MR.strings.host_webui),
|
||||
subtitle = stringResource(MR.strings.host_webui_sub),
|
||||
changeListener = vm::serverSettingChanged
|
||||
)
|
||||
}
|
||||
@@ -233,8 +234,8 @@ fun SettingsServerScreen(menuController: MenuController) {
|
||||
val webUIEnabled by vm.webUIEnabled.collectAsState()
|
||||
SwitchPreference(
|
||||
preference = vm.openInBrowserEnabled,
|
||||
title = stringResource("host_open_in_browser"),
|
||||
subtitle = stringResource("host_open_in_browser_sub"),
|
||||
title = stringResource(MR.strings.host_open_in_browser),
|
||||
subtitle = stringResource(MR.strings.host_open_in_browser_sub),
|
||||
changeListener = vm::serverSettingChanged,
|
||||
enabled = webUIEnabled
|
||||
)
|
||||
@@ -242,15 +243,15 @@ fun SettingsServerScreen(menuController: MenuController) {
|
||||
item {
|
||||
SwitchPreference(
|
||||
preference = vm.basicAuthEnabled,
|
||||
title = stringResource("basic_auth"),
|
||||
subtitle = stringResource("host_basic_auth_sub"),
|
||||
title = stringResource(MR.strings.basic_auth),
|
||||
subtitle = stringResource(MR.strings.host_basic_auth_sub),
|
||||
changeListener = vm::serverSettingChanged
|
||||
)
|
||||
}
|
||||
item {
|
||||
EditTextPreference(
|
||||
preference = vm.basicAuthUsername,
|
||||
title = stringResource("host_basic_auth_username"),
|
||||
title = stringResource(MR.strings.host_basic_auth_username),
|
||||
changeListener = vm::serverSettingChanged,
|
||||
enabled = basicAuthEnabled
|
||||
)
|
||||
@@ -258,7 +259,7 @@ fun SettingsServerScreen(menuController: MenuController) {
|
||||
item {
|
||||
EditTextPreference(
|
||||
preference = vm.basicAuthPassword,
|
||||
title = stringResource("host_basic_auth_password"),
|
||||
title = stringResource(MR.strings.host_basic_auth_password),
|
||||
changeListener = vm::serverSettingChanged,
|
||||
visualTransformation = PasswordVisualTransformation(),
|
||||
enabled = basicAuthEnabled
|
||||
@@ -271,27 +272,27 @@ fun SettingsServerScreen(menuController: MenuController) {
|
||||
item {
|
||||
EditTextPreference(
|
||||
vm.serverUrl,
|
||||
stringResource("server_url"),
|
||||
stringResource(MR.strings.server_url),
|
||||
subtitle = vm.serverUrl.collectAsState().value
|
||||
)
|
||||
}
|
||||
item {
|
||||
EditTextPreference(
|
||||
vm.serverPort,
|
||||
stringResource("server_port"),
|
||||
stringResource(MR.strings.server_port),
|
||||
subtitle = vm.serverPort.collectAsState().value
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
PreferenceRow(
|
||||
stringResource("server_preference_warning"),
|
||||
stringResource(MR.strings.server_preference_warning),
|
||||
Icons.Rounded.Warning,
|
||||
subtitle = stringResource("server_preference_warning_sub")
|
||||
subtitle = stringResource(MR.strings.server_preference_warning_sub)
|
||||
)
|
||||
}
|
||||
item {
|
||||
ChoicePreference(vm.proxy, vm.getProxyChoices(), stringResource("server_proxy"))
|
||||
ChoicePreference(vm.proxy, vm.getProxyChoices(), stringResource(MR.strings.server_proxy))
|
||||
}
|
||||
when (proxy) {
|
||||
Proxy.NO_PROXY -> Unit
|
||||
@@ -299,14 +300,14 @@ fun SettingsServerScreen(menuController: MenuController) {
|
||||
item {
|
||||
EditTextPreference(
|
||||
vm.httpHost,
|
||||
stringResource("http_proxy"),
|
||||
stringResource(MR.strings.http_proxy),
|
||||
vm.httpHost.collectAsState().value
|
||||
)
|
||||
}
|
||||
item {
|
||||
EditTextPreference(
|
||||
vm.httpPort,
|
||||
stringResource("http_port"),
|
||||
stringResource(MR.strings.http_port),
|
||||
vm.httpPort.collectAsState().value
|
||||
)
|
||||
}
|
||||
@@ -315,30 +316,30 @@ fun SettingsServerScreen(menuController: MenuController) {
|
||||
item {
|
||||
EditTextPreference(
|
||||
vm.socksHost,
|
||||
stringResource("socks_proxy"),
|
||||
stringResource(MR.strings.socks_proxy),
|
||||
vm.socksHost.collectAsState().value
|
||||
)
|
||||
}
|
||||
item {
|
||||
EditTextPreference(
|
||||
vm.socksPort,
|
||||
stringResource("socks_port"),
|
||||
stringResource(MR.strings.socks_port),
|
||||
vm.socksPort.collectAsState().value
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
item {
|
||||
ChoicePreference(vm.auth, vm.getAuthChoices(), stringResource("authentication"))
|
||||
ChoicePreference(vm.auth, vm.getAuthChoices(), stringResource(MR.strings.authentication))
|
||||
}
|
||||
if (auth != Auth.NONE) {
|
||||
item {
|
||||
EditTextPreference(vm.authUsername, stringResource("auth_username"))
|
||||
EditTextPreference(vm.authUsername, stringResource(MR.strings.auth_username))
|
||||
}
|
||||
item {
|
||||
EditTextPreference(
|
||||
vm.authPassword,
|
||||
stringResource("auth_password"),
|
||||
stringResource(MR.strings.auth_password),
|
||||
visualTransformation = PasswordVisualTransformation()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -21,12 +21,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ca.gosyer.ui.base.components.MenuController
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
|
||||
@Composable
|
||||
fun SettingsTrackingScreen(menuController: MenuController) {
|
||||
Column {
|
||||
Toolbar(stringResource("settings_tracking_screen"), menuController, true)
|
||||
Toolbar(stringResource(MR.strings.settings_tracking_screen), menuController, true)
|
||||
Box {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state) {
|
||||
|
||||
@@ -42,7 +42,8 @@ import ca.gosyer.build.BuildConfig
|
||||
import ca.gosyer.data.models.Source
|
||||
import ca.gosyer.ui.base.components.KamelImage
|
||||
import ca.gosyer.ui.base.components.combinedMouseClickable
|
||||
import ca.gosyer.ui.base.resources.stringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import ca.gosyer.i18n.MR
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.ui.manga.openMangaMenu
|
||||
import ca.gosyer.ui.sources.components.SourceHomeScreen
|
||||
@@ -122,7 +123,7 @@ fun SourcesSideMenu(
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
elevation = 4.dp
|
||||
) {
|
||||
Text(source?.name ?: stringResource("sources_home"), modifier = Modifier.padding(10.dp))
|
||||
Text(source?.name ?: stringResource(MR.strings.sources_home), modifier = Modifier.padding(10.dp))
|
||||
}
|
||||
},
|
||||
modifier = Modifier.size(64.dp),
|
||||
@@ -153,7 +154,7 @@ fun SourcesSideMenu(
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Icon(Icons.Rounded.Home, stringResource("sources_home"), modifier = modifier)
|
||||
Icon(Icons.Rounded.Home, stringResource(MR.strings.sources_home), modifier = modifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user