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:
Syer10
2022-01-26 18:30:44 -05:00
parent f7d5a4af5c
commit d2009541e8
139 changed files with 692 additions and 605 deletions

View File

@@ -4,7 +4,7 @@
<option name="executionName" /> <option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" /> <option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="-PdebugApp" /> <option name="scriptParameters" value="-PdebugApp --stacktrace" />
<option name="taskDescriptions"> <option name="taskDescriptions">
<list /> <list />
</option> </option>
@@ -14,6 +14,7 @@
<option value="run" /> <option value="run" />
</list> </list>
</option> </option>
<option name="vmOptions" />
</ExternalSystemSettings> </ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess> <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess> <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>

View File

@@ -2,8 +2,11 @@ plugins {
kotlin("multiplatform") version "1.6.10" apply false kotlin("multiplatform") version "1.6.10" apply false
kotlin("kapt") version "1.6.10" apply false kotlin("kapt") version "1.6.10" apply false
kotlin("plugin.serialization") 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("org.jetbrains.compose") version "1.0.1" apply false
id("com.github.gmazzo.buildconfig") version "3.0.3" 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("org.jmailen.kotlinter") version "3.8.0" apply false
id("com.github.ben-manes.versions") version "0.41.0" 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") 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
View 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
}
}

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="ca.gosyer.core"/>

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * 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.KSerializer
import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.SerializersModule

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * 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.CoroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * 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.KSerializer
import kotlinx.serialization.modules.EmptySerializersModule import kotlinx.serialization.modules.EmptySerializersModule

View File

@@ -6,7 +6,6 @@
package ca.gosyer.core.prefs package ca.gosyer.core.prefs
import ca.gosyer.common.prefs.Preference
import com.russhwolf.settings.ObservableSettings import com.russhwolf.settings.ObservableSettings
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose

View File

@@ -6,8 +6,6 @@
package ca.gosyer.core.prefs package ca.gosyer.core.prefs
import ca.gosyer.common.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore
import com.russhwolf.settings.ObservableSettings import com.russhwolf.settings.ObservableSettings
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.SerializersModule

View File

@@ -6,7 +6,6 @@
package ca.gosyer.core.prefs package ca.gosyer.core.prefs
import ca.gosyer.common.prefs.PreferenceStore
import com.russhwolf.settings.JvmPreferencesSettings import com.russhwolf.settings.JvmPreferencesSettings
import java.util.prefs.Preferences import java.util.prefs.Preferences

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * 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.Scope
import toothpick.ktp.KTP import toothpick.ktp.KTP

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * 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.Scope
import javax.inject.Provider import javax.inject.Provider

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * 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 import toothpick.config.Module

View File

@@ -4,9 +4,9 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * 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.Buffer
import okio.Source import okio.Source
import okio.Timeout import okio.Timeout

View File

@@ -4,13 +4,14 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * 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.BufferedSink
import okio.Source import okio.Source
import okio.buffer import okio.buffer
import okio.sink import okio.sink
import okio.use
import java.nio.file.Path import java.nio.file.Path
suspend fun Source.saveTo(path: Path) { suspend fun Source.saveTo(path: Path) {

View File

@@ -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
}

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * 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 import java.util.Locale

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * 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.decodeBase64
import okio.ByteString.Companion.encode import okio.ByteString.Companion.encode

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * 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]. * Returns a new list that replaces the item at the given [position] with [newItem].

View File

@@ -4,7 +4,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
package ca.gosyer.common.util package ca.gosyer.core.util
object ImageUtil { object ImageUtil {

View File

@@ -8,6 +8,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jmailen.gradle.kotlinter.tasks.FormatTask import org.jmailen.gradle.kotlinter.tasks.FormatTask
import org.jmailen.gradle.kotlinter.tasks.LintTask import org.jmailen.gradle.kotlinter.tasks.LintTask
import proguard.gradle.ProGuardTask import proguard.gradle.ProGuardTask
import java.nio.file.Files
import kotlin.streams.asSequence
plugins { plugins {
kotlin("jvm") kotlin("jvm")
@@ -19,6 +21,9 @@ plugins {
} }
dependencies { dependencies {
implementation(project(":core"))
implementation(project(":i18n"))
// UI (Compose) // UI (Compose)
implementation(compose.desktop.currentOs) implementation(compose.desktop.currentOs)
implementation(compose.uiTooling) implementation(compose.uiTooling)
@@ -63,7 +68,8 @@ dependencies {
implementation(libs.log4jSlf4j) implementation(libs.log4jSlf4j)
implementation(libs.ktlogging) implementation(libs.ktlogging)
// User storage // Storage
implementation(libs.okio)
implementation(libs.appDirs) implementation(libs.appDirs)
// Preferences // Preferences
@@ -74,6 +80,10 @@ dependencies {
// Utility // Utility
implementation(libs.krokiCoroutines) implementation(libs.krokiCoroutines)
// Localization
implementation(libs.mokoCore)
implementation(libs.mokoCompose)
// Testing // Testing
testImplementation(kotlin("test-junit")) testImplementation(kotlin("test-junit"))
testImplementation(compose("org.jetbrains.compose.ui:ui-test-junit4")) testImplementation(compose("org.jetbrains.compose.ui:ui-test-junit4"))
@@ -126,14 +136,13 @@ tasks {
registerTachideskTasks(project) registerTachideskTasks(project)
task("generateResourceConstants") { task("generateResourceConstants") {
val buildResources = buildConfig.forClass(project.group.toString()+ ".build", "BuildResources") val buildResources = buildConfig.forClass("${project.group}.build", "BuildResources")
doFirst { doFirst {
val langs = listOf("en") + sourceSets["main"].resources val langs = listOf("en") + Files.list(rootDir.toPath().resolve("i18n/src/commonMain/resources/MR/values")).asSequence()
.filter { it.name == "strings.xml" } .map { it.fileName.toString().replace("-r", "-") }
.drop(1) .toList()
.map { it.absolutePath.substringAfter("values-").substringBefore(File.separatorChar) } buildResources.buildConfigField("ca.gosyer.i18n.StringList", "LANGUAGES", langs.joinToString(prefix = "listOf(", postfix = ")") { it.wrap() })
buildResources.buildConfigField("Array<String>", "LANGUAGES", langs.joinToString(prefix = "arrayOf(", postfix = ")") { it.wrap() })
} }
generateBuildConfig { generateBuildConfig {
@@ -176,6 +185,8 @@ compose.desktop {
mainClass = "ca.gosyer.ui.main.MainKt" mainClass = "ca.gosyer.ui.main.MainKt"
nativeDistributions { nativeDistributions {
targetFormats( targetFormats(
// All
TargetFormat.AppImage,
// Windows // Windows
TargetFormat.Msi, TargetFormat.Msi,
TargetFormat.Exe, TargetFormat.Exe,
@@ -228,7 +239,7 @@ buildConfig {
packageName(project.group.toString() + ".build") packageName(project.group.toString() + ".build")
useKotlinOutput { internalVisibility = true } useKotlinOutput { internalVisibility = true }
buildConfigField("String", "NAME", project.name.wrap()) buildConfigField("String", "NAME", rootProject.name.wrap())
buildConfigField("String", "VERSION", project.version.toString().wrap()) buildConfigField("String", "VERSION", project.version.toString().wrap())
buildConfigField("int", "MIGRATION_CODE", migrationCode.toString()) buildConfigField("int", "MIGRATION_CODE", migrationCode.toString())
buildConfigField("boolean", "DEBUG", project.hasProperty("debugApp").toString()) buildConfigField("boolean", "DEBUG", project.hasProperty("debugApp").toString())

View File

@@ -7,9 +7,9 @@
package ca.gosyer.core.service package ca.gosyer.core.service
import ca.gosyer.build.BuildConfig import ca.gosyer.build.BuildConfig
import ca.gosyer.core.lang.throwIfCancellation
import ca.gosyer.data.server.Http import ca.gosyer.data.server.Http
import ca.gosyer.data.server.ServerPreferences import ca.gosyer.data.server.ServerPreferences
import ca.gosyer.util.lang.throwIfCancellation
import ca.gosyer.util.system.CKLogger import ca.gosyer.util.system.CKLogger
import io.ktor.client.features.websocket.ws import io.ktor.client.features.websocket.ws
import io.ktor.http.cio.websocket.Frame import io.ktor.http.cio.websocket.Frame

View File

@@ -29,8 +29,6 @@ import ca.gosyer.data.server.interactions.ExtensionInteractionHandler
import ca.gosyer.data.server.interactions.LibraryInteractionHandler import ca.gosyer.data.server.interactions.LibraryInteractionHandler
import ca.gosyer.data.server.interactions.MangaInteractionHandler import ca.gosyer.data.server.interactions.MangaInteractionHandler
import ca.gosyer.data.server.interactions.SourceInteractionHandler 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.ui.UiPreferences
import ca.gosyer.data.update.UpdateChecker import ca.gosyer.data.update.UpdateChecker
import ca.gosyer.data.update.UpdatePreferences import ca.gosyer.data.update.UpdatePreferences
@@ -85,10 +83,6 @@ val DataModule = module {
.toProvider(KamelConfigProvider::class) .toProvider(KamelConfigProvider::class)
.providesSingleton() .providesSingleton()
bind<XmlResourceBundle>()
.toProvider(ResourceProvider::class)
.providesSingleton()
bind<BackupInteractionHandler>() bind<BackupInteractionHandler>()
.toClass<BackupInteractionHandler>() .toClass<BackupInteractionHandler>()
bind<CategoryInteractionHandler>() bind<CategoryInteractionHandler>()

View File

@@ -6,8 +6,8 @@
package ca.gosyer.data.catalog package ca.gosyer.data.catalog
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
import java.util.Locale import java.util.Locale
class CatalogPreferences(private val preferenceStore: PreferenceStore) { class CatalogPreferences(private val preferenceStore: PreferenceStore) {

View File

@@ -6,8 +6,8 @@
package ca.gosyer.data.extension package ca.gosyer.data.extension
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
import java.util.Locale import java.util.Locale
class ExtensionPreferences(private val preferenceStore: PreferenceStore) { class ExtensionPreferences(private val preferenceStore: PreferenceStore) {

View File

@@ -6,8 +6,8 @@
package ca.gosyer.data.library package ca.gosyer.data.library
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
import ca.gosyer.data.library.model.DisplayMode import ca.gosyer.data.library.model.DisplayMode
class LibraryPreferences(private val preferenceStore: PreferenceStore) { class LibraryPreferences(private val preferenceStore: PreferenceStore) {

View File

@@ -6,8 +6,8 @@
package ca.gosyer.data.migration package ca.gosyer.data.migration
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
class MigrationPreferences(private val preferenceStore: PreferenceStore) { class MigrationPreferences(private val preferenceStore: PreferenceStore) {
fun version(): Preference<Int> { fun version(): Preference<Int> {

View File

@@ -6,8 +6,8 @@
package ca.gosyer.data.reader package ca.gosyer.data.reader
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
import ca.gosyer.data.reader.model.DefaultReaderMode import ca.gosyer.data.reader.model.DefaultReaderMode
import ca.gosyer.data.reader.model.Direction import ca.gosyer.data.reader.model.Direction
import ca.gosyer.data.reader.model.ImageScale import ca.gosyer.data.reader.model.ImageScale

View File

@@ -6,8 +6,8 @@
package ca.gosyer.data.reader package ca.gosyer.data.reader
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
import ca.gosyer.data.reader.model.DefaultReaderMode import ca.gosyer.data.reader.model.DefaultReaderMode
import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer

View File

@@ -6,12 +6,15 @@
package ca.gosyer.data.reader.model package ca.gosyer.data.reader.model
import ca.gosyer.i18n.MR
import dev.icerock.moko.resources.StringResource
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
@Serializable @Serializable
enum class Direction(val res: String) { enum class Direction(@Transient val res: StringResource) {
Down("dir_down"), Down(MR.strings.dir_down),
Left("dir_rtl"), Left(MR.strings.dir_rtl),
Right("dir_ltr"), Right(MR.strings.dir_ltr),
Up("dir_up") Up(MR.strings.dir_up)
} }

View File

@@ -6,14 +6,17 @@
package ca.gosyer.data.reader.model package ca.gosyer.data.reader.model
import ca.gosyer.i18n.MR
import dev.icerock.moko.resources.StringResource
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
@Serializable @Serializable
enum class ImageScale(val res: String) { enum class ImageScale(@Transient val res: StringResource) {
FitScreen("scale_fit_screen"), FitScreen(MR.strings.scale_fit_screen),
Stretch("scale_stretch"), Stretch(MR.strings.scale_stretch),
FitWidth("scale_fit_width"), FitWidth(MR.strings.scale_fit_width),
FitHeight("scale_fit_height"), FitHeight(MR.strings.scale_fit_height),
OriginalSize("scale_original"), OriginalSize(MR.strings.scale_original),
SmartFit("scale_smart"), SmartFit(MR.strings.scale_smart),
} }

View File

@@ -6,12 +6,15 @@
package ca.gosyer.data.reader.model package ca.gosyer.data.reader.model
import ca.gosyer.i18n.MR
import dev.icerock.moko.resources.StringResource
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
@Serializable @Serializable
enum class NavigationMode(val res: String) { enum class NavigationMode(@Transient val res: StringResource) {
LNavigation("nav_l_shaped"), LNavigation(MR.strings.nav_l_shaped),
KindlishNavigation("nav_kindle_ish"), KindlishNavigation(MR.strings.nav_kindle_ish),
EdgeNavigation("nav_edge"), EdgeNavigation(MR.strings.nav_edge),
RightAndLeftNavigation("nav_left_right"), RightAndLeftNavigation(MR.strings.nav_left_right),
} }

View File

@@ -6,8 +6,8 @@
package ca.gosyer.data.server package ca.gosyer.data.server
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
import ca.gosyer.data.server.host.ServerHostPreference import ca.gosyer.data.server.host.ServerHostPreference
class ServerHostPreferences(preferenceStore: PreferenceStore) { class ServerHostPreferences(preferenceStore: PreferenceStore) {

View File

@@ -6,8 +6,8 @@
package ca.gosyer.data.server package ca.gosyer.data.server
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
import ca.gosyer.data.server.model.Auth import ca.gosyer.data.server.model.Auth
import ca.gosyer.data.server.model.Proxy import ca.gosyer.data.server.model.Proxy

View File

@@ -7,7 +7,7 @@
package ca.gosyer.data.server package ca.gosyer.data.server
import ca.gosyer.build.BuildConfig 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.CKLogger
import ca.gosyer.util.system.userDataDir import ca.gosyer.util.system.userDataDir
import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineExceptionHandler

View File

@@ -6,7 +6,7 @@
package ca.gosyer.data.server package ca.gosyer.data.server
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted

View File

@@ -6,8 +6,8 @@
package ca.gosyer.data.server.host package ca.gosyer.data.server.host
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
sealed class ServerHostPreference<T : Any> { sealed class ServerHostPreference<T : Any> {
protected abstract val propertyName: String protected abstract val propertyName: String

View File

@@ -6,13 +6,13 @@
package ca.gosyer.data.server.interactions package ca.gosyer.data.server.interactions
import ca.gosyer.core.lang.withIOContext
import ca.gosyer.data.models.BackupValidationResult import ca.gosyer.data.models.BackupValidationResult
import ca.gosyer.data.server.Http import ca.gosyer.data.server.Http
import ca.gosyer.data.server.ServerPreferences import ca.gosyer.data.server.ServerPreferences
import ca.gosyer.data.server.requests.backupFileExportRequest import ca.gosyer.data.server.requests.backupFileExportRequest
import ca.gosyer.data.server.requests.backupFileImportRequest import ca.gosyer.data.server.requests.backupFileImportRequest
import ca.gosyer.data.server.requests.validateBackupFileRequest import ca.gosyer.data.server.requests.validateBackupFileRequest
import ca.gosyer.util.lang.withIOContext
import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.forms.formData import io.ktor.client.request.forms.formData
import io.ktor.client.request.forms.submitFormWithBinaryData import io.ktor.client.request.forms.submitFormWithBinaryData

View File

@@ -6,6 +6,7 @@
package ca.gosyer.data.server.interactions package ca.gosyer.data.server.interactions
import ca.gosyer.core.lang.withIOContext
import ca.gosyer.data.models.Category import ca.gosyer.data.models.Category
import ca.gosyer.data.models.Manga import ca.gosyer.data.models.Manga
import ca.gosyer.data.server.Http 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.getMangaCategoriesQuery
import ca.gosyer.data.server.requests.getMangaInCategoryQuery import ca.gosyer.data.server.requests.getMangaInCategoryQuery
import ca.gosyer.data.server.requests.removeMangaFromCategoryRequest import ca.gosyer.data.server.requests.removeMangaFromCategoryRequest
import ca.gosyer.util.lang.withIOContext
import io.ktor.client.request.delete import io.ktor.client.request.delete
import io.ktor.client.request.forms.submitForm import io.ktor.client.request.forms.submitForm
import io.ktor.client.request.get import io.ktor.client.request.get

View File

@@ -6,6 +6,7 @@
package ca.gosyer.data.server.interactions package ca.gosyer.data.server.interactions
import ca.gosyer.core.lang.withIOContext
import ca.gosyer.data.models.Chapter import ca.gosyer.data.models.Chapter
import ca.gosyer.data.models.Manga import ca.gosyer.data.models.Manga
import ca.gosyer.data.server.Http 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.updateChapterMetaRequest
import ca.gosyer.data.server.requests.updateChapterRequest import ca.gosyer.data.server.requests.updateChapterRequest
import ca.gosyer.util.compose.imageFromUrl import ca.gosyer.util.compose.imageFromUrl
import ca.gosyer.util.lang.withIOContext
import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.delete import io.ktor.client.request.delete
import io.ktor.client.request.forms.submitForm import io.ktor.client.request.forms.submitForm

View File

@@ -6,12 +6,12 @@
package ca.gosyer.data.server.interactions package ca.gosyer.data.server.interactions
import ca.gosyer.core.lang.withIOContext
import ca.gosyer.data.server.Http import ca.gosyer.data.server.Http
import ca.gosyer.data.server.ServerPreferences import ca.gosyer.data.server.ServerPreferences
import ca.gosyer.data.server.requests.downloadsClearRequest import ca.gosyer.data.server.requests.downloadsClearRequest
import ca.gosyer.data.server.requests.downloadsStartRequest import ca.gosyer.data.server.requests.downloadsStartRequest
import ca.gosyer.data.server.requests.downloadsStopRequest import ca.gosyer.data.server.requests.downloadsStopRequest
import ca.gosyer.util.lang.withIOContext
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.client.statement.HttpResponse import io.ktor.client.statement.HttpResponse
import javax.inject.Inject import javax.inject.Inject

View File

@@ -6,6 +6,7 @@
package ca.gosyer.data.server.interactions package ca.gosyer.data.server.interactions
import ca.gosyer.core.lang.withIOContext
import ca.gosyer.data.models.Extension import ca.gosyer.data.models.Extension
import ca.gosyer.data.server.Http import ca.gosyer.data.server.Http
import ca.gosyer.data.server.ServerPreferences 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.apkUpdateQuery
import ca.gosyer.data.server.requests.extensionListQuery import ca.gosyer.data.server.requests.extensionListQuery
import ca.gosyer.util.compose.imageFromUrl import ca.gosyer.util.compose.imageFromUrl
import ca.gosyer.util.lang.withIOContext
import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.client.statement.HttpResponse import io.ktor.client.statement.HttpResponse

View File

@@ -6,12 +6,12 @@
package ca.gosyer.data.server.interactions package ca.gosyer.data.server.interactions
import ca.gosyer.core.lang.withIOContext
import ca.gosyer.data.models.Manga import ca.gosyer.data.models.Manga
import ca.gosyer.data.server.Http import ca.gosyer.data.server.Http
import ca.gosyer.data.server.ServerPreferences import ca.gosyer.data.server.ServerPreferences
import ca.gosyer.data.server.requests.addMangaToLibraryQuery import ca.gosyer.data.server.requests.addMangaToLibraryQuery
import ca.gosyer.data.server.requests.removeMangaFromLibraryRequest import ca.gosyer.data.server.requests.removeMangaFromLibraryRequest
import ca.gosyer.util.lang.withIOContext
import io.ktor.client.request.delete import io.ktor.client.request.delete
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.client.statement.HttpResponse import io.ktor.client.statement.HttpResponse

View File

@@ -6,6 +6,7 @@
package ca.gosyer.data.server.interactions package ca.gosyer.data.server.interactions
import ca.gosyer.core.lang.withIOContext
import ca.gosyer.data.models.Manga import ca.gosyer.data.models.Manga
import ca.gosyer.data.server.Http import ca.gosyer.data.server.Http
import ca.gosyer.data.server.ServerPreferences 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.mangaThumbnailQuery
import ca.gosyer.data.server.requests.updateMangaMetaRequest import ca.gosyer.data.server.requests.updateMangaMetaRequest
import ca.gosyer.util.compose.imageFromUrl import ca.gosyer.util.compose.imageFromUrl
import ca.gosyer.util.lang.withIOContext
import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.forms.submitForm import io.ktor.client.request.forms.submitForm
import io.ktor.client.request.get import io.ktor.client.request.get

View File

@@ -6,6 +6,7 @@
package ca.gosyer.data.server.interactions package ca.gosyer.data.server.interactions
import ca.gosyer.core.lang.withIOContext
import ca.gosyer.data.models.MangaPage import ca.gosyer.data.models.MangaPage
import ca.gosyer.data.models.Source import ca.gosyer.data.models.Source
import ca.gosyer.data.models.sourcefilters.SourceFilter 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.sourcePopularQuery
import ca.gosyer.data.server.requests.sourceSearchQuery import ca.gosyer.data.server.requests.sourceSearchQuery
import ca.gosyer.data.server.requests.updateSourceSettingQuery import ca.gosyer.data.server.requests.updateSourceSettingQuery
import ca.gosyer.util.lang.withIOContext
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.client.request.parameter import io.ktor.client.request.parameter
import io.ktor.client.request.post import io.ktor.client.request.post

View File

@@ -6,13 +6,13 @@
package ca.gosyer.data.server.interactions package ca.gosyer.data.server.interactions
import ca.gosyer.core.lang.withIOContext
import ca.gosyer.data.models.Category import ca.gosyer.data.models.Category
import ca.gosyer.data.models.Updates import ca.gosyer.data.models.Updates
import ca.gosyer.data.server.Http import ca.gosyer.data.server.Http
import ca.gosyer.data.server.ServerPreferences import ca.gosyer.data.server.ServerPreferences
import ca.gosyer.data.server.requests.fetchUpdatesRequest import ca.gosyer.data.server.requests.fetchUpdatesRequest
import ca.gosyer.data.server.requests.recentUpdatesQuery 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.forms.submitForm
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.client.request.post import io.ktor.client.request.post

View File

@@ -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())
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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>)

View File

@@ -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
)

View File

@@ -6,8 +6,8 @@
package ca.gosyer.data.ui package ca.gosyer.data.ui
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
import ca.gosyer.data.ui.model.StartScreen import ca.gosyer.data.ui.model.StartScreen
import ca.gosyer.data.ui.model.ThemeMode import ca.gosyer.data.ui.model.ThemeMode
import ca.gosyer.data.ui.model.WindowSettings import ca.gosyer.data.ui.model.WindowSettings

View File

@@ -7,10 +7,10 @@
package ca.gosyer.data.update package ca.gosyer.data.update
import ca.gosyer.build.BuildConfig 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.server.Http
import ca.gosyer.data.update.model.GithubRelease 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 io.ktor.client.request.get
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow

View File

@@ -6,8 +6,8 @@
package ca.gosyer.data.update package ca.gosyer.data.update
import ca.gosyer.common.prefs.Preference import ca.gosyer.core.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore import ca.gosyer.core.prefs.PreferenceStore
class UpdatePreferences(private val preferenceStore: PreferenceStore) { class UpdatePreferences(private val preferenceStore: PreferenceStore) {
fun enabled(): Preference<Boolean> { fun enabled(): Preference<Boolean> {

View File

@@ -35,9 +35,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowPosition import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.rememberWindowState import androidx.compose.ui.window.rememberWindowState
import ca.gosyer.common.di.AppScope import ca.gosyer.core.di.AppScope
import ca.gosyer.data.translation.XmlResourceBundle
import ca.gosyer.ui.base.resources.LocalResources
import ca.gosyer.ui.base.theme.AppTheme import ca.gosyer.ui.base.theme.AppTheme
import ca.gosyer.util.lang.launchApplication import ca.gosyer.util.lang.launchApplication
import io.kamel.core.config.KamelConfig import io.kamel.core.config.KamelConfig
@@ -71,7 +69,6 @@ fun WindowDialog(
} }
val icon = painterResource("icon.png") val icon = painterResource("icon.png")
val resources = remember { AppScope.getInstance<XmlResourceBundle>() }
val kamelConfig = remember { AppScope.getInstance<KamelConfig>() } val kamelConfig = remember { AppScope.getInstance<KamelConfig>() }
val windowState = rememberWindowState(size = size, position = WindowPosition(Alignment.Center)) val windowState = rememberWindowState(size = size, position = WindowPosition(Alignment.Center))
@@ -99,7 +96,6 @@ fun WindowDialog(
alwaysOnTop = forceFocus alwaysOnTop = forceFocus
) { ) {
CompositionLocalProvider( CompositionLocalProvider(
LocalResources provides resources,
LocalKamelConfig provides kamelConfig LocalKamelConfig provides kamelConfig
) { ) {
AppTheme { AppTheme {
@@ -149,7 +145,6 @@ fun WindowDialog(
} }
val icon = painterResource("icon.png") val icon = painterResource("icon.png")
val resources = remember { AppScope.getInstance<XmlResourceBundle>() }
val kamelConfig = remember { AppScope.getInstance<KamelConfig>() } val kamelConfig = remember { AppScope.getInstance<KamelConfig>() }
val windowState = rememberWindowState(size = size, position = WindowPosition.Aligned(Alignment.Center)) val windowState = rememberWindowState(size = size, position = WindowPosition.Aligned(Alignment.Center))
@@ -169,7 +164,6 @@ fun WindowDialog(
alwaysOnTop = forceFocus, alwaysOnTop = forceFocus,
) { ) {
CompositionLocalProvider( CompositionLocalProvider(
LocalResources provides resources,
LocalKamelConfig provides kamelConfig LocalKamelConfig provides kamelConfig
) { ) {
AppTheme { AppTheme {

View File

@@ -37,7 +37,8 @@ import ca.gosyer.data.download.model.DownloadState
import ca.gosyer.data.models.Chapter import ca.gosyer.data.models.Chapter
import ca.gosyer.data.models.Manga import ca.gosyer.data.models.Manga
import ca.gosyer.data.server.interactions.ChapterInteractionHandler 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.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
@@ -143,7 +144,7 @@ private fun DownloadingIconButton(downloadChapter: DownloadChapter?, onClick: ()
downloadChapter?.mangaId to downloadChapter?.chapterIndex, downloadChapter?.mangaId to downloadChapter?.chapterIndex,
{ {
DropdownMenuItem(onClick = onClick) { 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, chapter,
{ {
DropdownMenuItem(onClick = onClick) { DropdownMenuItem(onClick = onClick) {
Text(stringResource("action_delete")) Text(stringResource(MR.strings.action_delete))
} }
} }
) { ) {

View File

@@ -15,7 +15,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier 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 @Composable
fun LoadingScreen( fun LoadingScreen(
@@ -24,7 +25,7 @@ fun LoadingScreen(
/*@FloatRange(from = 0.0, to = 1.0)*/ /*@FloatRange(from = 0.0, to = 1.0)*/
progress: Float = 0.0F, progress: Float = 0.0F,
errorMessage: String? = null, errorMessage: String? = null,
retryMessage: String = stringResource("action_retry"), retryMessage: String = stringResource(MR.strings.action_retry),
retry: (() -> Unit)? = null retry: (() -> Unit)? = null
) { ) {
BoxWithConstraints(modifier) { BoxWithConstraints(modifier) {

View File

@@ -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.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp 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 @Composable
fun Toolbar( fun Toolbar(
@@ -120,7 +121,7 @@ fun Toolbar(
Row { Row {
actions() actions()
if (closable) { if (closable) {
TextActionIcon(onClick = onClose, stringResource("action_close"), Icons.Rounded.Close) TextActionIcon(onClick = onClose, stringResource(MR.strings.action_close), Icons.Rounded.Close)
} }
} }
} }

View File

@@ -8,7 +8,7 @@ package ca.gosyer.ui.base.prefs
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb 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.CoroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted

View File

@@ -6,7 +6,7 @@
package ca.gosyer.ui.base.prefs 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.CoroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted

View File

@@ -6,7 +6,7 @@
package ca.gosyer.ui.base.prefs 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.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn

View File

@@ -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)
}

View File

@@ -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()

View File

@@ -7,7 +7,7 @@
package ca.gosyer.ui.base.theme package ca.gosyer.ui.base.theme
import androidx.compose.ui.graphics.Color 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.data.ui.UiPreferences
import ca.gosyer.ui.base.prefs.PreferenceMutableStateFlow import ca.gosyer.ui.base.prefs.PreferenceMutableStateFlow
import ca.gosyer.ui.base.prefs.asColor import ca.gosyer.ui.base.prefs.asColor

View File

@@ -10,7 +10,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisallowComposableCalls import androidx.compose.runtime.DisallowComposableCalls
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import ca.gosyer.common.di.AppScope import ca.gosyer.core.di.AppScope
import toothpick.Toothpick import toothpick.Toothpick
import toothpick.ktp.binding.module import toothpick.ktp.binding.module
import toothpick.ktp.extension.getInstance import toothpick.ktp.extension.getInstance

View File

@@ -6,7 +6,7 @@
package ca.gosyer.ui.base.vm 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 ca.gosyer.ui.base.prefs.PreferenceMutableStateFlow
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel

View File

@@ -12,8 +12,9 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
import ca.gosyer.build.BuildConfig import ca.gosyer.build.BuildConfig
import ca.gosyer.i18n.MR
import ca.gosyer.ui.base.WindowDialog 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 import kotlinx.coroutines.flow.MutableStateFlow
fun openRenameDialog( fun openRenameDialog(
@@ -54,7 +55,7 @@ fun openDeleteDialog(
}, },
negativeButtonText = "No" negativeButtonText = "No"
) { ) {
Text(stringResource("categories_delete_confirm", category.name)) Text(stringResource(MR.strings.categories_delete_confirm, category.name))
} }
} }

View File

@@ -46,7 +46,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ca.gosyer.build.BuildConfig 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.ui.base.vm.viewModel
import ca.gosyer.util.compose.ThemedWindow import ca.gosyer.util.compose.ThemedWindow
import ca.gosyer.util.lang.launchApplication import ca.gosyer.util.lang.launchApplication
@@ -114,7 +115,7 @@ fun CategoriesMenu(notifyFinished: (() -> Unit)? = null) {
} }
} }
ExtendedFloatingActionButton( ExtendedFloatingActionButton(
text = { Text(text = stringResource("action_add")) }, text = { Text(text = stringResource(MR.strings.action_add)) },
icon = { Icon(imageVector = Icons.Rounded.Add, contentDescription = null) }, icon = { Icon(imageVector = Icons.Rounded.Add, contentDescription = null) },
modifier = Modifier.align(Alignment.BottomEnd).padding(16.dp), modifier = Modifier.align(Alignment.BottomEnd).padding(16.dp),
onClick = { onClick = {

View File

@@ -6,10 +6,10 @@
package ca.gosyer.ui.categories package ca.gosyer.ui.categories
import ca.gosyer.core.lang.throwIfCancellation
import ca.gosyer.data.models.Category import ca.gosyer.data.models.Category
import ca.gosyer.data.server.interactions.CategoryInteractionHandler import ca.gosyer.data.server.interactions.CategoryInteractionHandler
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.CKLogger
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow

View File

@@ -57,7 +57,8 @@ import ca.gosyer.ui.base.components.MangaListItemSubtitle
import ca.gosyer.ui.base.components.MangaListItemTitle import ca.gosyer.ui.base.components.MangaListItemTitle
import ca.gosyer.ui.base.components.Toolbar import ca.gosyer.ui.base.components.Toolbar
import ca.gosyer.ui.base.components.mangaAspectRatio 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.base.vm.viewModel
import ca.gosyer.ui.manga.openMangaMenu import ca.gosyer.ui.manga.openMangaMenu
import ca.gosyer.util.compose.ThemedWindow import ca.gosyer.util.compose.ThemedWindow
@@ -83,16 +84,16 @@ fun DownloadsMenu(onMangaClick: (Long) -> Unit) {
Column { Column {
Toolbar( Toolbar(
stringResource("location_downloads"), stringResource(MR.strings.location_downloads),
closable = false, closable = false,
actions = { actions = {
val downloadStatus by vm.downloaderStatus.collectAsState() val downloadStatus by vm.downloaderStatus.collectAsState()
if (downloadStatus == DownloaderStatus.Started) { 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 { } 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 { Box {
@@ -170,10 +171,10 @@ fun DownloadsItem(
item.mangaId to item.chapterIndex, item.mangaId to item.chapterIndex,
{ {
DropdownMenuItem(onClick = { onClickCancel(item.chapter) }) { DropdownMenuItem(onClick = { onClickCancel(item.chapter) }) {
Text(stringResource("action_cancel")) Text(stringResource(MR.strings.action_cancel))
} }
DropdownMenuItem(onClick = { onClickMoveToBottom(item.chapter) }) { DropdownMenuItem(onClick = { onClickMoveToBottom(item.chapter) }) {
Text(stringResource("action_move_to_bottom")) Text(stringResource(MR.strings.action_move_to_bottom))
} }
} }
) { ) {

View File

@@ -53,7 +53,8 @@ import ca.gosyer.ui.base.components.KamelImage
import ca.gosyer.ui.base.components.LoadingScreen import ca.gosyer.ui.base.components.LoadingScreen
import ca.gosyer.ui.base.components.TextActionIcon import ca.gosyer.ui.base.components.TextActionIcon
import ca.gosyer.ui.base.components.Toolbar 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.base.vm.viewModel
import ca.gosyer.util.compose.ThemedWindow import ca.gosyer.util.compose.ThemedWindow
import ca.gosyer.util.compose.persistentLazyListState import ca.gosyer.util.compose.persistentLazyListState
@@ -146,7 +147,7 @@ fun ExtensionsToolbar(
setEnabledLanguages: (Set<String>) -> Unit setEnabledLanguages: (Set<String>) -> Unit
) { ) {
Toolbar( Toolbar(
stringResource("location_extensions"), stringResource(MR.strings.location_extensions),
closable = false, closable = false,
searchText = searchText, searchText = searchText,
search = search, search = search,
@@ -158,7 +159,7 @@ fun ExtensionsToolbar(
setEnabledLanguages(enabledLangs.value) setEnabledLanguages(enabledLangs.value)
} }
}, },
stringResource("enabled_languages"), stringResource(MR.strings.enabled_languages),
Icons.Rounded.Translate Icons.Rounded.Translate
) )
} }
@@ -209,9 +210,9 @@ fun ExtensionItem(
) { ) {
Text( Text(
when { when {
extension.hasUpdate -> stringResource("action_update") extension.hasUpdate -> stringResource(MR.strings.action_update)
extension.installed -> stringResource("action_uninstall") extension.installed -> stringResource(MR.strings.action_uninstall)
else -> stringResource("action_install") else -> stringResource(MR.strings.action_install)
} }
) )
} }

View File

@@ -6,12 +6,12 @@
package ca.gosyer.ui.extensions package ca.gosyer.ui.extensions
import ca.gosyer.core.lang.throwIfCancellation
import ca.gosyer.data.extension.ExtensionPreferences import ca.gosyer.data.extension.ExtensionPreferences
import ca.gosyer.data.models.Extension import ca.gosyer.data.models.Extension
import ca.gosyer.data.server.interactions.ExtensionInteractionHandler 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.ui.base.vm.ViewModel
import ca.gosyer.util.lang.throwIfCancellation
import ca.gosyer.util.system.CKLogger import ca.gosyer.util.system.CKLogger
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
@@ -24,7 +24,6 @@ import javax.inject.Inject
class ExtensionsMenuViewModel @Inject constructor( class ExtensionsMenuViewModel @Inject constructor(
private val extensionHandler: ExtensionInteractionHandler, private val extensionHandler: ExtensionInteractionHandler,
private val resources: XmlResourceBundle,
extensionPreferences: ExtensionPreferences extensionPreferences: ExtensionPreferences
) : ViewModel() { ) : ViewModel() {
private val _enabledLangs = extensionPreferences.languages().asStateFlow() private val _enabledLangs = extensionPreferences.languages().asStateFlow()
@@ -129,10 +128,10 @@ class ExtensionsMenuViewModel @Inject constructor(
val available = filter { !it.installed }.sortedWith(comparator) val available = filter { !it.installed }.sortedWith(comparator)
return mapOf( 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 { ).filterNot { it.value.isEmpty() } + available.groupBy { it.lang }.mapKeys {
if (it.key == "all") { if (it.key == "all") {
resources.getStringA("all") MR.strings.all.localized()
} else { } else {
Locale.forLanguageTag(it.key).displayName Locale.forLanguageTag(it.key).displayName
} }

View File

@@ -32,7 +32,8 @@ import ca.gosyer.data.models.Category
import ca.gosyer.data.models.Manga import ca.gosyer.data.models.Manga
import ca.gosyer.ui.base.components.LoadingScreen import ca.gosyer.ui.base.components.LoadingScreen
import ca.gosyer.ui.base.components.Toolbar 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.base.vm.viewModel
import ca.gosyer.ui.manga.openMangaMenu import ca.gosyer.ui.manga.openMangaMenu
import ca.gosyer.util.compose.ThemedWindow import ca.gosyer.util.compose.ThemedWindow
@@ -100,7 +101,7 @@ fun LibraryScreen(bundle: Bundle, onClickManga: (Long) -> Unit = ::openMangaMenu
} }
)*/ )*/
Toolbar( Toolbar(
stringResource("location_library"), stringResource(MR.strings.location_library),
closable = false, closable = false,
searchText = query, searchText = query,
search = vm::updateQuery search = vm::updateQuery

View File

@@ -6,6 +6,8 @@
package ca.gosyer.ui.library 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.library.LibraryPreferences
import ca.gosyer.data.models.Category import ca.gosyer.data.models.Category
import ca.gosyer.data.models.Manga 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.ui.base.vm.ViewModel
import ca.gosyer.util.compose.saveIntInBundle import ca.gosyer.util.compose.saveIntInBundle
import ca.gosyer.util.compose.saveStringInBundle 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 com.github.zsoltk.compose.savedinstancestate.Bundle
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll

View File

@@ -21,14 +21,16 @@ import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material.icons.rounded.Store import androidx.compose.material.icons.rounded.Store
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import ca.gosyer.i18n.MR
import ca.gosyer.ui.extensions.openExtensionsMenu import ca.gosyer.ui.extensions.openExtensionsMenu
import ca.gosyer.ui.library.openLibraryMenu import ca.gosyer.ui.library.openLibraryMenu
import ca.gosyer.ui.main.components.DownloadsExtraInfo import ca.gosyer.ui.main.components.DownloadsExtraInfo
import ca.gosyer.ui.sources.openSourcesMenu import ca.gosyer.ui.sources.openSourcesMenu
import com.github.zsoltk.compose.router.BackStack import com.github.zsoltk.compose.router.BackStack
import dev.icerock.moko.resources.StringResource
enum class TopLevelMenus( enum class TopLevelMenus(
val textKey: String, val textKey: StringResource,
val unselectedIcon: ImageVector, val unselectedIcon: ImageVector,
val selectedIcon: ImageVector, val selectedIcon: ImageVector,
val menu: Routes, val menu: Routes,
@@ -36,12 +38,12 @@ enum class TopLevelMenus(
val openInNewWindow: () -> Unit = {}, val openInNewWindow: () -> Unit = {},
val extraInfo: (@Composable () -> Unit)? = null val extraInfo: (@Composable () -> Unit)? = null
) { ) {
Library("location_library", Icons.Outlined.Book, Icons.Rounded.Book, Routes.Library, true, ::openLibraryMenu), Library(MR.strings.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), Updates(MR.strings.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), Sources(MR.strings.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), Extensions(MR.strings.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() }), Downloads(MR.strings.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); Settings(MR.strings.location_settings, Icons.Outlined.Settings, Icons.Rounded.Settings, Routes.Settings, false);
fun isSelected(backStack: BackStack<Routes>) = backStack.elements.first() == menu fun isSelected(backStack: BackStack<Routes>) = backStack.elements.first() == menu
} }

View File

@@ -18,9 +18,10 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ca.gosyer.core.service.WebsocketService 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.base.vm.viewModel
import ca.gosyer.ui.downloads.DownloadsMenuViewModel import ca.gosyer.ui.downloads.DownloadsMenuViewModel
import dev.icerock.moko.resources.compose.stringResource
@Composable @Composable
fun DownloadsExtraInfo() { fun DownloadsExtraInfo() {
@@ -28,10 +29,10 @@ fun DownloadsExtraInfo() {
val status by vm.serviceStatus.collectAsState() val status by vm.serviceStatus.collectAsState()
val list by vm.downloadQueue.collectAsState() val list by vm.downloadQueue.collectAsState()
val text = when (status) { val text = when (status) {
WebsocketService.Status.STARTING -> stringResource("downloads_loading") WebsocketService.Status.STARTING -> stringResource(MR.strings.downloads_loading)
WebsocketService.Status.RUNNING -> { WebsocketService.Status.RUNNING -> {
if (list.isNotEmpty()) { if (list.isNotEmpty()) {
stringResource("downloads_remaining", list.size) stringResource(MR.strings.downloads_remaining, list.size)
} else null } else null
} }
WebsocketService.Status.STOPPED -> null WebsocketService.Status.STOPPED -> null
@@ -45,7 +46,7 @@ fun DownloadsExtraInfo() {
} else if (status == WebsocketService.Status.STOPPED) { } else if (status == WebsocketService.Status.STOPPED) {
Surface(onClick = vm::restartDownloader, shape = RoundedCornerShape(4.dp)) { Surface(onClick = vm::restartDownloader, shape = RoundedCornerShape(4.dp)) {
Text( Text(
stringResource("downloads_stopped"), stringResource(MR.strings.downloads_stopped),
style = MaterialTheme.typography.body2, style = MaterialTheme.typography.body2,
color = Color.Red.copy(alpha = ContentAlpha.disabled) color = Color.Red.copy(alpha = ContentAlpha.disabled)
) )

View File

@@ -26,7 +26,8 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ca.gosyer.ui.base.components.combinedMouseClickable 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.Routes
import ca.gosyer.ui.main.TopLevelMenus import ca.gosyer.ui.main.TopLevelMenus

View File

@@ -14,12 +14,13 @@ import androidx.compose.ui.window.Notification
import androidx.compose.ui.window.Tray import androidx.compose.ui.window.Tray
import androidx.compose.ui.window.rememberTrayState import androidx.compose.ui.window.rememberTrayState
import ca.gosyer.build.BuildConfig import ca.gosyer.build.BuildConfig
import ca.gosyer.data.translation.XmlResourceBundle import ca.gosyer.i18n.MR
import ca.gosyer.ui.base.vm.viewModel import ca.gosyer.ui.base.vm.viewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.Locale
@Composable @Composable
fun ApplicationScope.Tray(icon: Painter, resources: XmlResourceBundle) { fun ApplicationScope.Tray(icon: Painter) {
val vm = viewModel<TrayViewModel>() val vm = viewModel<TrayViewModel>()
val trayState = rememberTrayState() val trayState = rememberTrayState()
Tray( Tray(
@@ -27,7 +28,7 @@ fun ApplicationScope.Tray(icon: Painter, resources: XmlResourceBundle) {
trayState, trayState,
tooltip = BuildConfig.NAME, tooltip = BuildConfig.NAME,
menu = { 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 { vm.updateFound.collect {
trayState.sendNotification( trayState.sendNotification(
Notification( Notification(
resources.getStringA("new_update_title"), MR.strings.new_update_title.localized(),
resources.getString("new_update_message", it.version), MR.strings.new_update_message.localized(Locale.getDefault(), it.version),
Notification.Type.Info Notification.Type.Info
) )
) )

View File

@@ -25,22 +25,20 @@ import androidx.compose.ui.window.Window
import androidx.compose.ui.window.awaitApplication import androidx.compose.ui.window.awaitApplication
import androidx.compose.ui.window.rememberWindowState import androidx.compose.ui.window.rememberWindowState
import ca.gosyer.build.BuildConfig import ca.gosyer.build.BuildConfig
import ca.gosyer.core.lang.withUIContext
import ca.gosyer.core.logging.initializeLogger import ca.gosyer.core.logging.initializeLogger
import ca.gosyer.data.DataModule import ca.gosyer.data.DataModule
import ca.gosyer.data.migration.Migrations import ca.gosyer.data.migration.Migrations
import ca.gosyer.data.server.ServerService import ca.gosyer.data.server.ServerService
import ca.gosyer.data.server.ServerService.ServerResult import ca.gosyer.data.server.ServerService.ServerResult
import ca.gosyer.data.translation.XmlResourceBundle
import ca.gosyer.data.ui.UiPreferences import ca.gosyer.data.ui.UiPreferences
import ca.gosyer.data.ui.model.ThemeMode import ca.gosyer.data.ui.model.ThemeMode
import ca.gosyer.i18n.MR
import ca.gosyer.ui.base.WindowDialog import ca.gosyer.ui.base.WindowDialog
import ca.gosyer.ui.base.components.LoadingScreen import ca.gosyer.ui.base.components.LoadingScreen
import ca.gosyer.ui.base.prefs.asStateIn 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.base.theme.AppTheme
import ca.gosyer.ui.main.components.Tray import ca.gosyer.ui.main.components.Tray
import ca.gosyer.util.lang.withUIContext
import ca.gosyer.util.system.getAsFlow import ca.gosyer.util.system.getAsFlow
import ca.gosyer.util.system.userDataDir import ca.gosyer.util.system.userDataDir
import com.github.weisj.darklaf.LafManager 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.BackPressHandler
import com.github.zsoltk.compose.backpress.LocalBackPressHandler import com.github.zsoltk.compose.backpress.LocalBackPressHandler
import com.github.zsoltk.compose.savedinstancestate.Bundle import com.github.zsoltk.compose.savedinstancestate.Bundle
import dev.icerock.moko.resources.compose.stringResource
import io.kamel.core.config.KamelConfig import io.kamel.core.config.KamelConfig
import io.kamel.image.config.LocalKamelConfig import io.kamel.image.config.LocalKamelConfig
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
@@ -98,7 +97,6 @@ suspend fun main() {
} }
} }
val resources = scope.getInstance<XmlResourceBundle>()
val kamelConfig = scope.getInstance<KamelConfig>() val kamelConfig = scope.getInstance<KamelConfig>()
// Set the Compose constants before any // Set the Compose constants before any
@@ -154,16 +152,16 @@ suspend fun main() {
val icon = painterResource("icon.png") val icon = painterResource("icon.png")
Tray(icon, resources) Tray(icon)
Window( Window(
onCloseRequest = { onCloseRequest = {
if (confirmExit.value) { if (confirmExit.value) {
WindowDialog( WindowDialog(
title = resources.getStringA("confirm_exit"), title = MR.strings.confirm_exit.localized(),
onPositiveButton = ::exitApplication onPositiveButton = ::exitApplication
) { ) {
Text(stringResource("confirm_exit_message")) Text(stringResource(MR.strings.confirm_exit_message))
} }
} else { } else {
exitApplication() exitApplication()
@@ -190,7 +188,6 @@ suspend fun main() {
AppTheme { AppTheme {
CompositionLocalProvider( CompositionLocalProvider(
LocalBackPressHandler provides backPressHandler, LocalBackPressHandler provides backPressHandler,
LocalResources provides resources,
LocalKamelConfig provides kamelConfig LocalKamelConfig provides kamelConfig
) { ) {
Crossfade(serverService.initialized.collectAsState().value) { initialized -> Crossfade(serverService.initialized.collectAsState().value) { initialized ->
@@ -208,8 +205,8 @@ suspend fun main() {
Surface { Surface {
LoadingScreen( LoadingScreen(
initialized == ServerResult.STARTING, initialized == ServerResult.STARTING,
errorMessage = stringResource("unable_to_start_server"), errorMessage = stringResource(MR.strings.unable_to_start_server),
retryMessage = stringResource("action_start_anyway"), retryMessage = stringResource(MR.strings.action_start_anyway),
retry = serverService::startAnyway retry = serverService::startAnyway
) )
} }

View File

@@ -29,10 +29,11 @@ import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ca.gosyer.i18n.MR
import ca.gosyer.ui.base.components.ChapterDownloadIcon import ca.gosyer.ui.base.components.ChapterDownloadIcon
import ca.gosyer.ui.base.components.ChapterDownloadItem import ca.gosyer.ui.base.components.ChapterDownloadItem
import ca.gosyer.ui.base.components.contextMenuClickable 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 import java.time.Instant
@Composable @Composable
@@ -90,7 +91,7 @@ fun ChapterItem(
if (length > 0) append("") if (length > 0) append("")
append( append(
AnnotatedString( AnnotatedString(
stringResource("page_progress", (chapter.lastPageRead + 1)), stringResource(MR.strings.page_progress, (chapter.lastPageRead + 1)),
SpanStyle(color = LocalContentColor.current.copy(alpha = ContentAlpha.disabled)) SpanStyle(color = LocalContentColor.current.copy(alpha = ContentAlpha.disabled))
) )
) )

View File

@@ -51,6 +51,7 @@ import androidx.compose.ui.util.fastForEach
import ca.gosyer.build.BuildConfig import ca.gosyer.build.BuildConfig
import ca.gosyer.data.models.Category import ca.gosyer.data.models.Category
import ca.gosyer.data.models.Manga import ca.gosyer.data.models.Manga
import ca.gosyer.i18n.MR
import ca.gosyer.ui.base.WindowDialog import ca.gosyer.ui.base.WindowDialog
import ca.gosyer.ui.base.components.ErrorScreen import ca.gosyer.ui.base.components.ErrorScreen
import ca.gosyer.ui.base.components.KamelImage 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.MenuController
import ca.gosyer.ui.base.components.TextActionIcon import ca.gosyer.ui.base.components.TextActionIcon
import ca.gosyer.ui.base.components.Toolbar 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.base.vm.viewModel
import ca.gosyer.ui.reader.openReaderMenu import ca.gosyer.ui.reader.openReaderMenu
import ca.gosyer.util.compose.ThemedWindow import ca.gosyer.util.compose.ThemedWindow
import ca.gosyer.util.lang.launchApplication import ca.gosyer.util.lang.launchApplication
import com.google.accompanist.flowlayout.FlowRow import com.google.accompanist.flowlayout.FlowRow
import dev.icerock.moko.resources.compose.stringResource
import io.kamel.image.lazyPainterResource import io.kamel.image.lazyPainterResource
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@@ -100,20 +101,20 @@ fun MangaMenu(mangaId: Long, menuController: MenuController? = LocalMenuControll
Box { Box {
Column { Column {
Toolbar( Toolbar(
stringResource("location_manga"), stringResource(MR.strings.location_manga),
menuController, menuController,
menuController != null, menuController != null,
actions = { actions = {
AnimatedVisibility(categoriesExist && manga?.inLibrary == true) { AnimatedVisibility(categoriesExist && manga?.inLibrary == true) {
TextActionIcon( TextActionIcon(
vm::setCategories, vm::setCategories,
stringResource("edit_categories"), stringResource(MR.strings.edit_categories),
Icons.Rounded.Label Icons.Rounded.Label
) )
} }
TextActionIcon( TextActionIcon(
vm::toggleFavorite, 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) { if (manga?.inLibrary == true) {
Icons.Rounded.Favorite Icons.Rounded.Favorite
} else { } else {
@@ -123,7 +124,7 @@ fun MangaMenu(mangaId: Long, menuController: MenuController? = LocalMenuControll
) )
TextActionIcon( TextActionIcon(
vm::refreshManga, vm::refreshManga,
stringResource("action_refresh_manga"), stringResource(MR.strings.action_refresh_manga),
Icons.Rounded.Refresh, Icons.Rounded.Refresh,
!isLoading !isLoading
) )
@@ -155,7 +156,7 @@ fun MangaMenu(mangaId: Long, menuController: MenuController? = LocalMenuControll
} else if (!isLoading) { } else if (!isLoading) {
item { item {
ErrorScreen( ErrorScreen(
stringResource("no_chapters_found"), stringResource(MR.strings.no_chapters_found),
Modifier.height(400.dp).fillMaxWidth(), Modifier.height(400.dp).fillMaxWidth(),
retry = vm::loadChapters retry = vm::loadChapters
) )
@@ -170,7 +171,7 @@ fun MangaMenu(mangaId: Long, menuController: MenuController? = LocalMenuControll
) )
} }
} else if (!isLoading) { } else if (!isLoading) {
ErrorScreen(stringResource("failed_manga_fetch"), retry = vm::loadManga) ErrorScreen(stringResource(MR.strings.failed_manga_fetch), retry = vm::loadManga)
} }
} }
} }

View File

@@ -6,6 +6,8 @@
package ca.gosyer.ui.manga 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.download.DownloadService
import ca.gosyer.data.models.Category import ca.gosyer.data.models.Category
import ca.gosyer.data.models.Chapter 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.data.ui.UiPreferences
import ca.gosyer.ui.base.components.ChapterDownloadItem import ca.gosyer.ui.base.components.ChapterDownloadItem
import ca.gosyer.ui.base.vm.ViewModel 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.async
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow

View File

@@ -54,18 +54,16 @@ import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowPlacement import androidx.compose.ui.window.WindowPlacement
import androidx.compose.ui.window.rememberWindowState import androidx.compose.ui.window.rememberWindowState
import ca.gosyer.build.BuildConfig 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.Direction
import ca.gosyer.data.reader.model.ImageScale import ca.gosyer.data.reader.model.ImageScale
import ca.gosyer.data.reader.model.NavigationMode import ca.gosyer.data.reader.model.NavigationMode
import ca.gosyer.data.translation.XmlResourceBundle
import ca.gosyer.data.ui.UiPreferences import ca.gosyer.data.ui.UiPreferences
import ca.gosyer.data.ui.model.WindowSettings 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.ErrorScreen
import ca.gosyer.ui.base.components.LoadingScreen import ca.gosyer.ui.base.components.LoadingScreen
import ca.gosyer.ui.base.components.mangaAspectRatio 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.theme.AppTheme
import ca.gosyer.ui.base.vm.viewModel import ca.gosyer.ui.base.vm.viewModel
import ca.gosyer.ui.reader.model.Navigation 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.ContinuousReader
import ca.gosyer.ui.reader.viewer.PagerReader import ca.gosyer.ui.reader.viewer.PagerReader
import ca.gosyer.util.lang.launchApplication import ca.gosyer.util.lang.launchApplication
import dev.icerock.moko.resources.compose.stringResource
import io.kamel.core.config.KamelConfig import io.kamel.core.config.KamelConfig
import io.kamel.image.config.LocalKamelConfig import io.kamel.image.config.LocalKamelConfig
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
@@ -108,7 +107,6 @@ fun openReaderMenu(chapterIndex: Int, mangaId: Long) {
placement placement
) = windowSettings.get().get() ) = windowSettings.get().get()
val resources = AppScope.getInstance<XmlResourceBundle>()
val kamelConfig = AppScope.getInstance<KamelConfig>() val kamelConfig = AppScope.getInstance<KamelConfig>()
launchApplication { launchApplication {
@@ -144,7 +142,6 @@ fun openReaderMenu(chapterIndex: Int, mangaId: Long) {
} }
) { ) {
CompositionLocalProvider( CompositionLocalProvider(
LocalResources provides resources,
LocalKamelConfig provides kamelConfig LocalKamelConfig provides kamelConfig
) { ) {
AppTheme { AppTheme {
@@ -292,7 +289,7 @@ fun ReaderMenu(
SideMenuButton(sideMenuOpen, onOpenSideMenuClicked = { sideMenuOpen = true }) SideMenuButton(sideMenuOpen, onOpenSideMenuClicked = { sideMenuOpen = true })
} }
} else { } else {
ErrorScreen(stringResource("no_pages_found")) ErrorScreen(stringResource(MR.strings.no_pages_found))
} }
} else { } else {
LoadingScreen( LoadingScreen(
@@ -354,15 +351,15 @@ fun ChapterSeparator(
Column { Column {
when { when {
previousChapter == null && nextChapter != null -> { previousChapter == null && nextChapter != null -> {
Text(stringResource("no_previous_chapter")) Text(stringResource(MR.strings.no_previous_chapter))
} }
previousChapter != null && nextChapter != null -> { 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)) 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 -> { previousChapter != null && nextChapter == null -> {
Text(stringResource("no_next_chapter")) Text(stringResource(MR.strings.no_next_chapter))
} }
} }
} }

View File

@@ -6,6 +6,7 @@
package ca.gosyer.ui.reader package ca.gosyer.ui.reader
import ca.gosyer.core.lang.throwIfCancellation
import ca.gosyer.data.models.Chapter import ca.gosyer.data.models.Chapter
import ca.gosyer.data.models.Manga import ca.gosyer.data.models.Manga
import ca.gosyer.data.models.MangaMeta 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.ReaderChapter
import ca.gosyer.ui.reader.model.ReaderPage import ca.gosyer.ui.reader.model.ReaderPage
import ca.gosyer.ui.reader.model.ViewerChapters import ca.gosyer.ui.reader.model.ViewerChapters
import ca.gosyer.util.lang.throwIfCancellation
import ca.gosyer.util.system.CKLogger import ca.gosyer.util.system.CKLogger
import ca.gosyer.util.system.getAsFlow import ca.gosyer.util.system.getAsFlow
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi

View File

@@ -39,12 +39,13 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import ca.gosyer.common.util.replace import ca.gosyer.core.util.replace
import ca.gosyer.data.models.Chapter import ca.gosyer.data.models.Chapter
import ca.gosyer.data.models.ChapterMeta import ca.gosyer.data.models.ChapterMeta
import ca.gosyer.data.models.MangaMeta import ca.gosyer.data.models.MangaMeta
import ca.gosyer.ui.base.components.Spinner 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.ui.reader.model.ReaderChapter
import ca.gosyer.util.system.kLogger import ca.gosyer.util.system.kLogger
import kotlin.math.roundToInt import kotlin.math.roundToInt
@@ -78,7 +79,7 @@ fun ReaderSideMenu(
@Composable @Composable
fun ReaderModeSetting(readerModes: List<String>, selectedMode: String, onSetReaderMode: (String) -> Unit) { fun ReaderModeSetting(readerModes: List<String>, selectedMode: String, onSetReaderMode: (String) -> Unit) {
val modes = remember(readerModes) { listOf(MangaMeta.DEFAULT_READER_MODE) + readerModes } 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 displayModes = remember(modes, defaultModeString) { modes.replace(0, defaultModeString) }
val selectedModeIndex = remember(modes, selectedMode) { modes.indexOf(selectedMode) } val selectedModeIndex = remember(modes, selectedMode) { modes.indexOf(selectedMode) }
Row( Row(
@@ -88,7 +89,7 @@ fun ReaderModeSetting(readerModes: List<String>, selectedMode: String, onSetRead
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween 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)) Spacer(Modifier.width(8.dp))
Spinner( Spinner(
modifier = Modifier.weight(0.75f), modifier = Modifier.weight(0.75f),
@@ -144,14 +145,14 @@ private fun NavigateChapters(loadPrevChapter: () -> Unit, loadNextChapter: () ->
Row(horizontalArrangement = Arrangement.SpaceBetween,) { Row(horizontalArrangement = Arrangement.SpaceBetween,) {
OutlinedButton(loadPrevChapter, Modifier.weight(0.5F)) { OutlinedButton(loadPrevChapter, Modifier.weight(0.5F)) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
val nextChapter = stringResource("nav_prev_chapter") val nextChapter = stringResource(MR.strings.nav_prev_chapter)
Icon(Icons.Rounded.NavigateBefore, nextChapter) Icon(Icons.Rounded.NavigateBefore, nextChapter)
Text(nextChapter, fontSize = 10.sp) Text(nextChapter, fontSize = 10.sp)
} }
} }
OutlinedButton(loadNextChapter, Modifier.weight(0.5F)) { OutlinedButton(loadNextChapter, Modifier.weight(0.5F)) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
val nextChapter = stringResource("nav_next_chapter") val nextChapter = stringResource(MR.strings.nav_next_chapter)
Text(nextChapter, fontSize = 10.sp) Text(nextChapter, fontSize = 10.sp)
Icon(Icons.Rounded.NavigateNext, nextChapter) Icon(Icons.Rounded.NavigateNext, nextChapter)
} }

View File

@@ -6,11 +6,11 @@
package ca.gosyer.ui.reader.loader package ca.gosyer.ui.reader.loader
import ca.gosyer.core.lang.throwIfCancellation
import ca.gosyer.data.reader.ReaderPreferences import ca.gosyer.data.reader.ReaderPreferences
import ca.gosyer.data.server.interactions.ChapterInteractionHandler import ca.gosyer.data.server.interactions.ChapterInteractionHandler
import ca.gosyer.ui.reader.model.ReaderChapter import ca.gosyer.ui.reader.model.ReaderChapter
import ca.gosyer.ui.reader.model.ReaderPage import ca.gosyer.ui.reader.model.ReaderPage
import ca.gosyer.util.lang.throwIfCancellation
import ca.gosyer.util.system.CKLogger import ca.gosyer.util.system.CKLogger
import io.github.kerubistan.kroki.coroutines.priorityChannel import io.github.kerubistan.kroki.coroutines.priorityChannel
import io.ktor.client.features.onDownload import io.ktor.client.features.onDownload

View File

@@ -23,7 +23,8 @@ import ca.gosyer.data.update.UpdatePreferences
import ca.gosyer.ui.base.components.MenuController import ca.gosyer.ui.base.components.MenuController
import ca.gosyer.ui.base.components.Toolbar import ca.gosyer.ui.base.components.Toolbar
import ca.gosyer.ui.base.prefs.SwitchPreference 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.base.vm.viewModel import ca.gosyer.ui.base.vm.viewModel
import javax.inject.Inject import javax.inject.Inject
@@ -38,12 +39,12 @@ class SettingsAdvancedViewModel @Inject constructor(
fun SettingsAdvancedScreen(menuController: MenuController) { fun SettingsAdvancedScreen(menuController: MenuController) {
val vm = viewModel<SettingsAdvancedViewModel>() val vm = viewModel<SettingsAdvancedViewModel>()
Column { Column {
Toolbar(stringResource("settings_advanced_screen"), menuController, true) Toolbar(stringResource(MR.strings.settings_advanced_screen), menuController, true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {
item { item {
SwitchPreference(preference = vm.updatesEnabled, title = stringResource("update_checker")) SwitchPreference(preference = vm.updatesEnabled, title = stringResource(MR.strings.update_checker))
} }
} }
VerticalScrollbar( VerticalScrollbar(

View File

@@ -41,7 +41,8 @@ import ca.gosyer.ui.base.components.Toolbar
import ca.gosyer.ui.base.prefs.ChoicePreference import ca.gosyer.ui.base.prefs.ChoicePreference
import ca.gosyer.ui.base.prefs.ColorPreference import ca.gosyer.ui.base.prefs.ColorPreference
import ca.gosyer.ui.base.prefs.SwitchPreference 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.AppColorsPreferenceState
import ca.gosyer.ui.base.theme.Theme import ca.gosyer.ui.base.theme.Theme
import ca.gosyer.ui.base.theme.asStateFlow import ca.gosyer.ui.base.theme.asStateFlow
@@ -81,7 +82,7 @@ fun SettingsAppearance(menuController: MenuController) {
} }
Column { Column {
Toolbar(stringResource("settings_appearance_screen"), menuController, true) Toolbar(stringResource(MR.strings.settings_appearance_screen), menuController, true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {
@@ -89,16 +90,16 @@ fun SettingsAppearance(menuController: MenuController) {
ChoicePreference( ChoicePreference(
preference = vm.themeMode, preference = vm.themeMode,
choices = mapOf( choices = mapOf(
ThemeMode.System to stringResource("theme_follow_system"), ThemeMode.System to stringResource(MR.strings.theme_follow_system),
ThemeMode.Light to stringResource("theme_light"), ThemeMode.Light to stringResource(MR.strings.theme_light),
ThemeMode.Dark to stringResource("theme_dark") ThemeMode.Dark to stringResource(MR.strings.theme_dark)
), ),
title = stringResource("theme") title = stringResource(MR.strings.theme)
) )
} }
item { item {
Text( Text(
stringResource("preset_themes"), stringResource(MR.strings.preset_themes),
modifier = Modifier.padding(start = 16.dp, top = 16.dp, bottom = 4.dp) modifier = Modifier.padding(start = 16.dp, top = 16.dp, bottom = 4.dp)
) )
LazyRow(modifier = Modifier.padding(horizontal = 8.dp)) { LazyRow(modifier = Modifier.padding(horizontal = 8.dp)) {
@@ -117,24 +118,24 @@ fun SettingsAppearance(menuController: MenuController) {
item { item {
ColorPreference( ColorPreference(
preference = activeColors.primaryStateFlow, preference = activeColors.primaryStateFlow,
title = stringResource("color_primary"), title = stringResource(MR.strings.color_primary),
subtitle = stringResource("color_primary_sub"), subtitle = stringResource(MR.strings.color_primary_sub),
unsetColor = MaterialTheme.colors.primary unsetColor = MaterialTheme.colors.primary
) )
} }
item { item {
ColorPreference( ColorPreference(
preference = activeColors.secondaryStateFlow, preference = activeColors.secondaryStateFlow,
title = stringResource("color_secondary"), title = stringResource(MR.strings.color_secondary),
subtitle = stringResource("color_secondary_sub"), subtitle = stringResource(MR.strings.color_secondary_sub),
unsetColor = MaterialTheme.colors.secondary unsetColor = MaterialTheme.colors.secondary
) )
} }
item { item {
SwitchPreference( SwitchPreference(
vm.windowDecorations, vm.windowDecorations,
stringResource("window_decorations"), stringResource(MR.strings.window_decorations),
stringResource("window_decorations_sub") stringResource(MR.strings.window_decorations_sub)
) )
} }
} }
@@ -176,7 +177,7 @@ private fun ThemeItem(
.weight(1f) .weight(1f)
.padding(6.dp) .padding(6.dp)
) { ) {
Text(stringResource("theme_text"), fontSize = 11.sp) Text(stringResource(MR.strings.theme_text), fontSize = 11.sp)
Button( Button(
onClick = {}, onClick = {},
enabled = false, enabled = false,

View File

@@ -32,15 +32,16 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ca.gosyer.core.lang.throwIfCancellation
import ca.gosyer.data.server.interactions.BackupInteractionHandler import ca.gosyer.data.server.interactions.BackupInteractionHandler
import ca.gosyer.ui.base.WindowDialog import ca.gosyer.ui.base.WindowDialog
import ca.gosyer.ui.base.components.MenuController import ca.gosyer.ui.base.components.MenuController
import ca.gosyer.ui.base.components.Toolbar import ca.gosyer.ui.base.components.Toolbar
import ca.gosyer.ui.base.prefs.PreferenceRow 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.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.CKLogger
import ca.gosyer.util.system.filePicker import ca.gosyer.util.system.filePicker
import ca.gosyer.util.system.fileSaver import ca.gosyer.util.system.fileSaver
@@ -205,14 +206,14 @@ fun SettingsBackupScreen(menuController: MenuController) {
} }
Column { Column {
Toolbar(stringResource("settings_backup_screen"), menuController, true) Toolbar(stringResource(MR.strings.settings_backup_screen), menuController, true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {
item { item {
PreferenceFile( PreferenceFile(
stringResource("backup_restore"), stringResource(MR.strings.backup_restore),
stringResource("backup_restore_sub"), stringResource(MR.strings.backup_restore_sub),
restoring, restoring,
restoringProgress, restoringProgress,
restoreStatus restoreStatus
@@ -222,8 +223,8 @@ fun SettingsBackupScreen(menuController: MenuController) {
} }
} }
PreferenceFile( PreferenceFile(
stringResource("backup_create"), stringResource(MR.strings.backup_create),
stringResource("backup_create_sub"), stringResource(MR.strings.backup_create_sub),
creating, creating,
creatingProgress, creatingProgress,
creatingStatus, creatingStatus,
@@ -249,7 +250,7 @@ private fun openMissingSourcesDialog(missingSources: List<String>, onPositiveCli
) { ) {
LazyColumn { LazyColumn {
item { item {
Text(stringResource("missing_sources"), style = MaterialTheme.typography.subtitle2) Text(stringResource(MR.strings.missing_sources), style = MaterialTheme.typography.subtitle2)
} }
items(missingSources) { items(missingSources) {
Text(it) Text(it)

View File

@@ -19,14 +19,15 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ca.gosyer.i18n.MR
import ca.gosyer.ui.base.components.MenuController import ca.gosyer.ui.base.components.MenuController
import ca.gosyer.ui.base.components.Toolbar import ca.gosyer.ui.base.components.Toolbar
import ca.gosyer.ui.base.resources.stringResource import dev.icerock.moko.resources.compose.stringResource
@Composable @Composable
fun SettingsBrowseScreen(menuController: MenuController) { fun SettingsBrowseScreen(menuController: MenuController) {
Column { Column {
Toolbar(stringResource("settings_browse_screen"), menuController, true) Toolbar(stringResource(MR.strings.settings_browse_screen), menuController, true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {

View File

@@ -21,12 +21,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ca.gosyer.ui.base.components.MenuController import ca.gosyer.ui.base.components.MenuController
import ca.gosyer.ui.base.components.Toolbar 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 @Composable
fun SettingsDownloadsScreen(menuController: MenuController) { fun SettingsDownloadsScreen(menuController: MenuController) {
Column { Column {
Toolbar(stringResource("settings_download_screen"), menuController, true) Toolbar(stringResource(MR.strings.settings_download_screen), menuController, true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {

View File

@@ -23,13 +23,14 @@ import androidx.compose.ui.unit.dp
import ca.gosyer.build.BuildResources import ca.gosyer.build.BuildResources
import ca.gosyer.data.ui.UiPreferences import ca.gosyer.data.ui.UiPreferences
import ca.gosyer.data.ui.model.StartScreen 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.MenuController
import ca.gosyer.ui.base.components.Toolbar import ca.gosyer.ui.base.components.Toolbar
import ca.gosyer.ui.base.prefs.ChoicePreference import ca.gosyer.ui.base.prefs.ChoicePreference
import ca.gosyer.ui.base.prefs.SwitchPreference 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 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.Instant
import java.time.ZoneId import java.time.ZoneId
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@@ -51,16 +52,16 @@ class SettingsGeneralViewModel @Inject constructor(
@Composable @Composable
fun getStartScreenChoices() = mapOf( fun getStartScreenChoices() = mapOf(
StartScreen.Library to stringResource("location_library"), StartScreen.Library to stringResource(MR.strings.location_library),
StartScreen.Updates to stringResource("location_updates"), StartScreen.Updates to stringResource(MR.strings.location_updates),
StartScreen.Sources to stringResource("location_sources"), StartScreen.Sources to stringResource(MR.strings.location_sources),
StartScreen.Extensions to stringResource("location_extensions") StartScreen.Extensions to stringResource(MR.strings.location_extensions)
) )
@Composable @Composable
fun getLanguageChoices(): Map<String, String> = ( fun getLanguageChoices(): Map<String, String> = (
mapOf( mapOf(
"" to stringResource("language_system_default", currentLocale.getDisplayName(currentLocale)) "" to stringResource(MR.strings.language_system_default, currentLocale.getDisplayName(currentLocale))
) + BuildResources.LANGUAGES ) + BuildResources.LANGUAGES
.associateWith { Locale.forLanguageTag(it).getDisplayName(currentLocale) } .associateWith { Locale.forLanguageTag(it).getDisplayName(currentLocale) }
) )
@@ -69,7 +70,7 @@ class SettingsGeneralViewModel @Inject constructor(
@Composable @Composable
fun getDateChoices(): Map<String, String> { fun getDateChoices(): Map<String, String> {
return mapOf( return mapOf(
"" to stringResource("date_system_default"), "" to stringResource(MR.strings.date_system_default),
"MM/dd/yy" to "MM/dd/yy", "MM/dd/yy" to "MM/dd/yy",
"dd/MM/yy" to "dd/MM/yy", "dd/MM/yy" to "dd/MM/yy",
"yyyy-MM-dd" to "yyyy-MM-dd" "yyyy-MM-dd" to "yyyy-MM-dd"
@@ -91,21 +92,21 @@ class SettingsGeneralViewModel @Inject constructor(
fun SettingsGeneralScreen(menuController: MenuController) { fun SettingsGeneralScreen(menuController: MenuController) {
val vm = viewModel<SettingsGeneralViewModel>() val vm = viewModel<SettingsGeneralViewModel>()
Column { Column {
Toolbar(stringResource("settings_general_screen"), menuController, closable = true) Toolbar(stringResource(MR.strings.settings_general_screen), menuController, closable = true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {
item { item {
ChoicePreference( ChoicePreference(
preference = vm.startScreen, preference = vm.startScreen,
title = stringResource("start_screen"), title = stringResource(MR.strings.start_screen),
choices = vm.getStartScreenChoices() choices = vm.getStartScreenChoices()
) )
} }
item { item {
SwitchPreference( SwitchPreference(
preference = vm.confirmExit, preference = vm.confirmExit,
title = stringResource("confirm_exit") title = stringResource(MR.strings.confirm_exit)
) )
} }
item { item {
@@ -114,14 +115,14 @@ fun SettingsGeneralScreen(menuController: MenuController) {
item { item {
ChoicePreference( ChoicePreference(
preference = vm.language, preference = vm.language,
title = stringResource("language"), title = stringResource(MR.strings.language),
choices = vm.getLanguageChoices(), choices = vm.getLanguageChoices(),
) )
} }
item { item {
ChoicePreference( ChoicePreference(
preference = vm.dateFormat, preference = vm.dateFormat,
title = stringResource("date_format"), title = stringResource(MR.strings.date_format),
choices = vm.getDateChoices() choices = vm.getDateChoices()
) )
} }

View File

@@ -26,7 +26,8 @@ import ca.gosyer.ui.base.components.MenuController
import ca.gosyer.ui.base.components.Toolbar import ca.gosyer.ui.base.components.Toolbar
import ca.gosyer.ui.base.prefs.PreferenceRow import ca.gosyer.ui.base.prefs.PreferenceRow
import ca.gosyer.ui.base.prefs.SwitchPreference 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.base.vm.viewModel import ca.gosyer.ui.base.vm.viewModel
import ca.gosyer.ui.categories.openCategoriesMenu import ca.gosyer.ui.categories.openCategoriesMenu
@@ -60,19 +61,19 @@ fun SettingsLibraryScreen(menuController: MenuController) {
val vm = viewModel<SettingsLibraryViewModel>() val vm = viewModel<SettingsLibraryViewModel>()
Column { Column {
Toolbar(stringResource("settings_library_screen"), menuController, true) Toolbar(stringResource(MR.strings.settings_library_screen), menuController, true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {
item { item {
SwitchPreference( SwitchPreference(
preference = vm.showAllCategory, preference = vm.showAllCategory,
title = stringResource("show_all_category") title = stringResource(MR.strings.show_all_category)
) )
} }
item { item {
PreferenceRow( PreferenceRow(
stringResource("location_categories"), stringResource(MR.strings.location_categories),
onClick = { openCategoriesMenu(vm::refreshCategoryCount) }, onClick = { openCategoriesMenu(vm::refreshCategoryCount) },
subtitle = vm.categories.collectAsState().value.toString() subtitle = vm.categories.collectAsState().value.toString()
) )

View File

@@ -21,12 +21,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ca.gosyer.ui.base.components.MenuController import ca.gosyer.ui.base.components.MenuController
import ca.gosyer.ui.base.components.Toolbar 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 @Composable
fun SettingsParentalControlsScreen(menuController: MenuController) { fun SettingsParentalControlsScreen(menuController: MenuController) {
Column { Column {
Toolbar(stringResource("settings_parental_control_screen"), menuController, true) Toolbar(stringResource(MR.strings.settings_parental_control_screen), menuController, true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {

View File

@@ -28,7 +28,7 @@ import ca.gosyer.data.reader.ReaderPreferences
import ca.gosyer.data.reader.model.Direction import ca.gosyer.data.reader.model.Direction
import ca.gosyer.data.reader.model.ImageScale import ca.gosyer.data.reader.model.ImageScale
import ca.gosyer.data.reader.model.NavigationMode 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.MenuController
import ca.gosyer.ui.base.components.Toolbar import ca.gosyer.ui.base.components.Toolbar
import ca.gosyer.ui.base.prefs.ChoicePreference 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.PreferenceMutableStateFlow
import ca.gosyer.ui.base.prefs.SwitchPreference import ca.gosyer.ui.base.prefs.SwitchPreference
import ca.gosyer.ui.base.prefs.asStateIn 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 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.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
@@ -47,7 +47,6 @@ import kotlinx.coroutines.flow.onEach
import javax.inject.Inject import javax.inject.Inject
class SettingsReaderViewModel @Inject constructor( class SettingsReaderViewModel @Inject constructor(
private val resources: XmlResourceBundle,
readerPreferences: ReaderPreferences readerPreferences: ReaderPreferences
) : ViewModel() { ) : ViewModel() {
val modes = readerPreferences.modes().asStateFlow() val modes = readerPreferences.modes().asStateFlow()
@@ -68,10 +67,10 @@ class SettingsReaderViewModel @Inject constructor(
}.launchIn(scope) }.launchIn(scope)
} }
fun getDirectionChoices() = Direction.values().associate { it to resources.getStringA(it.res) } fun getDirectionChoices() = Direction.values().associateWith { it.res.localized() }
fun getPaddingChoices() = mapOf( fun getPaddingChoices() = mapOf(
0 to resources.getStringA("page_padding_none"), 0 to MR.strings.page_padding_none.localized(),
8 to "8 Dp", 8 to "8 Dp",
16 to "16 Dp", 16 to "16 Dp",
32 to "32 Dp" 32 to "32 Dp"
@@ -79,23 +78,23 @@ class SettingsReaderViewModel @Inject constructor(
fun getMaxSizeChoices(direction: Direction) = if (direction == Direction.Right || direction == Direction.Left) { fun getMaxSizeChoices(direction: Direction) = if (direction == Direction.Right || direction == Direction.Left) {
mapOf( mapOf(
0 to resources.getStringA("max_size_unrestricted"), 0 to MR.strings.max_size_unrestricted.localized(),
700 to "700 Dp", 700 to "700 Dp",
900 to "900 Dp", 900 to "900 Dp",
1100 to "1100 Dp" 1100 to "1100 Dp"
) )
} else { } else {
mapOf( mapOf(
0 to resources.getStringA("max_size_unrestricted"), 0 to MR.strings.max_size_unrestricted.localized(),
500 to "500 Dp", 500 to "500 Dp",
700 to "700 Dp", 700 to "700 Dp",
900 to "900 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( data class ReaderModePreference(
@@ -130,7 +129,7 @@ fun SettingsReaderScreen(menuController: MenuController) {
val vm = viewModel<SettingsReaderViewModel>() val vm = viewModel<SettingsReaderViewModel>()
val modeSettings by vm.modeSettings.collectAsState() val modeSettings by vm.modeSettings.collectAsState()
Column { Column {
Toolbar(stringResource("settings_reader"), menuController, true) Toolbar(stringResource(MR.strings.settings_reader), menuController, true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {
@@ -138,7 +137,7 @@ fun SettingsReaderScreen(menuController: MenuController) {
ChoicePreference( ChoicePreference(
vm.selectedMode, vm.selectedMode,
vm.modes.collectAsState().value.associateWith { it }, vm.modes.collectAsState().value.associateWith { it },
stringResource("reader_mode") stringResource(MR.strings.reader_mode)
) )
} }
item { item {
@@ -150,13 +149,13 @@ fun SettingsReaderScreen(menuController: MenuController) {
ChoicePreference( ChoicePreference(
it.direction, it.direction,
vm.getDirectionChoices(), vm.getDirectionChoices(),
stringResource("direction"), stringResource(MR.strings.direction),
enabled = !it.defaultMode enabled = !it.defaultMode
) )
SwitchPreference( SwitchPreference(
it.continuous, it.continuous,
stringResource("continuous"), stringResource(MR.strings.continuous),
stringResource("continuous_sub"), stringResource(MR.strings.continuous_sub),
enabled = !it.defaultMode enabled = !it.defaultMode
) )
val continuous by it.continuous.collectAsState() val continuous by it.continuous.collectAsState()
@@ -164,13 +163,13 @@ fun SettingsReaderScreen(menuController: MenuController) {
ChoicePreference( ChoicePreference(
it.padding, it.padding,
vm.getPaddingChoices(), vm.getPaddingChoices(),
stringResource("page_padding") stringResource(MR.strings.page_padding)
) )
val direction by it.direction.collectAsState() val direction by it.direction.collectAsState()
val (title, subtitle) = if (direction == Direction.Up || direction == Direction.Down) { 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 { } 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( SwitchPreference(
it.fitSize, it.fitSize,
@@ -179,13 +178,13 @@ fun SettingsReaderScreen(menuController: MenuController) {
) )
val maxSize by it.maxSize.collectAsState() val maxSize by it.maxSize.collectAsState()
val (maxSizeTitle, maxSizeSubtitle) = if (direction == Direction.Up || direction == Direction.Down) { val (maxSizeTitle, maxSizeSubtitle) = if (direction == Direction.Up || direction == Direction.Down) {
stringResource("max_width") to stringResource( stringResource(MR.strings.max_width) to stringResource(
"max_width_sub", MR.strings.max_width_sub,
maxSize maxSize
) )
} else { } else {
stringResource("max_height") to stringResource( stringResource(MR.strings.max_height) to stringResource(
"max_height_sub", MR.strings.max_height_sub,
maxSize maxSize
) )
} }
@@ -199,13 +198,13 @@ fun SettingsReaderScreen(menuController: MenuController) {
ChoicePreference( ChoicePreference(
it.imageScale, it.imageScale,
vm.getImageScaleChoices(), vm.getImageScaleChoices(),
stringResource("image_scale") stringResource(MR.strings.image_scale)
) )
} }
ChoicePreference( ChoicePreference(
it.navigationMode, it.navigationMode,
vm.getNavigationModeChoices(), vm.getNavigationModeChoices(),
stringResource("navigation_mode") stringResource(MR.strings.navigation_mode)
) )
} }
} }

View File

@@ -31,96 +31,97 @@ import androidx.compose.ui.unit.dp
import ca.gosyer.ui.base.components.MenuController import ca.gosyer.ui.base.components.MenuController
import ca.gosyer.ui.base.components.Toolbar import ca.gosyer.ui.base.components.Toolbar
import ca.gosyer.ui.base.prefs.PreferenceRow 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 import ca.gosyer.ui.main.Routes
@Composable @Composable
fun SettingsScreen(menuController: MenuController) { fun SettingsScreen(menuController: MenuController) {
Column { Column {
Toolbar(stringResource("location_settings"), closable = false) Toolbar(stringResource(MR.strings.location_settings), closable = false)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {
item { item {
PreferenceRow( PreferenceRow(
title = stringResource("settings_general"), title = stringResource(MR.strings.settings_general),
icon = Icons.Rounded.Tune, icon = Icons.Rounded.Tune,
onClick = { menuController.push(Routes.SettingsGeneral) } onClick = { menuController.push(Routes.SettingsGeneral) }
) )
} }
item { item {
PreferenceRow( PreferenceRow(
title = stringResource("settings_appearance"), title = stringResource(MR.strings.settings_appearance),
icon = Icons.Rounded.Palette, icon = Icons.Rounded.Palette,
onClick = { menuController.push(Routes.SettingsAppearance) } onClick = { menuController.push(Routes.SettingsAppearance) }
) )
} }
item { item {
PreferenceRow( PreferenceRow(
title = stringResource("settings_server"), title = stringResource(MR.strings.settings_server),
icon = Icons.Rounded.Computer, icon = Icons.Rounded.Computer,
onClick = { menuController.push(Routes.SettingsServer) } onClick = { menuController.push(Routes.SettingsServer) }
) )
} }
item { item {
PreferenceRow( PreferenceRow(
title = stringResource("settings_library"), title = stringResource(MR.strings.settings_library),
icon = Icons.Rounded.CollectionsBookmark, icon = Icons.Rounded.CollectionsBookmark,
onClick = { menuController.push(Routes.SettingsLibrary) } onClick = { menuController.push(Routes.SettingsLibrary) }
) )
} }
item { item {
PreferenceRow( PreferenceRow(
title = stringResource("settings_reader"), title = stringResource(MR.strings.settings_reader),
icon = Icons.Rounded.ChromeReaderMode, icon = Icons.Rounded.ChromeReaderMode,
onClick = { menuController.push(Routes.SettingsReader) } onClick = { menuController.push(Routes.SettingsReader) }
) )
} }
/*item { /*item {
Pref( Pref(
title = stringResource("settings_download"), title = stringResource(MR.strings.settings_download),
icon = Icons.Rounded.GetApp, icon = Icons.Rounded.GetApp,
onClick = { navController.push(Route.SettingsDownloads) } onClick = { navController.push(Route.SettingsDownloads) }
) )
} }
item { item {
Pref( Pref(
title = stringResource("settings_tracking"), title = stringResource(MR.strings.settings_tracking),
icon = Icons.Rounded.Sync, icon = Icons.Rounded.Sync,
onClick = { navController.push(Route.SettingsTracking) } onClick = { navController.push(Route.SettingsTracking) }
) )
}*/ }*/
item { item {
PreferenceRow( PreferenceRow(
title = stringResource("settings_browse"), title = stringResource(MR.strings.settings_browse),
icon = Icons.Rounded.Explore, icon = Icons.Rounded.Explore,
onClick = { menuController.push(Routes.SettingsBrowse) } onClick = { menuController.push(Routes.SettingsBrowse) }
) )
} }
item { item {
PreferenceRow( PreferenceRow(
title = stringResource("settings_backup"), title = stringResource(MR.strings.settings_backup),
icon = Icons.Rounded.Backup, icon = Icons.Rounded.Backup,
onClick = { menuController.push(Routes.SettingsBackup) } onClick = { menuController.push(Routes.SettingsBackup) }
) )
} }
/*item { /*item {
Pref( Pref(
title = stringResource("settings_security"), title = stringResource(MR.strings.settings_security),
icon = Icons.Rounded.Security, icon = Icons.Rounded.Security,
onClick = { navController.push(Route.SettingsSecurity) } onClick = { navController.push(Route.SettingsSecurity) }
) )
} }
item { item {
Pref( Pref(
title = stringResource("settings_parental_controls"), title = stringResource(MR.strings.settings_parental_controls),
icon = Icons.Rounded.PeopleOutline, icon = Icons.Rounded.PeopleOutline,
onClick = { navController.push(Route.SettingsParentalControls) } onClick = { navController.push(Route.SettingsParentalControls) }
) )
}*/ }*/
item { item {
PreferenceRow( PreferenceRow(
title = stringResource("settings_advanced"), title = stringResource(MR.strings.settings_advanced),
icon = Icons.Rounded.Code, icon = Icons.Rounded.Code,
onClick = { menuController.push(Routes.SettingsAdvanced) } onClick = { menuController.push(Routes.SettingsAdvanced) }
) )

View File

@@ -21,12 +21,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ca.gosyer.ui.base.components.MenuController import ca.gosyer.ui.base.components.MenuController
import ca.gosyer.ui.base.components.Toolbar 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 @Composable
fun SettingsSecurityScreen(menuController: MenuController) { fun SettingsSecurityScreen(menuController: MenuController) {
Column { Column {
Toolbar(stringResource("settings_security_screen"), menuController, true) Toolbar(stringResource(MR.strings.settings_security_screen), menuController, true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {

View File

@@ -32,6 +32,7 @@ import ca.gosyer.data.server.ServerPreferences
import ca.gosyer.data.server.ServerService import ca.gosyer.data.server.ServerService
import ca.gosyer.data.server.model.Auth import ca.gosyer.data.server.model.Auth
import ca.gosyer.data.server.model.Proxy 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.MenuController
import ca.gosyer.ui.base.components.Toolbar import ca.gosyer.ui.base.components.Toolbar
import ca.gosyer.ui.base.prefs.ChoicePreference 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.SwitchPreference
import ca.gosyer.ui.base.prefs.asStateIn import ca.gosyer.ui.base.prefs.asStateIn
import ca.gosyer.ui.base.prefs.asStringStateIn 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.ui.base.vm.viewModel import ca.gosyer.ui.base.vm.viewModel
import ca.gosyer.util.system.CKLogger import ca.gosyer.util.system.CKLogger
import dev.icerock.moko.resources.compose.stringResource
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
@@ -85,9 +86,9 @@ class SettingsServerViewModel @Inject constructor(
@Composable @Composable
fun getProxyChoices() = mapOf( fun getProxyChoices() = mapOf(
Proxy.NO_PROXY to stringResource("no_proxy"), Proxy.NO_PROXY to stringResource(MR.strings.no_proxy),
Proxy.HTTP_PROXY to stringResource("http_proxy"), Proxy.HTTP_PROXY to stringResource(MR.strings.http_proxy),
Proxy.SOCKS_PROXY to stringResource("socks_proxy") Proxy.SOCKS_PROXY to stringResource(MR.strings.socks_proxy)
) )
val httpHost = serverPreferences.proxyHttpHost().asStateIn(scope) val httpHost = serverPreferences.proxyHttpHost().asStateIn(scope)
@@ -99,9 +100,9 @@ class SettingsServerViewModel @Inject constructor(
@Composable @Composable
fun getAuthChoices() = mapOf( fun getAuthChoices() = mapOf(
Auth.NONE to stringResource("no_auth"), Auth.NONE to stringResource(MR.strings.no_auth),
Auth.BASIC to stringResource("basic_auth"), Auth.BASIC to stringResource(MR.strings.basic_auth),
Auth.DIGEST to stringResource("digest_auth") Auth.DIGEST to stringResource(MR.strings.digest_auth)
) )
val authUsername = serverPreferences.authUsername().asStateIn(scope) val authUsername = serverPreferences.authUsername().asStateIn(scope)
val authPassword = serverPreferences.authPassword().asStateIn(scope) val authPassword = serverPreferences.authPassword().asStateIn(scope)
@@ -147,27 +148,27 @@ fun SettingsServerScreen(menuController: MenuController) {
} }
} }
Column { Column {
Toolbar(stringResource("settings_server_screen"), menuController, true) Toolbar(stringResource(MR.strings.settings_server_screen), menuController, true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {
item { item {
SwitchPreference(preference = vm.host, title = stringResource("host_server")) SwitchPreference(preference = vm.host, title = stringResource(MR.strings.host_server))
} }
if (host) { if (host) {
item { item {
PreferenceRow( PreferenceRow(
stringResource("host_settings"), stringResource(MR.strings.host_settings),
Icons.Rounded.Info, Icons.Rounded.Info,
subtitle = stringResource("host_settings_sub") subtitle = stringResource(MR.strings.host_settings_sub)
) )
} }
item { item {
val ip by vm.ip.collectAsState() val ip by vm.ip.collectAsState()
EditTextPreference( EditTextPreference(
preference = vm.ip, preference = vm.ip,
title = stringResource("host_ip"), title = stringResource(MR.strings.host_ip),
subtitle = stringResource("host_ip_sub", ip), subtitle = stringResource(MR.strings.host_ip_sub, ip),
changeListener = vm::serverSettingChanged changeListener = vm::serverSettingChanged
) )
} }
@@ -175,15 +176,15 @@ fun SettingsServerScreen(menuController: MenuController) {
val port by vm.port.collectAsState() val port by vm.port.collectAsState()
EditTextPreference( EditTextPreference(
preference = vm.port, preference = vm.port,
title = stringResource("host_port"), title = stringResource(MR.strings.host_port),
subtitle = stringResource("host_port_sub", port), subtitle = stringResource(MR.strings.host_port_sub, port),
changeListener = vm::serverSettingChanged changeListener = vm::serverSettingChanged
) )
} }
item { item {
SwitchPreference( SwitchPreference(
preference = vm.socksProxyEnabled, preference = vm.socksProxyEnabled,
title = stringResource("host_socks_enabled"), title = stringResource(MR.strings.host_socks_enabled),
changeListener = vm::serverSettingChanged changeListener = vm::serverSettingChanged
) )
} }
@@ -191,8 +192,8 @@ fun SettingsServerScreen(menuController: MenuController) {
val proxyHost by vm.socksProxyHost.collectAsState() val proxyHost by vm.socksProxyHost.collectAsState()
EditTextPreference( EditTextPreference(
preference = vm.socksProxyHost, preference = vm.socksProxyHost,
title = stringResource("host_socks_host"), title = stringResource(MR.strings.host_socks_host),
subtitle = stringResource("host_socks_host_sub", proxyHost), subtitle = stringResource(MR.strings.host_socks_host_sub, proxyHost),
changeListener = vm::serverSettingChanged changeListener = vm::serverSettingChanged
) )
} }
@@ -200,32 +201,32 @@ fun SettingsServerScreen(menuController: MenuController) {
val proxyPort by vm.socksProxyPort.collectAsState() val proxyPort by vm.socksProxyPort.collectAsState()
EditTextPreference( EditTextPreference(
preference = vm.socksProxyPort, preference = vm.socksProxyPort,
title = stringResource("host_socks_port"), title = stringResource(MR.strings.host_socks_port),
subtitle = stringResource("host_socks_port_sub", proxyPort), subtitle = stringResource(MR.strings.host_socks_port_sub, proxyPort),
changeListener = vm::serverSettingChanged changeListener = vm::serverSettingChanged
) )
} }
item { item {
SwitchPreference( SwitchPreference(
preference = vm.debugLogsEnabled, preference = vm.debugLogsEnabled,
title = stringResource("host_debug_logging"), title = stringResource(MR.strings.host_debug_logging),
subtitle = stringResource("host_debug_logging_sub"), subtitle = stringResource(MR.strings.host_debug_logging_sub),
changeListener = vm::serverSettingChanged changeListener = vm::serverSettingChanged
) )
} }
item { item {
SwitchPreference( SwitchPreference(
preference = vm.systemTrayEnabled, preference = vm.systemTrayEnabled,
title = stringResource("host_system_tray"), title = stringResource(MR.strings.host_system_tray),
subtitle = stringResource("host_system_tray_sub"), subtitle = stringResource(MR.strings.host_system_tray_sub),
changeListener = vm::serverSettingChanged changeListener = vm::serverSettingChanged
) )
} }
item { item {
SwitchPreference( SwitchPreference(
preference = vm.webUIEnabled, preference = vm.webUIEnabled,
title = stringResource("host_webui"), title = stringResource(MR.strings.host_webui),
subtitle = stringResource("host_webui_sub"), subtitle = stringResource(MR.strings.host_webui_sub),
changeListener = vm::serverSettingChanged changeListener = vm::serverSettingChanged
) )
} }
@@ -233,8 +234,8 @@ fun SettingsServerScreen(menuController: MenuController) {
val webUIEnabled by vm.webUIEnabled.collectAsState() val webUIEnabled by vm.webUIEnabled.collectAsState()
SwitchPreference( SwitchPreference(
preference = vm.openInBrowserEnabled, preference = vm.openInBrowserEnabled,
title = stringResource("host_open_in_browser"), title = stringResource(MR.strings.host_open_in_browser),
subtitle = stringResource("host_open_in_browser_sub"), subtitle = stringResource(MR.strings.host_open_in_browser_sub),
changeListener = vm::serverSettingChanged, changeListener = vm::serverSettingChanged,
enabled = webUIEnabled enabled = webUIEnabled
) )
@@ -242,15 +243,15 @@ fun SettingsServerScreen(menuController: MenuController) {
item { item {
SwitchPreference( SwitchPreference(
preference = vm.basicAuthEnabled, preference = vm.basicAuthEnabled,
title = stringResource("basic_auth"), title = stringResource(MR.strings.basic_auth),
subtitle = stringResource("host_basic_auth_sub"), subtitle = stringResource(MR.strings.host_basic_auth_sub),
changeListener = vm::serverSettingChanged changeListener = vm::serverSettingChanged
) )
} }
item { item {
EditTextPreference( EditTextPreference(
preference = vm.basicAuthUsername, preference = vm.basicAuthUsername,
title = stringResource("host_basic_auth_username"), title = stringResource(MR.strings.host_basic_auth_username),
changeListener = vm::serverSettingChanged, changeListener = vm::serverSettingChanged,
enabled = basicAuthEnabled enabled = basicAuthEnabled
) )
@@ -258,7 +259,7 @@ fun SettingsServerScreen(menuController: MenuController) {
item { item {
EditTextPreference( EditTextPreference(
preference = vm.basicAuthPassword, preference = vm.basicAuthPassword,
title = stringResource("host_basic_auth_password"), title = stringResource(MR.strings.host_basic_auth_password),
changeListener = vm::serverSettingChanged, changeListener = vm::serverSettingChanged,
visualTransformation = PasswordVisualTransformation(), visualTransformation = PasswordVisualTransformation(),
enabled = basicAuthEnabled enabled = basicAuthEnabled
@@ -271,27 +272,27 @@ fun SettingsServerScreen(menuController: MenuController) {
item { item {
EditTextPreference( EditTextPreference(
vm.serverUrl, vm.serverUrl,
stringResource("server_url"), stringResource(MR.strings.server_url),
subtitle = vm.serverUrl.collectAsState().value subtitle = vm.serverUrl.collectAsState().value
) )
} }
item { item {
EditTextPreference( EditTextPreference(
vm.serverPort, vm.serverPort,
stringResource("server_port"), stringResource(MR.strings.server_port),
subtitle = vm.serverPort.collectAsState().value subtitle = vm.serverPort.collectAsState().value
) )
} }
item { item {
PreferenceRow( PreferenceRow(
stringResource("server_preference_warning"), stringResource(MR.strings.server_preference_warning),
Icons.Rounded.Warning, Icons.Rounded.Warning,
subtitle = stringResource("server_preference_warning_sub") subtitle = stringResource(MR.strings.server_preference_warning_sub)
) )
} }
item { item {
ChoicePreference(vm.proxy, vm.getProxyChoices(), stringResource("server_proxy")) ChoicePreference(vm.proxy, vm.getProxyChoices(), stringResource(MR.strings.server_proxy))
} }
when (proxy) { when (proxy) {
Proxy.NO_PROXY -> Unit Proxy.NO_PROXY -> Unit
@@ -299,14 +300,14 @@ fun SettingsServerScreen(menuController: MenuController) {
item { item {
EditTextPreference( EditTextPreference(
vm.httpHost, vm.httpHost,
stringResource("http_proxy"), stringResource(MR.strings.http_proxy),
vm.httpHost.collectAsState().value vm.httpHost.collectAsState().value
) )
} }
item { item {
EditTextPreference( EditTextPreference(
vm.httpPort, vm.httpPort,
stringResource("http_port"), stringResource(MR.strings.http_port),
vm.httpPort.collectAsState().value vm.httpPort.collectAsState().value
) )
} }
@@ -315,30 +316,30 @@ fun SettingsServerScreen(menuController: MenuController) {
item { item {
EditTextPreference( EditTextPreference(
vm.socksHost, vm.socksHost,
stringResource("socks_proxy"), stringResource(MR.strings.socks_proxy),
vm.socksHost.collectAsState().value vm.socksHost.collectAsState().value
) )
} }
item { item {
EditTextPreference( EditTextPreference(
vm.socksPort, vm.socksPort,
stringResource("socks_port"), stringResource(MR.strings.socks_port),
vm.socksPort.collectAsState().value vm.socksPort.collectAsState().value
) )
} }
} }
} }
item { item {
ChoicePreference(vm.auth, vm.getAuthChoices(), stringResource("authentication")) ChoicePreference(vm.auth, vm.getAuthChoices(), stringResource(MR.strings.authentication))
} }
if (auth != Auth.NONE) { if (auth != Auth.NONE) {
item { item {
EditTextPreference(vm.authUsername, stringResource("auth_username")) EditTextPreference(vm.authUsername, stringResource(MR.strings.auth_username))
} }
item { item {
EditTextPreference( EditTextPreference(
vm.authPassword, vm.authPassword,
stringResource("auth_password"), stringResource(MR.strings.auth_password),
visualTransformation = PasswordVisualTransformation() visualTransformation = PasswordVisualTransformation()
) )
} }

View File

@@ -21,12 +21,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ca.gosyer.ui.base.components.MenuController import ca.gosyer.ui.base.components.MenuController
import ca.gosyer.ui.base.components.Toolbar 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 @Composable
fun SettingsTrackingScreen(menuController: MenuController) { fun SettingsTrackingScreen(menuController: MenuController) {
Column { Column {
Toolbar(stringResource("settings_tracking_screen"), menuController, true) Toolbar(stringResource(MR.strings.settings_tracking_screen), menuController, true)
Box { Box {
val state = rememberLazyListState() val state = rememberLazyListState()
LazyColumn(Modifier.fillMaxSize(), state) { LazyColumn(Modifier.fillMaxSize(), state) {

View File

@@ -42,7 +42,8 @@ import ca.gosyer.build.BuildConfig
import ca.gosyer.data.models.Source import ca.gosyer.data.models.Source
import ca.gosyer.ui.base.components.KamelImage import ca.gosyer.ui.base.components.KamelImage
import ca.gosyer.ui.base.components.combinedMouseClickable 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.base.vm.viewModel
import ca.gosyer.ui.manga.openMangaMenu import ca.gosyer.ui.manga.openMangaMenu
import ca.gosyer.ui.sources.components.SourceHomeScreen import ca.gosyer.ui.sources.components.SourceHomeScreen
@@ -122,7 +123,7 @@ fun SourcesSideMenu(
shape = RoundedCornerShape(4.dp), shape = RoundedCornerShape(4.dp),
elevation = 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), modifier = Modifier.size(64.dp),
@@ -153,7 +154,7 @@ fun SourcesSideMenu(
) )
} }
} else { } 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