mirror of
https://github.com/Suwayomi/TachideskJUI.git
synced 2025-12-10 06:42:05 +01:00
Lint
This commit is contained in:
@@ -20,7 +20,9 @@ import kotlinx.coroutines.flow.launchIn
|
|||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class App : Application(), DefaultLifecycleObserver {
|
class App :
|
||||||
|
Application(),
|
||||||
|
DefaultLifecycleObserver {
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super<Application>.onCreate()
|
super<Application>.onCreate()
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ abstract class AppComponent(
|
|||||||
@get:AppScope
|
@get:AppScope
|
||||||
@get:Provides
|
@get:Provides
|
||||||
val context: Context,
|
val context: Context,
|
||||||
) : ViewModelComponent, DataComponent, DomainComponent, UiComponent {
|
) : ViewModelComponent,
|
||||||
|
DataComponent,
|
||||||
|
DomainComponent,
|
||||||
|
UiComponent {
|
||||||
abstract val appMigrations: AppMigrations
|
abstract val appMigrations: AppMigrations
|
||||||
|
|
||||||
@get:AppScope
|
@get:AppScope
|
||||||
|
|||||||
@@ -208,7 +208,10 @@ class AndroidDownloadService : Service() {
|
|||||||
|
|
||||||
val title = downloadingChapter.manga.title.chop(15)
|
val title = downloadingChapter.manga.title.chop(15)
|
||||||
val quotedTitle = Pattern.quote(title)
|
val quotedTitle = Pattern.quote(title)
|
||||||
val chapter = downloadingChapter.chapter.name.replaceFirst("$quotedTitle[\\s]*[-]*[\\s]*".toRegex(RegexOption.IGNORE_CASE), "")
|
val chapter = downloadingChapter.chapter.name.replaceFirst(
|
||||||
|
"$quotedTitle[\\s]*[-]*[\\s]*".toRegex(RegexOption.IGNORE_CASE),
|
||||||
|
"",
|
||||||
|
)
|
||||||
setContentTitle("$title - $chapter".chop(30))
|
setContentTitle("$title - $chapter".chop(30))
|
||||||
|
|
||||||
setContentText(
|
setContentText(
|
||||||
|
|||||||
@@ -23,9 +23,12 @@ import ca.gosyer.jui.i18n.MR
|
|||||||
import dev.icerock.moko.resources.desc.desc
|
import dev.icerock.moko.resources.desc.desc
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class UpdateCheckWorker(private val context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams) {
|
class UpdateCheckWorker(
|
||||||
override suspend fun doWork(): Result {
|
private val context: Context,
|
||||||
return try {
|
workerParams: WorkerParameters,
|
||||||
|
) : CoroutineWorker(context, workerParams) {
|
||||||
|
override suspend fun doWork(): Result =
|
||||||
|
try {
|
||||||
val update = AppComponent.getInstance(context.applicationContext)
|
val update = AppComponent.getInstance(context.applicationContext)
|
||||||
.let {
|
.let {
|
||||||
if (it.updatePreferences.enabled().get()) {
|
if (it.updatePreferences.enabled().get()) {
|
||||||
@@ -48,7 +51,6 @@ class UpdateCheckWorker(private val context: Context, workerParams: WorkerParame
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Result.failure()
|
Result.failure()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "UpdateChecker"
|
private const val TAG = "UpdateChecker"
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import me.tatarka.inject.annotations.Inject
|
|||||||
|
|
||||||
actual class PreferenceStoreFactory
|
actual class PreferenceStoreFactory
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val context: Context) {
|
constructor(
|
||||||
actual fun create(vararg names: String): PreferenceStore {
|
private val context: Context,
|
||||||
return StandardPreferenceStore(
|
) {
|
||||||
|
actual fun create(vararg names: String): PreferenceStore =
|
||||||
|
StandardPreferenceStore(
|
||||||
SharedPreferencesSettings(
|
SharedPreferencesSettings(
|
||||||
context.getSharedPreferences(
|
context.getSharedPreferences(
|
||||||
names.joinToString(separator = "_"),
|
names.joinToString(separator = "_"),
|
||||||
@@ -22,5 +24,4 @@ actual class PreferenceStoreFactory
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,4 @@ suspend fun Source.copyTo(sink: BufferedSink) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ByteArray.source(): BufferedSource {
|
fun ByteArray.source(): BufferedSource = Buffer().write(this)
|
||||||
return Buffer().write(this)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ suspend fun <T> withUIContext(block: suspend CoroutineScope.() -> T): T = withCo
|
|||||||
|
|
||||||
suspend fun <T> withIOContext(block: suspend CoroutineScope.() -> T): T = withContext(Dispatchers.IO, block)
|
suspend fun <T> withIOContext(block: suspend CoroutineScope.() -> T): T = withContext(Dispatchers.IO, block)
|
||||||
|
|
||||||
fun Throwable.throwIfCancellation() { if (this is CancellationException) throw this }
|
fun Throwable.throwIfCancellation() {
|
||||||
|
if (this is CancellationException) throw this
|
||||||
|
}
|
||||||
|
|
||||||
fun <T> Result<T>.throwIfCancellation(): Result<T> {
|
fun <T> Result<T>.throwIfCancellation(): Result<T> {
|
||||||
if (isFailure) {
|
if (isFailure) {
|
||||||
|
|||||||
@@ -73,7 +73,10 @@ internal open class ProcessChannel<T>(
|
|||||||
override fun offer(element: T): Boolean = inChannel.trySend(element).isSuccess
|
override fun offer(element: T): Boolean = inChannel.trySend(element).isSuccess
|
||||||
|
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
"Deprecated in the favour of 'tryReceive'. Please note that the provided replacement does not rethrow channel's close cause as 'poll' did, for the precise replacement please refer to the 'poll' documentation",
|
"Deprecated in the favour of 'tryReceive'. " +
|
||||||
|
"Please note that the provided replacement does not rethrow " +
|
||||||
|
"channel's close cause as 'poll' did, for the precise replacement " +
|
||||||
|
"please refer to the 'poll' documentation",
|
||||||
replaceWith = ReplaceWith("tryReceive().getOrNull()"),
|
replaceWith = ReplaceWith("tryReceive().getOrNull()"),
|
||||||
level = DeprecationLevel.ERROR,
|
level = DeprecationLevel.ERROR,
|
||||||
)
|
)
|
||||||
@@ -82,6 +85,7 @@ internal open class ProcessChannel<T>(
|
|||||||
override suspend fun receive(): T = outChannel.receive()
|
override suspend fun receive(): T = outChannel.receive()
|
||||||
|
|
||||||
override suspend fun send(element: T) = inChannel.send(element)
|
override suspend fun send(element: T) = inChannel.send(element)
|
||||||
|
|
||||||
override val onReceiveCatching: SelectClause1<ChannelResult<T>>
|
override val onReceiveCatching: SelectClause1<ChannelResult<T>>
|
||||||
get() = TODO("not implemented")
|
get() = TODO("not implemented")
|
||||||
|
|
||||||
@@ -105,16 +109,16 @@ internal class PriorityChannelImpl<T>(
|
|||||||
scope: CoroutineScope,
|
scope: CoroutineScope,
|
||||||
comparator: Comparator<T>,
|
comparator: Comparator<T>,
|
||||||
) : ProcessChannel<T>(
|
) : ProcessChannel<T>(
|
||||||
// why a rendezvous channel should be the input channel?
|
// why a rendezvous channel should be the input channel?
|
||||||
// because we buffer and sort the messages in the co-routine
|
// because we buffer and sort the messages in the co-routine
|
||||||
// that is where the capacity constraint is enforced
|
// that is where the capacity constraint is enforced
|
||||||
// and the buffer we keep sorted, the input channel we can't
|
// and the buffer we keep sorted, the input channel we can't
|
||||||
inChannel = Channel(Channel.RENDEZVOUS),
|
inChannel = Channel(Channel.RENDEZVOUS),
|
||||||
// output channel is rendezvous channel because we may still
|
// output channel is rendezvous channel because we may still
|
||||||
// get higher priority input meanwhile and we will send that
|
// get higher priority input meanwhile and we will send that
|
||||||
// when output consumer is ready to take it
|
// when output consumer is ready to take it
|
||||||
outChannel = Channel(Channel.RENDEZVOUS),
|
outChannel = Channel(Channel.RENDEZVOUS),
|
||||||
) {
|
) {
|
||||||
private val buffer = PriorityQueue(comparator)
|
private val buffer = PriorityQueue(comparator)
|
||||||
|
|
||||||
private fun PriorityQueue<T>.isNotFull() = this.size < maxCapacity
|
private fun PriorityQueue<T>.isNotFull() = this.size < maxCapacity
|
||||||
|
|||||||
@@ -13,18 +13,16 @@ package ca.gosyer.jui.core.lang
|
|||||||
fun String.chop(
|
fun String.chop(
|
||||||
count: Int,
|
count: Int,
|
||||||
replacement: String = "…",
|
replacement: String = "…",
|
||||||
): String {
|
): String =
|
||||||
return if (length > count) {
|
if (length > count) {
|
||||||
take(count - replacement.length) + replacement
|
take(count - replacement.length) + replacement
|
||||||
} else {
|
} else {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun String.addSuffix(char: Char): String {
|
fun String.addSuffix(char: Char): String =
|
||||||
return if (endsWith(char)) {
|
if (endsWith(char)) {
|
||||||
this
|
this
|
||||||
} else {
|
} else {
|
||||||
this + char
|
this + char
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ class LazyPreferenceStore(
|
|||||||
override fun getString(
|
override fun getString(
|
||||||
key: String,
|
key: String,
|
||||||
defaultValue: String,
|
defaultValue: String,
|
||||||
): Preference<String> {
|
): Preference<String> = lazyStore.value.getString(key, defaultValue)
|
||||||
return lazyStore.value.getString(key, defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Long] preference for this [key].
|
* Returns a [Long] preference for this [key].
|
||||||
@@ -32,9 +30,7 @@ class LazyPreferenceStore(
|
|||||||
override fun getLong(
|
override fun getLong(
|
||||||
key: String,
|
key: String,
|
||||||
defaultValue: Long,
|
defaultValue: Long,
|
||||||
): Preference<Long> {
|
): Preference<Long> = lazyStore.value.getLong(key, defaultValue)
|
||||||
return lazyStore.value.getLong(key, defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an [Int] preference for this [key].
|
* Returns an [Int] preference for this [key].
|
||||||
@@ -42,9 +38,7 @@ class LazyPreferenceStore(
|
|||||||
override fun getInt(
|
override fun getInt(
|
||||||
key: String,
|
key: String,
|
||||||
defaultValue: Int,
|
defaultValue: Int,
|
||||||
): Preference<Int> {
|
): Preference<Int> = lazyStore.value.getInt(key, defaultValue)
|
||||||
return lazyStore.value.getInt(key, defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Float] preference for this [key].
|
* Returns a [Float] preference for this [key].
|
||||||
@@ -52,9 +46,7 @@ class LazyPreferenceStore(
|
|||||||
override fun getFloat(
|
override fun getFloat(
|
||||||
key: String,
|
key: String,
|
||||||
defaultValue: Float,
|
defaultValue: Float,
|
||||||
): Preference<Float> {
|
): Preference<Float> = lazyStore.value.getFloat(key, defaultValue)
|
||||||
return lazyStore.value.getFloat(key, defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Boolean] preference for this [key].
|
* Returns a [Boolean] preference for this [key].
|
||||||
@@ -62,9 +54,7 @@ class LazyPreferenceStore(
|
|||||||
override fun getBoolean(
|
override fun getBoolean(
|
||||||
key: String,
|
key: String,
|
||||||
defaultValue: Boolean,
|
defaultValue: Boolean,
|
||||||
): Preference<Boolean> {
|
): Preference<Boolean> = lazyStore.value.getBoolean(key, defaultValue)
|
||||||
return lazyStore.value.getBoolean(key, defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Set<String>] preference for this [key].
|
* Returns a [Set<String>] preference for this [key].
|
||||||
@@ -72,9 +62,7 @@ class LazyPreferenceStore(
|
|||||||
override fun getStringSet(
|
override fun getStringSet(
|
||||||
key: String,
|
key: String,
|
||||||
defaultValue: Set<String>,
|
defaultValue: Set<String>,
|
||||||
): Preference<Set<String>> {
|
): Preference<Set<String>> = lazyStore.value.getStringSet(key, defaultValue)
|
||||||
return lazyStore.value.getStringSet(key, defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns preference of type [T] for this [key]. The [serializer] and [deserializer] function
|
* Returns preference of type [T] for this [key]. The [serializer] and [deserializer] function
|
||||||
@@ -85,16 +73,12 @@ class LazyPreferenceStore(
|
|||||||
defaultValue: T,
|
defaultValue: T,
|
||||||
serializer: (T) -> String,
|
serializer: (T) -> String,
|
||||||
deserializer: (String) -> T,
|
deserializer: (String) -> T,
|
||||||
): Preference<T> {
|
): Preference<T> = lazyStore.value.getObject(key, defaultValue, serializer, deserializer)
|
||||||
return lazyStore.value.getObject(key, defaultValue, serializer, deserializer)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <T> getJsonObject(
|
override fun <T> getJsonObject(
|
||||||
key: String,
|
key: String,
|
||||||
defaultValue: T,
|
defaultValue: T,
|
||||||
serializer: KSerializer<T>,
|
serializer: KSerializer<T>,
|
||||||
serializersModule: SerializersModule,
|
serializersModule: SerializersModule,
|
||||||
): Preference<T> {
|
): Preference<T> = lazyStore.value.getJsonObject(key, defaultValue, serializer)
|
||||||
return lazyStore.value.getJsonObject(key, defaultValue, serializer)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ interface PreferenceStore {
|
|||||||
inline fun <reified T : Enum<T>> PreferenceStore.getEnum(
|
inline fun <reified T : Enum<T>> PreferenceStore.getEnum(
|
||||||
key: String,
|
key: String,
|
||||||
defaultValue: T,
|
defaultValue: T,
|
||||||
): Preference<T> {
|
): Preference<T> =
|
||||||
return getObject(
|
getObject(
|
||||||
key,
|
key,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
{ it.name },
|
{ it.name },
|
||||||
@@ -104,4 +104,3 @@ inline fun <reified T : Enum<T>> PreferenceStore.getEnum(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|||||||
@@ -24,20 +24,17 @@ internal class StandardPreference<T>(
|
|||||||
/**
|
/**
|
||||||
* Returns the key of this preference.
|
* Returns the key of this preference.
|
||||||
*/
|
*/
|
||||||
override fun key(): String {
|
override fun key(): String = key
|
||||||
return key
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current value of this preference.
|
* Returns the current value of this preference.
|
||||||
*/
|
*/
|
||||||
override fun get(): T {
|
override fun get(): T =
|
||||||
return if (isSet()) {
|
if (isSet()) {
|
||||||
adapter.get(key, preferences)
|
adapter.get(key, preferences)
|
||||||
} else {
|
} else {
|
||||||
defaultValue
|
defaultValue
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a new [value] for this preference.
|
* Sets a new [value] for this preference.
|
||||||
@@ -49,9 +46,7 @@ internal class StandardPreference<T>(
|
|||||||
/**
|
/**
|
||||||
* Returns whether there's an existing entry for this preference.
|
* Returns whether there's an existing entry for this preference.
|
||||||
*/
|
*/
|
||||||
override fun isSet(): Boolean {
|
override fun isSet(): Boolean = adapter.isSet(preferences.keys, key)
|
||||||
return adapter.isSet(preferences.keys, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the entry of this preference.
|
* Deletes the entry of this preference.
|
||||||
@@ -63,27 +58,22 @@ internal class StandardPreference<T>(
|
|||||||
/**
|
/**
|
||||||
* Returns the default value of this preference
|
* Returns the default value of this preference
|
||||||
*/
|
*/
|
||||||
override fun defaultValue(): T {
|
override fun defaultValue(): T = defaultValue
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a cold [Flow] of this preference to receive updates when its value changes.
|
* Returns a cold [Flow] of this preference to receive updates when its value changes.
|
||||||
*/
|
*/
|
||||||
override fun changes(): Flow<T> {
|
override fun changes(): Flow<T> =
|
||||||
return callbackFlow {
|
callbackFlow {
|
||||||
val listener = adapter.addListener(key, preferences) {
|
val listener = adapter.addListener(key, preferences) {
|
||||||
trySend(get())
|
trySend(get())
|
||||||
}
|
}
|
||||||
awaitClose { listener.deactivate() }
|
awaitClose { listener.deactivate() }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a hot [StateFlow] of this preference bound to the given [scope], allowing to read the
|
* Returns a hot [StateFlow] of this preference bound to the given [scope], allowing to read the
|
||||||
* current value and receive preference updates.
|
* current value and receive preference updates.
|
||||||
*/
|
*/
|
||||||
override fun stateIn(scope: CoroutineScope): StateFlow<T> {
|
override fun stateIn(scope: CoroutineScope): StateFlow<T> = changes().stateIn(scope, SharingStarted.Eagerly, get())
|
||||||
return changes().stateIn(scope, SharingStarted.Eagerly, get())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import com.russhwolf.settings.ObservableSettings
|
|||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.modules.SerializersModule
|
import kotlinx.serialization.modules.SerializersModule
|
||||||
|
|
||||||
class StandardPreferenceStore(private val preferences: ObservableSettings) : PreferenceStore {
|
class StandardPreferenceStore(
|
||||||
|
private val preferences: ObservableSettings,
|
||||||
|
) : PreferenceStore {
|
||||||
/**
|
/**
|
||||||
* Returns an [String] preference for this [key].
|
* Returns an [String] preference for this [key].
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -31,11 +31,12 @@ object ImageUtil {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun charByteArrayOf(vararg bytes: Int): ByteArray {
|
private fun charByteArrayOf(vararg bytes: Int): ByteArray = ByteArray(bytes.size) { pos -> bytes[pos].toByte() }
|
||||||
return ByteArray(bytes.size) { pos -> bytes[pos].toByte() }
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class ImageType(val mime: String, val extension: String) {
|
enum class ImageType(
|
||||||
|
val mime: String,
|
||||||
|
val extension: String,
|
||||||
|
) {
|
||||||
JPG("image/jpeg", "jpg"),
|
JPG("image/jpeg", "jpg"),
|
||||||
PNG("image/png", "png"),
|
PNG("image/png", "png"),
|
||||||
GIF("image/gif", "gif"),
|
GIF("image/gif", "gif"),
|
||||||
|
|||||||
@@ -16,11 +16,10 @@ actual class PreferenceStoreFactory
|
|||||||
private val rootNode: Preferences = Preferences.userRoot()
|
private val rootNode: Preferences = Preferences.userRoot()
|
||||||
.node("ca/gosyer/tachideskjui")
|
.node("ca/gosyer/tachideskjui")
|
||||||
|
|
||||||
actual fun create(vararg names: String): PreferenceStore {
|
actual fun create(vararg names: String): PreferenceStore =
|
||||||
return StandardPreferenceStore(
|
StandardPreferenceStore(
|
||||||
PreferencesSettings(
|
PreferencesSettings(
|
||||||
rootNode.node(names.joinToString(separator = "/")),
|
rootNode.node(names.joinToString(separator = "/")),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,10 @@ import platform.Foundation.NSUserDefaults
|
|||||||
actual class PreferenceStoreFactory
|
actual class PreferenceStoreFactory
|
||||||
@Inject
|
@Inject
|
||||||
constructor() {
|
constructor() {
|
||||||
actual fun create(vararg names: String): PreferenceStore {
|
actual fun create(vararg names: String): PreferenceStore =
|
||||||
return StandardPreferenceStore(
|
StandardPreferenceStore(
|
||||||
NSUserDefaultsSettings(
|
NSUserDefaultsSettings(
|
||||||
NSUserDefaults.standardUserDefaults,
|
NSUserDefaults.standardUserDefaults,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,5 @@ class FlowConverterFactory : Converter.Factory {
|
|||||||
override fun suspendResponseConverter(
|
override fun suspendResponseConverter(
|
||||||
typeData: TypeData,
|
typeData: TypeData,
|
||||||
ktorfit: Ktorfit,
|
ktorfit: Ktorfit,
|
||||||
): Converter.SuspendResponseConverter<HttpResponse, *>? {
|
): Converter.SuspendResponseConverter<HttpResponse, *>? = null
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ import me.tatarka.inject.annotations.Provides
|
|||||||
abstract class AppComponent(
|
abstract class AppComponent(
|
||||||
@get:Provides
|
@get:Provides
|
||||||
val context: ContextWrapper,
|
val context: ContextWrapper,
|
||||||
) : ViewModelComponent, DataComponent, DomainComponent, UiComponent {
|
) : ViewModelComponent,
|
||||||
|
DataComponent,
|
||||||
|
DomainComponent,
|
||||||
|
UiComponent {
|
||||||
abstract val appMigrations: AppMigrations
|
abstract val appMigrations: AppMigrations
|
||||||
|
|
||||||
@get:AppScope
|
@get:AppScope
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ class Slf4jLogFactory : LogFactory {
|
|||||||
override fun createKmLog(
|
override fun createKmLog(
|
||||||
tag: String,
|
tag: String,
|
||||||
className: String,
|
className: String,
|
||||||
): KmLog {
|
): KmLog = Slf4jLog(tag)
|
||||||
return Slf4jLog(tag)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Slf4jLog(tag: String) : KmLog(tag) {
|
class Slf4jLog(
|
||||||
|
tag: String,
|
||||||
|
) : KmLog(tag) {
|
||||||
private val logger: Logger = LoggerFactory.getLogger(tag)
|
private val logger: Logger = LoggerFactory.getLogger(tag)
|
||||||
|
|
||||||
override fun verbose(
|
override fun verbose(
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class ExportBackupFile
|
class ExportBackupFile
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val backupRepository: BackupRepository) {
|
constructor(
|
||||||
|
private val backupRepository: BackupRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
block: HttpRequestBuilder.() -> Unit = {},
|
block: HttpRequestBuilder.() -> Unit = {},
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class ImportBackupFile
|
class ImportBackupFile
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val backupRepository: BackupRepository) {
|
constructor(
|
||||||
|
private val backupRepository: BackupRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
file: Path,
|
file: Path,
|
||||||
block: HttpRequestBuilder.() -> Unit = {},
|
block: HttpRequestBuilder.() -> Unit = {},
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class ValidateBackupFile
|
class ValidateBackupFile
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val backupRepository: BackupRepository) {
|
constructor(
|
||||||
|
private val backupRepository: BackupRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
file: Path,
|
file: Path,
|
||||||
block: HttpRequestBuilder.() -> Unit = {},
|
block: HttpRequestBuilder.() -> Unit = {},
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class CreateCategory
|
class CreateCategory
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val categoryRepository: CategoryRepository) {
|
constructor(
|
||||||
|
private val categoryRepository: CategoryRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
name: String,
|
name: String,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class DeleteCategory
|
class DeleteCategory
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val categoryRepository: CategoryRepository) {
|
constructor(
|
||||||
|
private val categoryRepository: CategoryRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
categoryId: Long,
|
categoryId: Long,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetCategories
|
class GetCategories
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val categoryRepository: CategoryRepository) {
|
constructor(
|
||||||
|
private val categoryRepository: CategoryRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
dropDefault: Boolean = false,
|
dropDefault: Boolean = false,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetMangaCategories
|
class GetMangaCategories
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val categoryRepository: CategoryRepository) {
|
constructor(
|
||||||
|
private val categoryRepository: CategoryRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class ModifyCategory
|
class ModifyCategory
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val categoryRepository: CategoryRepository) {
|
constructor(
|
||||||
|
private val categoryRepository: CategoryRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
categoryId: Long,
|
categoryId: Long,
|
||||||
name: String,
|
name: String,
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class ReorderCategory
|
class ReorderCategory
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val categoryRepository: CategoryRepository) {
|
constructor(
|
||||||
|
private val categoryRepository: CategoryRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
to: Int,
|
to: Int,
|
||||||
from: Int,
|
from: Int,
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class UpdateCategoryMeta
|
class UpdateCategoryMeta
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val categoryRepository: CategoryRepository) {
|
constructor(
|
||||||
|
private val categoryRepository: CategoryRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
category: Category,
|
category: Category,
|
||||||
example: Int = category.meta.example,
|
example: Int = category.meta.example,
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetChapterPage
|
class GetChapterPage
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val chapterRepository: ChapterRepository) {
|
constructor(
|
||||||
|
private val chapterRepository: ChapterRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
index: Int,
|
index: Int,
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class BatchChapterDownload
|
class BatchChapterDownload
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val downloadRepository: DownloadRepository) {
|
constructor(
|
||||||
|
private val downloadRepository: DownloadRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
chapterIds: List<Long>,
|
chapterIds: List<Long>,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class ClearDownloadQueue
|
class ClearDownloadQueue
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val downloadRepository: DownloadRepository) {
|
constructor(
|
||||||
|
private val downloadRepository: DownloadRepository,
|
||||||
|
) {
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
asFlow()
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class QueueChapterDownload
|
class QueueChapterDownload
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val downloadRepository: DownloadRepository) {
|
constructor(
|
||||||
|
private val downloadRepository: DownloadRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
index: Int,
|
index: Int,
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class ReorderChapterDownload
|
class ReorderChapterDownload
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val downloadRepository: DownloadRepository) {
|
constructor(
|
||||||
|
private val downloadRepository: DownloadRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
index: Int,
|
index: Int,
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class StartDownloading
|
class StartDownloading
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val downloadRepository: DownloadRepository) {
|
constructor(
|
||||||
|
private val downloadRepository: DownloadRepository,
|
||||||
|
) {
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
asFlow()
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class StopChapterDownload
|
class StopChapterDownload
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val downloadRepository: DownloadRepository) {
|
constructor(
|
||||||
|
private val downloadRepository: DownloadRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
index: Int,
|
index: Int,
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class StopDownloading
|
class StopDownloading
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val downloadRepository: DownloadRepository) {
|
constructor(
|
||||||
|
private val downloadRepository: DownloadRepository,
|
||||||
|
) {
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
asFlow()
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ import kotlinx.serialization.Serializable
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@Stable
|
@Stable
|
||||||
enum class DownloadState(val state: Int) {
|
enum class DownloadState(
|
||||||
|
val state: Int,
|
||||||
|
) {
|
||||||
Queued(0),
|
Queued(0),
|
||||||
Downloading(1),
|
Downloading(1),
|
||||||
Finished(2),
|
Finished(2),
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class DownloadService
|
|||||||
.map {
|
.map {
|
||||||
it.filter { it.mangaId == mangaId }
|
it.filter { it.mangaId == mangaId }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerWatches(mangaIds: Set<Long>) =
|
fun registerWatches(mangaIds: Set<Long>) =
|
||||||
downloadQueue
|
downloadQueue
|
||||||
.map {
|
.map {
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetExtensionList
|
class GetExtensionList
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val extensionRepository: ExtensionRepository) {
|
constructor(
|
||||||
|
private val extensionRepository: ExtensionRepository,
|
||||||
|
) {
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
asFlow()
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class InstallExtension
|
class InstallExtension
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val extensionRepository: ExtensionRepository) {
|
constructor(
|
||||||
|
private val extensionRepository: ExtensionRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
extension: Extension,
|
extension: Extension,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class InstallExtensionFile
|
class InstallExtensionFile
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val extensionRepository: ExtensionRepository) {
|
constructor(
|
||||||
|
private val extensionRepository: ExtensionRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
path: Path,
|
path: Path,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class UninstallExtension
|
class UninstallExtension
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val extensionRepository: ExtensionRepository) {
|
constructor(
|
||||||
|
private val extensionRepository: ExtensionRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
extension: Extension,
|
extension: Extension,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class UpdateExtension
|
class UpdateExtension
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val extensionRepository: ExtensionRepository) {
|
constructor(
|
||||||
|
private val extensionRepository: ExtensionRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
extension: Extension,
|
extension: Extension,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -10,8 +10,12 @@ import androidx.compose.ui.text.intl.Locale
|
|||||||
import ca.gosyer.jui.core.prefs.Preference
|
import ca.gosyer.jui.core.prefs.Preference
|
||||||
import ca.gosyer.jui.core.prefs.PreferenceStore
|
import ca.gosyer.jui.core.prefs.PreferenceStore
|
||||||
|
|
||||||
class ExtensionPreferences(private val preferenceStore: PreferenceStore) {
|
class ExtensionPreferences(
|
||||||
fun languages(): Preference<Set<String>> {
|
private val preferenceStore: PreferenceStore,
|
||||||
return preferenceStore.getStringSet("enabled_langs", setOfNotNull("all", "en", Locale.current.language))
|
) {
|
||||||
}
|
fun languages(): Preference<Set<String>> =
|
||||||
|
preferenceStore.getStringSet(
|
||||||
|
"enabled_langs",
|
||||||
|
setOfNotNull("all", "en", Locale.current.language),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetGlobalMeta
|
class GetGlobalMeta
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val globalRepository: GlobalRepository) {
|
constructor(
|
||||||
|
private val globalRepository: GlobalRepository,
|
||||||
|
) {
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
asFlow()
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class UpdateGlobalMeta
|
class UpdateGlobalMeta
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val globalRepository: GlobalRepository) {
|
constructor(
|
||||||
|
private val globalRepository: GlobalRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
globalMeta: GlobalMeta,
|
globalMeta: GlobalMeta,
|
||||||
example: Int = globalMeta.example,
|
example: Int = globalMeta.example,
|
||||||
|
|||||||
@@ -11,56 +11,52 @@ import ca.gosyer.jui.core.prefs.PreferenceStore
|
|||||||
import ca.gosyer.jui.domain.library.model.FilterState
|
import ca.gosyer.jui.domain.library.model.FilterState
|
||||||
import ca.gosyer.jui.domain.library.model.Sort
|
import ca.gosyer.jui.domain.library.model.Sort
|
||||||
|
|
||||||
class LibraryPreferences(private val preferenceStore: PreferenceStore) {
|
class LibraryPreferences(
|
||||||
fun showAllCategory(): Preference<Boolean> {
|
private val preferenceStore: PreferenceStore,
|
||||||
return preferenceStore.getBoolean("show_all_category", false)
|
) {
|
||||||
}
|
fun showAllCategory(): Preference<Boolean> = preferenceStore.getBoolean("show_all_category", false)
|
||||||
|
|
||||||
fun filterDownloaded(): Preference<FilterState> {
|
fun filterDownloaded(): Preference<FilterState> =
|
||||||
return preferenceStore.getJsonObject("filter_downloaded", FilterState.IGNORED, FilterState.serializer())
|
preferenceStore.getJsonObject(
|
||||||
}
|
"filter_downloaded",
|
||||||
|
FilterState.IGNORED,
|
||||||
|
FilterState.serializer(),
|
||||||
|
)
|
||||||
|
|
||||||
fun filterUnread(): Preference<FilterState> {
|
fun filterUnread(): Preference<FilterState> =
|
||||||
return preferenceStore.getJsonObject("filter_unread", FilterState.IGNORED, FilterState.serializer())
|
preferenceStore.getJsonObject(
|
||||||
}
|
"filter_unread",
|
||||||
|
FilterState.IGNORED,
|
||||||
|
FilterState.serializer(),
|
||||||
|
)
|
||||||
|
|
||||||
fun filterCompleted(): Preference<FilterState> {
|
fun filterCompleted(): Preference<FilterState> =
|
||||||
return preferenceStore.getJsonObject("filter_completed", FilterState.IGNORED, FilterState.serializer())
|
preferenceStore.getJsonObject(
|
||||||
}
|
"filter_completed",
|
||||||
|
FilterState.IGNORED,
|
||||||
|
FilterState.serializer(),
|
||||||
|
)
|
||||||
|
|
||||||
fun sortMode(): Preference<Sort> {
|
fun sortMode(): Preference<Sort> = preferenceStore.getJsonObject("sort_mode", Sort.ALPHABETICAL, Sort.serializer())
|
||||||
return preferenceStore.getJsonObject("sort_mode", Sort.ALPHABETICAL, Sort.serializer())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun sortAscending(): Preference<Boolean> {
|
fun sortAscending(): Preference<Boolean> = preferenceStore.getBoolean("sort_ascending", true)
|
||||||
return preferenceStore.getBoolean("sort_ascending", true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun displayMode(): Preference<ca.gosyer.jui.domain.library.model.DisplayMode> {
|
fun displayMode(): Preference<ca.gosyer.jui.domain.library.model.DisplayMode> =
|
||||||
return preferenceStore.getJsonObject("display_mode", ca.gosyer.jui.domain.library.model.DisplayMode.CompactGrid, ca.gosyer.jui.domain.library.model.DisplayMode.serializer())
|
preferenceStore.getJsonObject(
|
||||||
}
|
"display_mode",
|
||||||
|
ca.gosyer.jui.domain.library.model.DisplayMode.CompactGrid,
|
||||||
|
ca.gosyer.jui.domain.library.model.DisplayMode.serializer(),
|
||||||
|
)
|
||||||
|
|
||||||
fun gridColumns(): Preference<Int> {
|
fun gridColumns(): Preference<Int> = preferenceStore.getInt("grid_columns", 0)
|
||||||
return preferenceStore.getInt("grid_columns", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun gridSize(): Preference<Int> {
|
fun gridSize(): Preference<Int> = preferenceStore.getInt("grid_size", 160)
|
||||||
return preferenceStore.getInt("grid_size", 160)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun unreadBadge(): Preference<Boolean> {
|
fun unreadBadge(): Preference<Boolean> = preferenceStore.getBoolean("unread_badge", true)
|
||||||
return preferenceStore.getBoolean("unread_badge", true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun downloadBadge(): Preference<Boolean> {
|
fun downloadBadge(): Preference<Boolean> = preferenceStore.getBoolean("download_badge", false)
|
||||||
return preferenceStore.getBoolean("download_badge", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun languageBadge(): Preference<Boolean> {
|
fun languageBadge(): Preference<Boolean> = preferenceStore.getBoolean("language_badge", false)
|
||||||
return preferenceStore.getBoolean("language_badge", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun localBadge(): Preference<Boolean> {
|
fun localBadge(): Preference<Boolean> = preferenceStore.getBoolean("local_badge", false)
|
||||||
return preferenceStore.getBoolean("local_badge", false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,10 @@ package ca.gosyer.jui.domain.migration.service
|
|||||||
import ca.gosyer.jui.core.prefs.Preference
|
import ca.gosyer.jui.core.prefs.Preference
|
||||||
import ca.gosyer.jui.core.prefs.PreferenceStore
|
import ca.gosyer.jui.core.prefs.PreferenceStore
|
||||||
|
|
||||||
class MigrationPreferences(private val preferenceStore: PreferenceStore) {
|
class MigrationPreferences(
|
||||||
fun version(): Preference<Int> {
|
private val preferenceStore: PreferenceStore,
|
||||||
return preferenceStore.getInt("version", 0)
|
) {
|
||||||
}
|
fun version(): Preference<Int> = preferenceStore.getInt("version", 0)
|
||||||
fun appVersion(): Preference<Int> {
|
|
||||||
return preferenceStore.getInt("app_version", 0)
|
fun appVersion(): Preference<Int> = preferenceStore.getInt("app_version", 0)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ import kotlinx.serialization.Serializable
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@Stable
|
@Stable
|
||||||
enum class TappingInvertMode(val shouldInvertHorizontal: Boolean = false, val shouldInvertVertical: Boolean = false) {
|
enum class TappingInvertMode(
|
||||||
|
val shouldInvertHorizontal: Boolean = false,
|
||||||
|
val shouldInvertVertical: Boolean = false,
|
||||||
|
) {
|
||||||
NONE,
|
NONE,
|
||||||
HORIZONTAL(shouldInvertHorizontal = true),
|
HORIZONTAL(shouldInvertHorizontal = true),
|
||||||
VERTICAL(shouldInvertVertical = true),
|
VERTICAL(shouldInvertVertical = true),
|
||||||
|
|||||||
@@ -13,38 +13,39 @@ import ca.gosyer.jui.domain.reader.model.Direction
|
|||||||
import ca.gosyer.jui.domain.reader.model.ImageScale
|
import ca.gosyer.jui.domain.reader.model.ImageScale
|
||||||
import ca.gosyer.jui.domain.reader.model.NavigationMode
|
import ca.gosyer.jui.domain.reader.model.NavigationMode
|
||||||
|
|
||||||
class ReaderModePreferences(private val mode: String, private val preferenceStore: PreferenceStore) {
|
class ReaderModePreferences(
|
||||||
|
private val mode: String,
|
||||||
|
private val preferenceStore: PreferenceStore,
|
||||||
|
) {
|
||||||
constructor(mode: String, factory: (String) -> PreferenceStore) :
|
constructor(mode: String, factory: (String) -> PreferenceStore) :
|
||||||
this(mode, factory(mode))
|
this(mode, factory(mode))
|
||||||
|
|
||||||
private val defaultMode by lazy { DefaultReaderMode.values().find { it.res == mode } }
|
private val defaultMode by lazy { DefaultReaderMode.values().find { it.res == mode } }
|
||||||
|
|
||||||
fun default(): Preference<Boolean> {
|
fun default(): Preference<Boolean> = preferenceStore.getBoolean("default", defaultMode != null)
|
||||||
return preferenceStore.getBoolean("default", defaultMode != null)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun continuous(): Preference<Boolean> {
|
fun continuous(): Preference<Boolean> = preferenceStore.getBoolean("continuous", defaultMode?.continuous ?: false)
|
||||||
return preferenceStore.getBoolean("continuous", defaultMode?.continuous ?: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun direction(): Preference<Direction> {
|
fun direction(): Preference<Direction> =
|
||||||
return preferenceStore.getJsonObject("direction", defaultMode?.direction ?: Direction.Down, Direction.serializer())
|
preferenceStore.getJsonObject(
|
||||||
}
|
"direction",
|
||||||
|
defaultMode?.direction ?: Direction.Down,
|
||||||
|
Direction.serializer(),
|
||||||
|
)
|
||||||
|
|
||||||
fun padding(): Preference<Int> {
|
fun padding(): Preference<Int> = preferenceStore.getInt("padding", defaultMode?.padding ?: 0)
|
||||||
return preferenceStore.getInt("padding", defaultMode?.padding ?: 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun imageScale(): Preference<ImageScale> {
|
fun imageScale(): Preference<ImageScale> =
|
||||||
return preferenceStore.getJsonObject("image_scale", defaultMode?.imageScale ?: ImageScale.FitScreen, ImageScale.serializer())
|
preferenceStore.getJsonObject(
|
||||||
}
|
"image_scale",
|
||||||
|
defaultMode?.imageScale ?: ImageScale.FitScreen,
|
||||||
|
ImageScale.serializer(),
|
||||||
|
)
|
||||||
|
|
||||||
fun fitSize(): Preference<Boolean> {
|
fun fitSize(): Preference<Boolean> = preferenceStore.getBoolean("fit_size", false)
|
||||||
return preferenceStore.getBoolean("fit_size", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun maxSize(): Preference<Int> {
|
fun maxSize(): Preference<Int> =
|
||||||
return preferenceStore.getInt(
|
preferenceStore.getInt(
|
||||||
"max_size",
|
"max_size",
|
||||||
if (defaultMode?.continuous == true) {
|
if (defaultMode?.continuous == true) {
|
||||||
if (defaultMode?.direction == Direction.Left || defaultMode?.direction == Direction.Right) {
|
if (defaultMode?.direction == Direction.Left || defaultMode?.direction == Direction.Right) {
|
||||||
@@ -56,9 +57,11 @@ class ReaderModePreferences(private val mode: String, private val preferenceStor
|
|||||||
0
|
0
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
fun navigationMode(): Preference<NavigationMode> {
|
fun navigationMode(): Preference<NavigationMode> =
|
||||||
return preferenceStore.getJsonObject("navigation", defaultMode?.navigationMode ?: NavigationMode.LNavigation, NavigationMode.serializer())
|
preferenceStore.getJsonObject(
|
||||||
}
|
"navigation",
|
||||||
|
defaultMode?.navigationMode ?: NavigationMode.LNavigation,
|
||||||
|
NavigationMode.serializer(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,28 +12,22 @@ import ca.gosyer.jui.domain.reader.model.DefaultReaderMode
|
|||||||
import kotlinx.serialization.builtins.ListSerializer
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
class ReaderPreferences(private val preferenceStore: PreferenceStore, private val factory: (String) -> PreferenceStore) {
|
class ReaderPreferences(
|
||||||
fun preload(): Preference<Int> {
|
private val preferenceStore: PreferenceStore,
|
||||||
return preferenceStore.getInt("preload", 3)
|
private val factory: (String) -> PreferenceStore,
|
||||||
}
|
) {
|
||||||
|
fun preload(): Preference<Int> = preferenceStore.getInt("preload", 3)
|
||||||
|
|
||||||
fun threads(): Preference<Int> {
|
fun threads(): Preference<Int> = preferenceStore.getInt("threads", 3)
|
||||||
return preferenceStore.getInt("threads", 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun modes(): Preference<List<String>> {
|
fun modes(): Preference<List<String>> =
|
||||||
return preferenceStore.getJsonObject(
|
preferenceStore.getJsonObject(
|
||||||
"modes",
|
"modes",
|
||||||
DefaultReaderMode.values().map { it.res },
|
DefaultReaderMode.values().map { it.res },
|
||||||
ListSerializer(String.serializer()),
|
ListSerializer(String.serializer()),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
fun mode(): Preference<String> {
|
fun mode(): Preference<String> = preferenceStore.getString("mode", "RTL")
|
||||||
return preferenceStore.getString("mode", "RTL")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getMode(mode: String): ReaderModePreferences {
|
fun getMode(mode: String): ReaderModePreferences = ReaderModePreferences(mode, factory)
|
||||||
return ReaderModePreferences(mode, factory)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ expect fun HttpClientConfig<HttpClientEngineConfig>.configurePlatform()
|
|||||||
fun httpClient(
|
fun httpClient(
|
||||||
serverPreferences: ServerPreferences,
|
serverPreferences: ServerPreferences,
|
||||||
json: Json,
|
json: Json,
|
||||||
): Http {
|
): Http =
|
||||||
return HttpClient(Engine) {
|
HttpClient(Engine) {
|
||||||
configurePlatform()
|
configurePlatform()
|
||||||
|
|
||||||
expectSuccess = true
|
expectSuccess = true
|
||||||
@@ -112,10 +112,10 @@ fun httpClient(
|
|||||||
}
|
}
|
||||||
logger = object : Logger {
|
logger = object : Logger {
|
||||||
val log = logging("HttpClient")
|
val log = logging("HttpClient")
|
||||||
|
|
||||||
override fun log(message: String) {
|
override fun log(message: String) {
|
||||||
log.info { message }
|
log.info { message }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -25,18 +25,15 @@ class ServerUrlPreference(
|
|||||||
private val port: Preference<Int>,
|
private val port: Preference<Int>,
|
||||||
private val pathPrefix: Preference<String>,
|
private val pathPrefix: Preference<String>,
|
||||||
) : Preference<Url> {
|
) : Preference<Url> {
|
||||||
override fun key(): String {
|
override fun key(): String = key
|
||||||
return key
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun get(): Url {
|
override fun get(): Url =
|
||||||
return URLBuilder(server.get()).apply {
|
URLBuilder(server.get()).apply {
|
||||||
port = this@ServerUrlPreference.port.get()
|
port = this@ServerUrlPreference.port.get()
|
||||||
if (pathPrefix.isSet()) {
|
if (pathPrefix.isSet()) {
|
||||||
pathPrefix.get().ifBlank { null }?.let { path(it) }
|
pathPrefix.get().ifBlank { null }?.let { path(it) }
|
||||||
}
|
}
|
||||||
}.build()
|
}.build()
|
||||||
}
|
|
||||||
|
|
||||||
override fun set(value: Url) {
|
override fun set(value: Url) {
|
||||||
server.set(value.protocol.name + "://" + value.host)
|
server.set(value.protocol.name + "://" + value.host)
|
||||||
@@ -44,9 +41,7 @@ class ServerUrlPreference(
|
|||||||
pathPrefix.set(value.encodedPath)
|
pathPrefix.set(value.encodedPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isSet(): Boolean {
|
override fun isSet(): Boolean = server.isSet() || port.isSet() || pathPrefix.isSet()
|
||||||
return server.isSet() || port.isSet() || pathPrefix.isSet()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun delete() {
|
override fun delete() {
|
||||||
server.delete()
|
server.delete()
|
||||||
@@ -54,14 +49,13 @@ class ServerUrlPreference(
|
|||||||
pathPrefix.delete()
|
pathPrefix.delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun defaultValue(): Url {
|
override fun defaultValue(): Url =
|
||||||
return URLBuilder(server.defaultValue()).apply {
|
URLBuilder(server.defaultValue()).apply {
|
||||||
port = this@ServerUrlPreference.port.defaultValue()
|
port = this@ServerUrlPreference.port.defaultValue()
|
||||||
}.build()
|
}.build()
|
||||||
}
|
|
||||||
|
|
||||||
override fun changes(): Flow<Url> {
|
override fun changes(): Flow<Url> =
|
||||||
return combine(server.getAsFlow(), port.getAsFlow(), pathPrefix.getAsFlow()) { server, port, pathPrefix ->
|
combine(server.getAsFlow(), port.getAsFlow(), pathPrefix.getAsFlow()) { server, port, pathPrefix ->
|
||||||
URLBuilder(server).apply {
|
URLBuilder(server).apply {
|
||||||
this.port = port
|
this.port = port
|
||||||
if (pathPrefix.isNotBlank()) {
|
if (pathPrefix.isNotBlank()) {
|
||||||
@@ -69,9 +63,6 @@ class ServerUrlPreference(
|
|||||||
}
|
}
|
||||||
}.build()
|
}.build()
|
||||||
}.drop(1)
|
}.drop(1)
|
||||||
}
|
|
||||||
|
|
||||||
override fun stateIn(scope: CoroutineScope): StateFlow<Url> {
|
override fun stateIn(scope: CoroutineScope): StateFlow<Url> = changes().stateIn(scope, SharingStarted.Eagerly, get())
|
||||||
return changes().stateIn(scope, SharingStarted.Eagerly, get())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,51 +13,30 @@ import ca.gosyer.jui.domain.server.model.Proxy
|
|||||||
import ca.gosyer.jui.domain.server.model.ServerUrlPreference
|
import ca.gosyer.jui.domain.server.model.ServerUrlPreference
|
||||||
import io.ktor.http.Url
|
import io.ktor.http.Url
|
||||||
|
|
||||||
class ServerPreferences(private val preferenceStore: PreferenceStore) {
|
class ServerPreferences(
|
||||||
fun server(): Preference<String> {
|
private val preferenceStore: PreferenceStore,
|
||||||
return preferenceStore.getString("server_url", "http://localhost")
|
) {
|
||||||
}
|
fun server(): Preference<String> = preferenceStore.getString("server_url", "http://localhost")
|
||||||
|
|
||||||
fun port(): Preference<Int> {
|
fun port(): Preference<Int> = preferenceStore.getInt("server_port", 4567)
|
||||||
return preferenceStore.getInt("server_port", 4567)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun pathPrefix(): Preference<String> {
|
fun pathPrefix(): Preference<String> = preferenceStore.getString("server_path_prefix", "")
|
||||||
return preferenceStore.getString("server_path_prefix", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun serverUrl(): Preference<Url> {
|
fun serverUrl(): Preference<Url> = ServerUrlPreference("", server(), port(), pathPrefix())
|
||||||
return ServerUrlPreference("", server(), port(), pathPrefix())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun proxy(): Preference<Proxy> {
|
fun proxy(): Preference<Proxy> = preferenceStore.getJsonObject("proxy", Proxy.NO_PROXY, Proxy.serializer())
|
||||||
return preferenceStore.getJsonObject("proxy", Proxy.NO_PROXY, Proxy.serializer())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun proxyHttpHost(): Preference<String> {
|
fun proxyHttpHost(): Preference<String> = preferenceStore.getString("proxy_http_host")
|
||||||
return preferenceStore.getString("proxy_http_host")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun proxyHttpPort(): Preference<Int> {
|
fun proxyHttpPort(): Preference<Int> = preferenceStore.getInt("proxy_http_port")
|
||||||
return preferenceStore.getInt("proxy_http_port")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun proxySocksHost(): Preference<String> {
|
fun proxySocksHost(): Preference<String> = preferenceStore.getString("proxy_socks_host")
|
||||||
return preferenceStore.getString("proxy_socks_host")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun proxySocksPort(): Preference<Int> {
|
fun proxySocksPort(): Preference<Int> = preferenceStore.getInt("proxy_socks_port")
|
||||||
return preferenceStore.getInt("proxy_socks_port")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun auth(): Preference<Auth> {
|
fun auth(): Preference<Auth> = preferenceStore.getJsonObject("auth", Auth.NONE, Auth.serializer())
|
||||||
return preferenceStore.getJsonObject("auth", Auth.NONE, Auth.serializer())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun authUsername(): Preference<String> {
|
fun authUsername(): Preference<String> = preferenceStore.getString("auth_username")
|
||||||
return preferenceStore.getString("auth_username")
|
|
||||||
}
|
fun authPassword(): Preference<String> = preferenceStore.getString("auth_password")
|
||||||
fun authPassword(): Preference<String> {
|
|
||||||
return preferenceStore.getString("auth_password")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class AboutServer
|
class AboutServer
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val settingsRepository: SettingsRepository) {
|
constructor(
|
||||||
|
private val settingsRepository: SettingsRepository,
|
||||||
|
) {
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
asFlow()
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class CheckUpdate
|
class CheckUpdate
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val settingsRepository: SettingsRepository) {
|
constructor(
|
||||||
|
private val settingsRepository: SettingsRepository,
|
||||||
|
) {
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
asFlow()
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetFilterList
|
class GetFilterList
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val sourceRepository: SourceRepository) {
|
constructor(
|
||||||
|
private val sourceRepository: SourceRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
source: Source,
|
source: Source,
|
||||||
reset: Boolean,
|
reset: Boolean,
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetLatestManga
|
class GetLatestManga
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val sourceRepository: SourceRepository) {
|
constructor(
|
||||||
|
private val sourceRepository: SourceRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
source: Source,
|
source: Source,
|
||||||
page: Int,
|
page: Int,
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetPopularManga
|
class GetPopularManga
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val sourceRepository: SourceRepository) {
|
constructor(
|
||||||
|
private val sourceRepository: SourceRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
source: Source,
|
source: Source,
|
||||||
page: Int,
|
page: Int,
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetQuickSearchManga
|
class GetQuickSearchManga
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val sourceRepository: SourceRepository) {
|
constructor(
|
||||||
|
private val sourceRepository: SourceRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
source: Source,
|
source: Source,
|
||||||
searchTerm: String?,
|
searchTerm: String?,
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetSearchManga
|
class GetSearchManga
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val sourceRepository: SourceRepository) {
|
constructor(
|
||||||
|
private val sourceRepository: SourceRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
source: Source,
|
source: Source,
|
||||||
searchTerm: String?,
|
searchTerm: String?,
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetSourceList
|
class GetSourceList
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val sourceRepository: SourceRepository) {
|
constructor(
|
||||||
|
private val sourceRepository: SourceRepository,
|
||||||
|
) {
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
asFlow()
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetSourceSettings
|
class GetSourceSettings
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val sourceRepository: SourceRepository) {
|
constructor(
|
||||||
|
private val sourceRepository: SourceRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
source: Source,
|
source: Source,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class SetSourceFilter
|
class SetSourceFilter
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val sourceRepository: SourceRepository) {
|
constructor(
|
||||||
|
private val sourceRepository: SourceRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
source: Source,
|
source: Source,
|
||||||
filterIndex: Int,
|
filterIndex: Int,
|
||||||
@@ -56,7 +58,8 @@ class SetSourceFilter
|
|||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) {
|
log.warn(it) {
|
||||||
"Failed to set filter for ${source.displayName} with index = $filterIndex and childIndex = $childFilterIndex and value = $filter"
|
"Failed to set filter for ${source.displayName} with index = $filterIndex " +
|
||||||
|
"and childIndex = $childFilterIndex and value = $filter"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
@@ -71,7 +74,10 @@ class SetSourceFilter
|
|||||||
) = asFlow(sourceId, filterIndex, childFilterIndex, filter)
|
) = asFlow(sourceId, filterIndex, childFilterIndex, filter)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to set filter for $sourceId with index = $filterIndex and childIndex = $childFilterIndex and value = $filter" }
|
log.warn(it) {
|
||||||
|
"Failed to set filter for $sourceId with index = $filterIndex " +
|
||||||
|
"and childIndex = $childFilterIndex and value = $filter"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class SetSourceSetting
|
class SetSourceSetting
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val sourceRepository: SourceRepository) {
|
constructor(
|
||||||
|
private val sourceRepository: SourceRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
source: Source,
|
source: Source,
|
||||||
settingIndex: Int,
|
settingIndex: Int,
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ import kotlinx.serialization.encodeToString
|
|||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class SourceFilterChange(val position: Int, val state: String) {
|
data class SourceFilterChange(
|
||||||
|
val position: Int,
|
||||||
|
val state: String,
|
||||||
|
) {
|
||||||
constructor(position: Int, state: Any) : this(
|
constructor(position: Int, state: Any) : this(
|
||||||
position,
|
position,
|
||||||
if (state is SortFilter.Selection) {
|
if (state is SortFilter.Selection) {
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ import kotlinx.serialization.Serializable
|
|||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("ListPreference")
|
@SerialName("ListPreference")
|
||||||
@Immutable
|
@Immutable
|
||||||
data class ListPreference(override val props: ListProps) : SourcePreference() {
|
data class ListPreference(
|
||||||
|
override val props: ListProps,
|
||||||
|
) : SourcePreference() {
|
||||||
@Serializable
|
@Serializable
|
||||||
@Immutable
|
@Immutable
|
||||||
data class ListProps(
|
data class ListProps(
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ import kotlinx.serialization.Serializable
|
|||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("MultiSelectListPreference")
|
@SerialName("MultiSelectListPreference")
|
||||||
@Immutable
|
@Immutable
|
||||||
data class MultiSelectListPreference(override val props: MultiSelectListProps) : SourcePreference() {
|
data class MultiSelectListPreference(
|
||||||
|
override val props: MultiSelectListProps,
|
||||||
|
) : SourcePreference() {
|
||||||
@Serializable
|
@Serializable
|
||||||
@Immutable
|
@Immutable
|
||||||
data class MultiSelectListProps(
|
data class MultiSelectListProps(
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ import kotlinx.serialization.encodeToString
|
|||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class SourcePreferenceChange(val position: Int, val value: String) {
|
data class SourcePreferenceChange(
|
||||||
|
val position: Int,
|
||||||
|
val value: String,
|
||||||
|
) {
|
||||||
constructor(position: Int, value: Any) : this(
|
constructor(position: Int, value: Any) : this(
|
||||||
position,
|
position,
|
||||||
if (value is List<*>) {
|
if (value is List<*>) {
|
||||||
|
|||||||
@@ -11,12 +11,15 @@ import ca.gosyer.jui.core.prefs.Preference
|
|||||||
import ca.gosyer.jui.core.prefs.PreferenceStore
|
import ca.gosyer.jui.core.prefs.PreferenceStore
|
||||||
import ca.gosyer.jui.domain.library.model.DisplayMode
|
import ca.gosyer.jui.domain.library.model.DisplayMode
|
||||||
|
|
||||||
class CatalogPreferences(private val preferenceStore: PreferenceStore) {
|
class CatalogPreferences(
|
||||||
fun languages(): Preference<Set<String>> {
|
private val preferenceStore: PreferenceStore,
|
||||||
return preferenceStore.getStringSet("enabled_langs", setOfNotNull("en", Locale.current.language))
|
) {
|
||||||
}
|
fun languages(): Preference<Set<String>> = preferenceStore.getStringSet("enabled_langs", setOfNotNull("en", Locale.current.language))
|
||||||
|
|
||||||
fun displayMode(): Preference<DisplayMode> {
|
fun displayMode(): Preference<DisplayMode> =
|
||||||
return preferenceStore.getJsonObject("display_mode", DisplayMode.CompactGrid, DisplayMode.serializer())
|
preferenceStore.getJsonObject(
|
||||||
}
|
"display_mode",
|
||||||
|
DisplayMode.CompactGrid,
|
||||||
|
DisplayMode.serializer(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,68 +12,48 @@ import ca.gosyer.jui.domain.ui.model.StartScreen
|
|||||||
import ca.gosyer.jui.domain.ui.model.ThemeMode
|
import ca.gosyer.jui.domain.ui.model.ThemeMode
|
||||||
import ca.gosyer.jui.domain.ui.model.WindowSettings
|
import ca.gosyer.jui.domain.ui.model.WindowSettings
|
||||||
|
|
||||||
class UiPreferences(private val preferenceStore: PreferenceStore) {
|
class UiPreferences(
|
||||||
fun themeMode(): Preference<ThemeMode> {
|
private val preferenceStore: PreferenceStore,
|
||||||
return preferenceStore.getJsonObject("theme_mode", ThemeMode.System, ThemeMode.serializer())
|
) {
|
||||||
}
|
fun themeMode(): Preference<ThemeMode> = preferenceStore.getJsonObject("theme_mode", ThemeMode.System, ThemeMode.serializer())
|
||||||
|
|
||||||
fun lightTheme(): Preference<Int> {
|
fun lightTheme(): Preference<Int> = preferenceStore.getInt("theme_light", 0)
|
||||||
return preferenceStore.getInt("theme_light", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun darkTheme(): Preference<Int> {
|
fun darkTheme(): Preference<Int> = preferenceStore.getInt("theme_dark", 0)
|
||||||
return preferenceStore.getInt("theme_dark", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun colorPrimaryLight(): Preference<Int> {
|
fun colorPrimaryLight(): Preference<Int> = preferenceStore.getInt("color_primary_light", 0)
|
||||||
return preferenceStore.getInt("color_primary_light", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun colorPrimaryDark(): Preference<Int> {
|
fun colorPrimaryDark(): Preference<Int> = preferenceStore.getInt("color_primary_dark", 0)
|
||||||
return preferenceStore.getInt("color_primary_dark", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun colorSecondaryLight(): Preference<Int> {
|
fun colorSecondaryLight(): Preference<Int> = preferenceStore.getInt("color_secondary_light", 0)
|
||||||
return preferenceStore.getInt("color_secondary_light", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun colorSecondaryDark(): Preference<Int> {
|
fun colorSecondaryDark(): Preference<Int> = preferenceStore.getInt("color_secondary_dark", 0)
|
||||||
return preferenceStore.getInt("color_secondary_dark", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun colorTertiaryLight(): Preference<Int> {
|
fun colorTertiaryLight(): Preference<Int> = preferenceStore.getInt("color_tertiary_light", 0)
|
||||||
return preferenceStore.getInt("color_tertiary_light", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun colorTertiaryDark(): Preference<Int> {
|
fun colorTertiaryDark(): Preference<Int> = preferenceStore.getInt("color_tertiary_dark", 0)
|
||||||
return preferenceStore.getInt("color_tertiary_dark", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun startScreen(): Preference<StartScreen> {
|
fun startScreen(): Preference<StartScreen> =
|
||||||
return preferenceStore.getJsonObject("start_screen", StartScreen.Library, StartScreen.serializer())
|
preferenceStore.getJsonObject(
|
||||||
}
|
"start_screen",
|
||||||
|
StartScreen.Library,
|
||||||
|
StartScreen.serializer(),
|
||||||
|
)
|
||||||
|
|
||||||
fun confirmExit(): Preference<Boolean> {
|
fun confirmExit(): Preference<Boolean> = preferenceStore.getBoolean("confirm_exit", false)
|
||||||
return preferenceStore.getBoolean("confirm_exit", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun language(): Preference<String> {
|
fun language(): Preference<String> = preferenceStore.getString("language", "")
|
||||||
return preferenceStore.getString("language", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun dateFormat(): Preference<String> {
|
fun dateFormat(): Preference<String> = preferenceStore.getString("date_format", "")
|
||||||
return preferenceStore.getString("date_format", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun window(): Preference<WindowSettings> {
|
fun window(): Preference<WindowSettings> = preferenceStore.getJsonObject("window", WindowSettings(), WindowSettings.serializer())
|
||||||
return preferenceStore.getJsonObject("window", WindowSettings(), WindowSettings.serializer())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun readerWindow(): Preference<WindowSettings> {
|
fun readerWindow(): Preference<WindowSettings> =
|
||||||
return preferenceStore.getJsonObject("reader_window", WindowSettings(), WindowSettings.serializer())
|
preferenceStore.getJsonObject(
|
||||||
}
|
"reader_window",
|
||||||
|
WindowSettings(),
|
||||||
|
WindowSettings.serializer(),
|
||||||
|
)
|
||||||
|
|
||||||
fun windowDecorations(): Preference<Boolean> {
|
fun windowDecorations(): Preference<Boolean> = preferenceStore.getBoolean("window_decorations", true)
|
||||||
return preferenceStore.getBoolean("window_decorations", true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class GetRecentUpdates
|
class GetRecentUpdates
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val updatesRepository: UpdatesRepository) {
|
constructor(
|
||||||
|
private val updatesRepository: UpdatesRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
pageNum: Int,
|
pageNum: Int,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class UpdateCategory
|
class UpdateCategory
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val updatesRepository: UpdatesRepository) {
|
constructor(
|
||||||
|
private val updatesRepository: UpdatesRepository,
|
||||||
|
) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
categoryId: Long,
|
categoryId: Long,
|
||||||
onError: suspend (Throwable) -> Unit = {},
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
|||||||
@@ -52,7 +52,10 @@ class UpdateChecker
|
|||||||
}.flowOn(Dispatchers.IO)
|
}.flowOn(Dispatchers.IO)
|
||||||
|
|
||||||
sealed class Update {
|
sealed class Update {
|
||||||
data class UpdateFound(val release: GithubRelease) : Update()
|
data class UpdateFound(
|
||||||
|
val release: GithubRelease,
|
||||||
|
) : Update()
|
||||||
|
|
||||||
object NoUpdatesFound : Update()
|
object NoUpdatesFound : Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class UpdateLibrary
|
class UpdateLibrary
|
||||||
@Inject
|
@Inject
|
||||||
constructor(private val updatesRepository: UpdatesRepository) {
|
constructor(
|
||||||
|
private val updatesRepository: UpdatesRepository,
|
||||||
|
) {
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
asFlow()
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
|
|||||||
@@ -157,10 +157,15 @@ class UpdatesPager
|
|||||||
@Immutable
|
@Immutable
|
||||||
sealed class Updates {
|
sealed class Updates {
|
||||||
@Immutable
|
@Immutable
|
||||||
data class Update(val manga: Manga, val chapter: Chapter) : Updates()
|
data class Update(
|
||||||
|
val manga: Manga,
|
||||||
|
val chapter: Chapter,
|
||||||
|
) : Updates()
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class Date(val date: String) : Updates() {
|
data class Date(
|
||||||
|
val date: String,
|
||||||
|
) : Updates() {
|
||||||
constructor(date: LocalDate) : this(date.toString())
|
constructor(date: LocalDate) : this(date.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ package ca.gosyer.jui.domain.updates.service
|
|||||||
import ca.gosyer.jui.core.prefs.Preference
|
import ca.gosyer.jui.core.prefs.Preference
|
||||||
import ca.gosyer.jui.core.prefs.PreferenceStore
|
import ca.gosyer.jui.core.prefs.PreferenceStore
|
||||||
|
|
||||||
class UpdatePreferences(private val preferenceStore: PreferenceStore) {
|
class UpdatePreferences(
|
||||||
fun enabled(): Preference<Boolean> {
|
private val preferenceStore: PreferenceStore,
|
||||||
return preferenceStore.getBoolean("enabled", true)
|
) {
|
||||||
}
|
fun enabled(): Preference<Boolean> = preferenceStore.getBoolean("enabled", true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,80 +10,74 @@ import ca.gosyer.jui.core.prefs.Preference
|
|||||||
import ca.gosyer.jui.core.prefs.PreferenceStore
|
import ca.gosyer.jui.core.prefs.PreferenceStore
|
||||||
import ca.gosyer.jui.domain.server.service.host.ServerHostPreference
|
import ca.gosyer.jui.domain.server.service.host.ServerHostPreference
|
||||||
|
|
||||||
class ServerHostPreferences(private val preferenceStore: PreferenceStore) {
|
class ServerHostPreferences(
|
||||||
fun host(): Preference<Boolean> {
|
private val preferenceStore: PreferenceStore,
|
||||||
return preferenceStore.getBoolean("host", true)
|
) {
|
||||||
}
|
fun host(): Preference<Boolean> = preferenceStore.getBoolean("host", true)
|
||||||
|
|
||||||
private val ip = ServerHostPreference.IP(preferenceStore)
|
private val ip = ServerHostPreference.IP(preferenceStore)
|
||||||
fun ip(): Preference<String> {
|
|
||||||
return ip.preference()
|
fun ip(): Preference<String> = ip.preference()
|
||||||
}
|
|
||||||
private val port = ServerHostPreference.Port(preferenceStore)
|
private val port = ServerHostPreference.Port(preferenceStore)
|
||||||
fun port(): Preference<Int> {
|
|
||||||
return port.preference()
|
fun port(): Preference<Int> = port.preference()
|
||||||
}
|
|
||||||
|
|
||||||
// Proxy
|
// Proxy
|
||||||
private val socksProxyEnabled = ServerHostPreference.SocksProxyEnabled(preferenceStore)
|
private val socksProxyEnabled = ServerHostPreference.SocksProxyEnabled(preferenceStore)
|
||||||
fun socksProxyEnabled(): Preference<Boolean> {
|
|
||||||
return socksProxyEnabled.preference()
|
fun socksProxyEnabled(): Preference<Boolean> = socksProxyEnabled.preference()
|
||||||
}
|
|
||||||
private val socksProxyHost = ServerHostPreference.SocksProxyHost(preferenceStore)
|
private val socksProxyHost = ServerHostPreference.SocksProxyHost(preferenceStore)
|
||||||
fun socksProxyHost(): Preference<String> {
|
|
||||||
return socksProxyHost.preference()
|
fun socksProxyHost(): Preference<String> = socksProxyHost.preference()
|
||||||
}
|
|
||||||
private val socksProxyPort = ServerHostPreference.SocksProxyPort(preferenceStore)
|
private val socksProxyPort = ServerHostPreference.SocksProxyPort(preferenceStore)
|
||||||
fun socksProxyPort(): Preference<Int> {
|
|
||||||
return socksProxyPort.preference()
|
fun socksProxyPort(): Preference<Int> = socksProxyPort.preference()
|
||||||
}
|
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
private val debugLogsEnabled = ServerHostPreference.DebugLogsEnabled(preferenceStore)
|
private val debugLogsEnabled = ServerHostPreference.DebugLogsEnabled(preferenceStore)
|
||||||
fun debugLogsEnabled(): Preference<Boolean> {
|
|
||||||
return debugLogsEnabled.preference()
|
fun debugLogsEnabled(): Preference<Boolean> = debugLogsEnabled.preference()
|
||||||
}
|
|
||||||
private val systemTrayEnabled = ServerHostPreference.SystemTrayEnabled(preferenceStore)
|
private val systemTrayEnabled = ServerHostPreference.SystemTrayEnabled(preferenceStore)
|
||||||
fun systemTrayEnabled(): Preference<Boolean> {
|
|
||||||
return systemTrayEnabled.preference()
|
fun systemTrayEnabled(): Preference<Boolean> = systemTrayEnabled.preference()
|
||||||
}
|
|
||||||
|
|
||||||
// Downloader
|
// Downloader
|
||||||
private val downloadPath = ServerHostPreference.DownloadPath(preferenceStore)
|
private val downloadPath = ServerHostPreference.DownloadPath(preferenceStore)
|
||||||
fun downloadPath(): Preference<String> {
|
|
||||||
return downloadPath.preference()
|
fun downloadPath(): Preference<String> = downloadPath.preference()
|
||||||
}
|
|
||||||
private val downloadAsCbz = ServerHostPreference.DownloadAsCbz(preferenceStore)
|
private val downloadAsCbz = ServerHostPreference.DownloadAsCbz(preferenceStore)
|
||||||
fun downloadAsCbz(): Preference<Boolean> {
|
|
||||||
return downloadAsCbz.preference()
|
fun downloadAsCbz(): Preference<Boolean> = downloadAsCbz.preference()
|
||||||
}
|
|
||||||
|
|
||||||
// WebUI
|
// WebUI
|
||||||
private val webUIEnabled = ServerHostPreference.WebUIEnabled(preferenceStore)
|
private val webUIEnabled = ServerHostPreference.WebUIEnabled(preferenceStore)
|
||||||
fun webUIEnabled(): Preference<Boolean> {
|
|
||||||
return webUIEnabled.preference()
|
fun webUIEnabled(): Preference<Boolean> = webUIEnabled.preference()
|
||||||
}
|
|
||||||
private val openInBrowserEnabled = ServerHostPreference.OpenInBrowserEnabled(preferenceStore)
|
private val openInBrowserEnabled = ServerHostPreference.OpenInBrowserEnabled(preferenceStore)
|
||||||
fun openInBrowserEnabled(): Preference<Boolean> {
|
|
||||||
return openInBrowserEnabled.preference()
|
fun openInBrowserEnabled(): Preference<Boolean> = openInBrowserEnabled.preference()
|
||||||
}
|
|
||||||
|
|
||||||
// Authentication
|
// Authentication
|
||||||
private val basicAuthEnabled = ServerHostPreference.BasicAuthEnabled(preferenceStore)
|
private val basicAuthEnabled = ServerHostPreference.BasicAuthEnabled(preferenceStore)
|
||||||
fun basicAuthEnabled(): Preference<Boolean> {
|
|
||||||
return basicAuthEnabled.preference()
|
|
||||||
}
|
|
||||||
private val basicAuthUsername = ServerHostPreference.BasicAuthUsername(preferenceStore)
|
|
||||||
fun basicAuthUsername(): Preference<String> {
|
|
||||||
return basicAuthUsername.preference()
|
|
||||||
}
|
|
||||||
private val basicAuthPassword = ServerHostPreference.BasicAuthPassword(preferenceStore)
|
|
||||||
fun basicAuthPassword(): Preference<String> {
|
|
||||||
return basicAuthPassword.preference()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun properties(): Array<String> {
|
fun basicAuthEnabled(): Preference<Boolean> = basicAuthEnabled.preference()
|
||||||
return listOf(
|
|
||||||
|
private val basicAuthUsername = ServerHostPreference.BasicAuthUsername(preferenceStore)
|
||||||
|
|
||||||
|
fun basicAuthUsername(): Preference<String> = basicAuthUsername.preference()
|
||||||
|
|
||||||
|
private val basicAuthPassword = ServerHostPreference.BasicAuthPassword(preferenceStore)
|
||||||
|
|
||||||
|
fun basicAuthPassword(): Preference<String> = basicAuthPassword.preference()
|
||||||
|
|
||||||
|
fun properties(): Array<String> =
|
||||||
|
listOf(
|
||||||
ip,
|
ip,
|
||||||
port,
|
port,
|
||||||
socksProxyEnabled,
|
socksProxyEnabled,
|
||||||
@@ -101,5 +95,4 @@ class ServerHostPreferences(private val preferenceStore: PreferenceStore) {
|
|||||||
).mapNotNull {
|
).mapNotNull {
|
||||||
it.getProperty()
|
it.getProperty()
|
||||||
}.toTypedArray()
|
}.toTypedArray()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ sealed class ServerHostPreference<T : Any> {
|
|||||||
|
|
||||||
protected abstract val defaultValue: T
|
protected abstract val defaultValue: T
|
||||||
protected abstract val serverValue: T
|
protected abstract val serverValue: T
|
||||||
|
|
||||||
private fun validate(value: T): Boolean {
|
private fun validate(value: T): Boolean {
|
||||||
return value != serverValue
|
return value != serverValue
|
||||||
}
|
}
|
||||||
@@ -30,6 +31,7 @@ sealed class ServerHostPreference<T : Any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract val preferenceStore: PreferenceStore
|
protected abstract val preferenceStore: PreferenceStore
|
||||||
|
|
||||||
abstract fun preference(): Preference<T>
|
abstract fun preference(): Preference<T>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -42,114 +44,144 @@ sealed class ServerHostPreference<T : Any> {
|
|||||||
override val defaultValue: String,
|
override val defaultValue: String,
|
||||||
override val serverValue: String = defaultValue,
|
override val serverValue: String = defaultValue,
|
||||||
) : ServerHostPreference<String>() {
|
) : ServerHostPreference<String>() {
|
||||||
override fun preference(): Preference<String> {
|
override fun preference(): Preference<String> = preferenceStore.getString(propertyName, defaultValue)
|
||||||
return preferenceStore.getString(propertyName, defaultValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class IntServerHostPreference(
|
sealed class IntServerHostPreference(
|
||||||
override val preferenceStore: PreferenceStore,
|
override val preferenceStore: PreferenceStore,
|
||||||
override val propertyName: String,
|
override val propertyName: String,
|
||||||
override val defaultValue: Int,
|
override val defaultValue: Int,
|
||||||
override val serverValue: Int = defaultValue,
|
override val serverValue: Int = defaultValue,
|
||||||
) : ServerHostPreference<Int>() {
|
) : ServerHostPreference<Int>() {
|
||||||
override fun preference(): Preference<Int> {
|
override fun preference(): Preference<Int> = preferenceStore.getInt(propertyName, defaultValue)
|
||||||
return preferenceStore.getInt(propertyName, defaultValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class BooleanServerHostPreference(
|
sealed class BooleanServerHostPreference(
|
||||||
override val preferenceStore: PreferenceStore,
|
override val preferenceStore: PreferenceStore,
|
||||||
override val propertyName: String,
|
override val propertyName: String,
|
||||||
override val defaultValue: Boolean,
|
override val defaultValue: Boolean,
|
||||||
override val serverValue: Boolean = defaultValue,
|
override val serverValue: Boolean = defaultValue,
|
||||||
) : ServerHostPreference<Boolean>() {
|
) : ServerHostPreference<Boolean>() {
|
||||||
override fun preference(): Preference<Boolean> {
|
override fun preference(): Preference<Boolean> = preferenceStore.getBoolean(propertyName, defaultValue)
|
||||||
return preferenceStore.getBoolean(propertyName, defaultValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class IP(preferenceStore: PreferenceStore) : StringServerHostPreference(
|
class IP(
|
||||||
preferenceStore,
|
preferenceStore: PreferenceStore,
|
||||||
"ip",
|
) : StringServerHostPreference(
|
||||||
"0.0.0.0",
|
preferenceStore,
|
||||||
)
|
"ip",
|
||||||
class Port(override val preferenceStore: PreferenceStore) : IntServerHostPreference(
|
"0.0.0.0",
|
||||||
preferenceStore,
|
)
|
||||||
"port",
|
|
||||||
4567,
|
class Port(
|
||||||
)
|
override val preferenceStore: PreferenceStore,
|
||||||
|
) : IntServerHostPreference(
|
||||||
|
preferenceStore,
|
||||||
|
"port",
|
||||||
|
4567,
|
||||||
|
)
|
||||||
|
|
||||||
// Proxy
|
// Proxy
|
||||||
class SocksProxyEnabled(preferenceStore: PreferenceStore) : BooleanServerHostPreference(
|
class SocksProxyEnabled(
|
||||||
preferenceStore,
|
preferenceStore: PreferenceStore,
|
||||||
"socksProxyEnabled",
|
) : BooleanServerHostPreference(
|
||||||
false,
|
preferenceStore,
|
||||||
)
|
"socksProxyEnabled",
|
||||||
class SocksProxyHost(preferenceStore: PreferenceStore) : StringServerHostPreference(
|
false,
|
||||||
preferenceStore,
|
)
|
||||||
"socksProxyHost",
|
|
||||||
"",
|
class SocksProxyHost(
|
||||||
)
|
preferenceStore: PreferenceStore,
|
||||||
class SocksProxyPort(override val preferenceStore: PreferenceStore) : IntServerHostPreference(
|
) : StringServerHostPreference(
|
||||||
preferenceStore,
|
preferenceStore,
|
||||||
"socksProxyPort",
|
"socksProxyHost",
|
||||||
0,
|
"",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class SocksProxyPort(
|
||||||
|
override val preferenceStore: PreferenceStore,
|
||||||
|
) : IntServerHostPreference(
|
||||||
|
preferenceStore,
|
||||||
|
"socksProxyPort",
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
class DebugLogsEnabled(preferenceStore: PreferenceStore) : BooleanServerHostPreference(
|
class DebugLogsEnabled(
|
||||||
preferenceStore,
|
preferenceStore: PreferenceStore,
|
||||||
"debugLogsEnabled",
|
) : BooleanServerHostPreference(
|
||||||
false,
|
preferenceStore,
|
||||||
)
|
"debugLogsEnabled",
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
|
||||||
class SystemTrayEnabled(preferenceStore: PreferenceStore) : BooleanServerHostPreference(
|
class SystemTrayEnabled(
|
||||||
preferenceStore,
|
preferenceStore: PreferenceStore,
|
||||||
"systemTrayEnabled",
|
) : BooleanServerHostPreference(
|
||||||
false,
|
preferenceStore,
|
||||||
true,
|
"systemTrayEnabled",
|
||||||
)
|
false,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
|
||||||
// Downloader
|
// Downloader
|
||||||
class DownloadPath(preferenceStore: PreferenceStore) : StringServerHostPreference(
|
class DownloadPath(
|
||||||
preferenceStore,
|
preferenceStore: PreferenceStore,
|
||||||
"downloadsPath",
|
) : StringServerHostPreference(
|
||||||
"",
|
preferenceStore,
|
||||||
)
|
"downloadsPath",
|
||||||
class DownloadAsCbz(preferenceStore: PreferenceStore) : BooleanServerHostPreference(
|
"",
|
||||||
preferenceStore,
|
)
|
||||||
"downloadAsCbz",
|
|
||||||
false,
|
class DownloadAsCbz(
|
||||||
)
|
preferenceStore: PreferenceStore,
|
||||||
|
) : BooleanServerHostPreference(
|
||||||
|
preferenceStore,
|
||||||
|
"downloadAsCbz",
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
|
||||||
// WebUI
|
// WebUI
|
||||||
class WebUIEnabled(preferenceStore: PreferenceStore) : BooleanServerHostPreference(
|
class WebUIEnabled(
|
||||||
preferenceStore,
|
preferenceStore: PreferenceStore,
|
||||||
"webUIEnabled",
|
) : BooleanServerHostPreference(
|
||||||
false,
|
preferenceStore,
|
||||||
true,
|
"webUIEnabled",
|
||||||
)
|
false,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
|
||||||
class OpenInBrowserEnabled(preferenceStore: PreferenceStore) : BooleanServerHostPreference(
|
class OpenInBrowserEnabled(
|
||||||
preferenceStore,
|
preferenceStore: PreferenceStore,
|
||||||
"initialOpenInBrowserEnabled",
|
) : BooleanServerHostPreference(
|
||||||
false,
|
preferenceStore,
|
||||||
true,
|
"initialOpenInBrowserEnabled",
|
||||||
)
|
false,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
|
||||||
// Authentication
|
// Authentication
|
||||||
class BasicAuthEnabled(preferenceStore: PreferenceStore) : BooleanServerHostPreference(
|
class BasicAuthEnabled(
|
||||||
preferenceStore,
|
preferenceStore: PreferenceStore,
|
||||||
"basicAuthEnabled",
|
) : BooleanServerHostPreference(
|
||||||
false,
|
preferenceStore,
|
||||||
)
|
"basicAuthEnabled",
|
||||||
class BasicAuthUsername(preferenceStore: PreferenceStore) : StringServerHostPreference(
|
false,
|
||||||
preferenceStore,
|
)
|
||||||
"basicAuthUsername",
|
|
||||||
"",
|
class BasicAuthUsername(
|
||||||
)
|
preferenceStore: PreferenceStore,
|
||||||
class BasicAuthPassword(preferenceStore: PreferenceStore) : StringServerHostPreference(
|
) : StringServerHostPreference(
|
||||||
preferenceStore,
|
preferenceStore,
|
||||||
"basicAuthPassword",
|
"basicAuthUsername",
|
||||||
"",
|
"",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class BasicAuthPassword(
|
||||||
|
preferenceStore: PreferenceStore,
|
||||||
|
) : StringServerHostPreference(
|
||||||
|
preferenceStore,
|
||||||
|
"basicAuthPassword",
|
||||||
|
"",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ import me.tatarka.inject.annotations.Provides
|
|||||||
abstract class AppComponent(
|
abstract class AppComponent(
|
||||||
@get:Provides
|
@get:Provides
|
||||||
val context: ContextWrapper,
|
val context: ContextWrapper,
|
||||||
) : ViewModelComponent, DataComponent, DomainComponent, UiComponent {
|
) : ViewModelComponent,
|
||||||
|
DataComponent,
|
||||||
|
DomainComponent,
|
||||||
|
UiComponent {
|
||||||
abstract val appMigrations: AppMigrations
|
abstract val appMigrations: AppMigrations
|
||||||
|
|
||||||
@get:AppScope
|
@get:AppScope
|
||||||
|
|||||||
@@ -4,11 +4,9 @@ package ca.gosyer.jui.ios
|
|||||||
|
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.sizeIn
|
import androidx.compose.foundation.layout.sizeIn
|
||||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material.Card
|
import androidx.compose.material.Card
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
@@ -33,34 +31,10 @@ import ca.gosyer.jui.uicore.vm.ContextWrapper
|
|||||||
import ca.gosyer.jui.uicore.vm.Length
|
import ca.gosyer.jui.uicore.vm.Length
|
||||||
import kotlinx.cinterop.BetaInteropApi
|
import kotlinx.cinterop.BetaInteropApi
|
||||||
import kotlinx.cinterop.ExperimentalForeignApi
|
import kotlinx.cinterop.ExperimentalForeignApi
|
||||||
import kotlinx.cinterop.autoreleasepool
|
|
||||||
import kotlinx.cinterop.cstr
|
|
||||||
import kotlinx.cinterop.memScoped
|
|
||||||
import kotlinx.cinterop.toCValues
|
|
||||||
import kotlinx.cinterop.useContents
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import org.lighthousegames.logging.FixedLogLevel
|
|
||||||
import org.lighthousegames.logging.KmLog
|
|
||||||
import org.lighthousegames.logging.KmLogging
|
|
||||||
import org.lighthousegames.logging.LogFactory
|
|
||||||
import org.lighthousegames.logging.LogLevel
|
|
||||||
import org.lighthousegames.logging.LogLevelController
|
|
||||||
import org.lighthousegames.logging.Logger
|
|
||||||
import org.lighthousegames.logging.TagProvider
|
|
||||||
import platform.Foundation.NSStringFromClass
|
|
||||||
import platform.Foundation.NSThread
|
|
||||||
import platform.UIKit.UIApplication
|
|
||||||
import platform.UIKit.UIApplicationDelegateProtocol
|
|
||||||
import platform.UIKit.UIApplicationDelegateProtocolMeta
|
|
||||||
import platform.UIKit.UIApplicationMain
|
|
||||||
import platform.UIKit.UIResponder
|
|
||||||
import platform.UIKit.UIResponderMeta
|
|
||||||
import platform.UIKit.UIScreen
|
|
||||||
import platform.UIKit.UIViewController
|
import platform.UIKit.UIViewController
|
||||||
import platform.UIKit.UIWindow
|
|
||||||
import platform.UIKit.safeAreaInsets
|
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import okio.Source
|
import okio.Source
|
||||||
import okio.source
|
import okio.source
|
||||||
|
|
||||||
actual class FileChooser(private val resultLauncher: ManagedActivityResultLauncher<String, Uri?>) {
|
actual class FileChooser(
|
||||||
|
private val resultLauncher: ManagedActivityResultLauncher<String, Uri?>,
|
||||||
|
) {
|
||||||
actual fun launch(extension: String) {
|
actual fun launch(extension: String) {
|
||||||
resultLauncher.launch(MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension))
|
resultLauncher.launch(MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,5 +10,6 @@ import ca.gosyer.jui.uicore.vm.ContextWrapper
|
|||||||
import com.seiko.imageloader.component.decoder.BitmapFactoryDecoder
|
import com.seiko.imageloader.component.decoder.BitmapFactoryDecoder
|
||||||
import com.seiko.imageloader.component.decoder.Decoder
|
import com.seiko.imageloader.component.decoder.Decoder
|
||||||
|
|
||||||
actual class BitmapDecoderFactory actual constructor(contextWrapper: ContextWrapper) :
|
actual class BitmapDecoderFactory actual constructor(
|
||||||
Decoder.Factory by BitmapFactoryDecoder.Factory(contextWrapper, Int.MAX_VALUE)
|
contextWrapper: ContextWrapper,
|
||||||
|
) : Decoder.Factory by BitmapFactoryDecoder.Factory(contextWrapper, Int.MAX_VALUE)
|
||||||
|
|||||||
@@ -15,11 +15,10 @@ internal actual fun Color.toHsv(): FloatArray {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
internal actual fun hexStringToColor(hex: String): Color? {
|
internal actual fun hexStringToColor(hex: String): Color? =
|
||||||
return try {
|
try {
|
||||||
val color = android.graphics.Color.parseColor(hex)
|
val color = android.graphics.Color.parseColor(hex)
|
||||||
Color(color)
|
Color(color)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -107,22 +107,20 @@ internal class SavedStateHandlesProvider(
|
|||||||
/**
|
/**
|
||||||
* Restore the state associated with a particular SavedStateHandle, identified by its [key]
|
* Restore the state associated with a particular SavedStateHandle, identified by its [key]
|
||||||
*/
|
*/
|
||||||
fun consumeRestoredStateForKey(key: String): Bundle? {
|
fun consumeRestoredStateForKey(key: String): Bundle? =
|
||||||
return savedStateRegistry::class.java
|
savedStateRegistry::class.java
|
||||||
.methods
|
.methods
|
||||||
.find { it.name == "consumeRestoredStateForKey" }
|
.find { it.name == "consumeRestoredStateForKey" }
|
||||||
?.invoke(savedStateRegistry, key) as? Bundle
|
?.invoke(savedStateRegistry, key) as? Bundle
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T : ScreenModel> CreationExtras.addScreenModelKey(
|
inline fun <reified T : ScreenModel> CreationExtras.addScreenModelKey(
|
||||||
screen: Screen,
|
screen: Screen,
|
||||||
tag: String?,
|
tag: String?,
|
||||||
): CreationExtras {
|
): CreationExtras =
|
||||||
return MutableCreationExtras(this).apply {
|
MutableCreationExtras(this).apply {
|
||||||
set(
|
set(
|
||||||
VIEW_MODEL_KEY,
|
VIEW_MODEL_KEY,
|
||||||
"${screen.key}:${T::class.qualifiedName}:${tag ?: "default"}",
|
"${screen.key}:${T::class.qualifiedName}:${tag ?: "default"}",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,7 +15,5 @@ actual object ThemeScrollbarStyle {
|
|||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
@Composable
|
@Composable
|
||||||
actual fun getScrollbarStyle(): ScrollbarStyle {
|
actual fun getScrollbarStyle(): ScrollbarStyle = defaultScrollbarStyle
|
||||||
return defaultScrollbarStyle
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ import androidx.compose.runtime.remember
|
|||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.Navigator
|
import cafe.adriel.voyager.navigator.Navigator
|
||||||
|
|
||||||
actual class CategoriesLauncher(private val navigator: Navigator?) {
|
actual class CategoriesLauncher(
|
||||||
|
private val navigator: Navigator?,
|
||||||
|
) {
|
||||||
actual fun open() {
|
actual fun open() {
|
||||||
navigator?.push(CategoriesScreen())
|
navigator?.push(CategoriesScreen())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ package ca.gosyer.jui.ui.main.about.components
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import ca.gosyer.jui.presentation.build.BuildKonfig
|
import ca.gosyer.jui.presentation.build.BuildKonfig
|
||||||
|
|
||||||
actual fun getDebugInfo(): String {
|
actual fun getDebugInfo(): String =
|
||||||
return """
|
"""
|
||||||
App version: ${BuildKonfig.VERSION} (${ if (BuildKonfig.DEBUG) "Debug" else "Standard"}, ${BuildKonfig.MIGRATION_CODE})
|
App version: ${BuildKonfig.VERSION} (${ if (BuildKonfig.DEBUG) "Debug" else "Standard"}, ${BuildKonfig.MIGRATION_CODE})
|
||||||
Preview build: r${BuildKonfig.PREVIEW_BUILD}
|
Preview build: r${BuildKonfig.PREVIEW_BUILD}
|
||||||
Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT})
|
Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT})
|
||||||
@@ -20,5 +20,4 @@ actual fun getDebugInfo(): String {
|
|||||||
Device name: ${Build.DEVICE}
|
Device name: ${Build.DEVICE}
|
||||||
Device model: ${Build.MODEL}
|
Device model: ${Build.MODEL}
|
||||||
Device product name: ${Build.PRODUCT}
|
Device product name: ${Build.PRODUCT}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
|
||||||
actual class ReaderLauncher(private val context: Context) {
|
actual class ReaderLauncher(
|
||||||
|
private val context: Context,
|
||||||
|
) {
|
||||||
actual fun launch(
|
actual fun launch(
|
||||||
chapterIndex: Int,
|
chapterIndex: Int,
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import ca.gosyer.jui.uicore.vm.ViewModel
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
actual fun getServerHostItems(viewModel: @Composable () -> SettingsServerHostViewModel): LazyListScope.() -> Unit {
|
actual fun getServerHostItems(viewModel: @Composable () -> SettingsServerHostViewModel): LazyListScope.() -> Unit = {}
|
||||||
return {}
|
|
||||||
}
|
|
||||||
|
|
||||||
actual class SettingsServerHostViewModel
|
actual class SettingsServerHostViewModel
|
||||||
@Inject
|
@Inject
|
||||||
constructor(contextWrapper: ContextWrapper) : ViewModel(contextWrapper)
|
constructor(
|
||||||
|
contextWrapper: ContextWrapper,
|
||||||
|
) : ViewModel(contextWrapper)
|
||||||
|
|||||||
@@ -13,6 +13,4 @@ import io.ktor.client.statement.HttpResponse
|
|||||||
import io.ktor.client.statement.bodyAsChannel
|
import io.ktor.client.statement.bodyAsChannel
|
||||||
import io.ktor.utils.io.jvm.javaio.toInputStream
|
import io.ktor.utils.io.jvm.javaio.toInputStream
|
||||||
|
|
||||||
actual suspend fun HttpResponse.toImageBitmap(): ImageBitmap {
|
actual suspend fun HttpResponse.toImageBitmap(): ImageBitmap = BitmapFactory.decodeStream(bodyAsChannel().toInputStream()).asImageBitmap()
|
||||||
return BitmapFactory.decodeStream(bodyAsChannel().toInputStream()).asImageBitmap()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -91,9 +91,7 @@ data class ChapterDownloadItem(
|
|||||||
_downloadState.value = ChapterDownloadState.NotDownloaded
|
_downloadState.value = ChapterDownloadState.NotDownloaded
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isSelected(selectedItems: List<Long>): Boolean {
|
fun isSelected(selectedItems: List<Long>): Boolean = (chapter.id in selectedItems).also { _isSelected.value = it }
|
||||||
return (chapter.id in selectedItems).also { _isSelected.value = it }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class ChapterDownloadState {
|
enum class ChapterDownloadState {
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ fun getMaterialDialogProperties(
|
|||||||
title: String = BuildKonfig.NAME,
|
title: String = BuildKonfig.NAME,
|
||||||
icon: Painter = MR.images.icon.toPainter(),
|
icon: Painter = MR.images.icon.toPainter(),
|
||||||
resizable: Boolean = true,
|
resizable: Boolean = true,
|
||||||
): MaterialDialogProperties {
|
): MaterialDialogProperties =
|
||||||
return MaterialDialogProperties(
|
MaterialDialogProperties(
|
||||||
dismissOnBackPress = dismissOnBackPress,
|
dismissOnBackPress = dismissOnBackPress,
|
||||||
dismissOnClickOutside = dismissOnClickOutside,
|
dismissOnClickOutside = dismissOnClickOutside,
|
||||||
securePolicy = securePolicy,
|
securePolicy = securePolicy,
|
||||||
@@ -41,4 +41,3 @@ fun getMaterialDialogProperties(
|
|||||||
windowIcon = icon,
|
windowIcon = icon,
|
||||||
windowIsResizable = resizable,
|
windowIsResizable = resizable,
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,4 +9,6 @@ package ca.gosyer.jui.ui.base.image
|
|||||||
import ca.gosyer.jui.uicore.vm.ContextWrapper
|
import ca.gosyer.jui.uicore.vm.ContextWrapper
|
||||||
import com.seiko.imageloader.component.decoder.Decoder
|
import com.seiko.imageloader.component.decoder.Decoder
|
||||||
|
|
||||||
expect class BitmapDecoderFactory constructor(contextWrapper: ContextWrapper) : Decoder.Factory
|
expect class BitmapDecoderFactory constructor(
|
||||||
|
contextWrapper: ContextWrapper,
|
||||||
|
) : Decoder.Factory
|
||||||
|
|||||||
@@ -10,11 +10,15 @@ import androidx.compose.runtime.Immutable
|
|||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
class StableHolder<T>(val item: T) {
|
class StableHolder<T>(
|
||||||
|
val item: T,
|
||||||
|
) {
|
||||||
operator fun component1(): T = item
|
operator fun component1(): T = item
|
||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
class ImmutableHolder<T>(val item: T) {
|
class ImmutableHolder<T>(
|
||||||
|
val item: T,
|
||||||
|
) {
|
||||||
operator fun component1(): T = item
|
operator fun component1(): T = item
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ enum class OverflowMode {
|
|||||||
@Composable
|
@Composable
|
||||||
fun ActionMenu(
|
fun ActionMenu(
|
||||||
items: ImmutableList<Action>,
|
items: ImmutableList<Action>,
|
||||||
numIcons: Int = 3, // includes overflow menu icon; may be overridden by NEVER_OVERFLOW
|
// includes overflow menu icon; may be overridden by NEVER_OVERFLOW
|
||||||
|
numIcons: Int = 3,
|
||||||
menuVisible: MutableState<Boolean> = remember { mutableStateOf(false) },
|
menuVisible: MutableState<Boolean> = remember { mutableStateOf(false) },
|
||||||
iconItem: @Composable (onClick: () -> Unit, name: String, icon: ImageVector, enabled: Boolean) -> Unit,
|
iconItem: @Composable (onClick: () -> Unit, name: String, icon: ImageVector, enabled: Boolean) -> Unit,
|
||||||
) {
|
) {
|
||||||
@@ -99,7 +100,9 @@ fun ActionMenu(
|
|||||||
} else {
|
} else {
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = when (item) {
|
onClick = when (item) {
|
||||||
is ActionGroup -> { { openGroup = item } }
|
is ActionGroup -> {
|
||||||
|
{ openGroup = item }
|
||||||
|
}
|
||||||
is ActionItem -> item.doAction
|
is ActionItem -> item.doAction
|
||||||
},
|
},
|
||||||
enabled = item.enabled,
|
enabled = item.enabled,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class DisplayController(
|
|||||||
fun openSideMenu() {
|
fun openSideMenu() {
|
||||||
_sideMenuVisible.value = true
|
_sideMenuVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun closeSideMenu() {
|
fun closeSideMenu() {
|
||||||
_sideMenuVisible.value = false
|
_sideMenuVisible.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,8 +88,10 @@ fun Toolbar(
|
|||||||
closeIcon: ImageVector = ToolbarDefault,
|
closeIcon: ImageVector = ToolbarDefault,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
actions: @Composable () -> ImmutableList<Action> = { remember { persistentListOf() } },
|
actions: @Composable () -> ImmutableList<Action> = { remember { persistentListOf() } },
|
||||||
backgroundColor: Color = MaterialTheme.colors.surface, // CustomColors.current.bars,
|
// CustomColors.current.bars,
|
||||||
contentColor: Color = contentColorFor(backgroundColor), // CustomColors.current.onBars,
|
backgroundColor: Color = MaterialTheme.colors.surface,
|
||||||
|
// CustomColors.current.onBars,
|
||||||
|
contentColor: Color = contentColorFor(backgroundColor),
|
||||||
elevation: Dp = Dp.Hairline,
|
elevation: Dp = Dp.Hairline,
|
||||||
searchText: String? = null,
|
searchText: String? = null,
|
||||||
search: ((String) -> Unit)? = null,
|
search: ((String) -> Unit)? = null,
|
||||||
@@ -216,6 +218,7 @@ private fun ThinToolbar(
|
|||||||
searchSubmit: (() -> Unit)?,
|
searchSubmit: (() -> Unit)?,
|
||||||
) {
|
) {
|
||||||
var searchMode by remember { mutableStateOf(!searchText.isNullOrEmpty()) }
|
var searchMode by remember { mutableStateOf(!searchText.isNullOrEmpty()) }
|
||||||
|
|
||||||
fun closeSearch() {
|
fun closeSearch() {
|
||||||
search?.invoke("")
|
search?.invoke("")
|
||||||
searchSubmit?.invoke()
|
searchSubmit?.invoke()
|
||||||
|
|||||||
@@ -421,16 +421,12 @@ private fun satValToCoordinates(
|
|||||||
saturation: Float,
|
saturation: Float,
|
||||||
value: Float,
|
value: Float,
|
||||||
size: IntSize,
|
size: IntSize,
|
||||||
): Offset {
|
): Offset = Offset(saturation * size.width, ((1f - value) * size.height))
|
||||||
return Offset(saturation * size.width, ((1f - value) * size.height))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hueToCoordinate(
|
private fun hueToCoordinate(
|
||||||
hue: Float,
|
hue: Float,
|
||||||
size: IntSize,
|
size: IntSize,
|
||||||
): Float {
|
): Float = size.height - (hue * size.height / 360f)
|
||||||
return size.height - (hue * size.height / 360f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Color space conversions
|
// Color space conversions
|
||||||
|
|
||||||
@@ -439,36 +435,51 @@ fun hsvToColor(
|
|||||||
hue: Float,
|
hue: Float,
|
||||||
saturation: Float,
|
saturation: Float,
|
||||||
value: Float,
|
value: Float,
|
||||||
): Color {
|
): Color = Color.hsv(hue, saturation.coerceIn(0F, 1F), value.coerceIn(0F, 1F))
|
||||||
return Color.hsv(hue, saturation.coerceIn(0F, 1F), value.coerceIn(0F, 1F))
|
|
||||||
}
|
|
||||||
|
|
||||||
internal expect fun Color.toHsv(): FloatArray
|
internal expect fun Color.toHsv(): FloatArray
|
||||||
|
|
||||||
private fun hueToColor(hue: Float): Color {
|
private fun hueToColor(hue: Float): Color = hsvToColor(hue, 1f, 1f)
|
||||||
return hsvToColor(hue, 1f, 1f)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal expect fun hexStringToColor(hex: String): Color?
|
internal expect fun hexStringToColor(hex: String): Color?
|
||||||
|
|
||||||
private val presetColors = listOf(
|
private val presetColors = listOf(
|
||||||
Color(0xFFF44336), // RED 500
|
// RED 500
|
||||||
Color(0xFFE91E63), // PINK 500
|
Color(0xFFF44336),
|
||||||
Color(0xFFFF2C93), // LIGHT PINK 500
|
// PINK 500
|
||||||
Color(0xFF9C27B0), // PURPLE 500
|
Color(0xFFE91E63),
|
||||||
Color(0xFF673AB7), // DEEP PURPLE 500
|
// LIGHT PINK 500
|
||||||
Color(0xFF3F51B5), // INDIGO 500
|
Color(0xFFFF2C93),
|
||||||
Color(0xFF2196F3), // BLUE 500
|
// PURPLE 500
|
||||||
Color(0xFF03A9F4), // LIGHT BLUE 500
|
Color(0xFF9C27B0),
|
||||||
Color(0xFF00BCD4), // CYAN 500
|
// DEEP PURPLE 500
|
||||||
Color(0xFF009688), // TEAL 500
|
Color(0xFF673AB7),
|
||||||
Color(0xFF4CAF50), // GREEN 500
|
// INDIGO 500
|
||||||
Color(0xFF8BC34A), // LIGHT GREEN 500
|
Color(0xFF3F51B5),
|
||||||
Color(0xFFCDDC39), // LIME 500
|
// BLUE 500
|
||||||
Color(0xFFFFEB3B), // YELLOW 500
|
Color(0xFF2196F3),
|
||||||
Color(0xFFFFC107), // AMBER 500
|
// LIGHT BLUE 500
|
||||||
Color(0xFFFF9800), // ORANGE 500
|
Color(0xFF03A9F4),
|
||||||
Color(0xFF795548), // BROWN 500
|
// CYAN 500
|
||||||
Color(0xFF607D8B), // BLUE GREY 500
|
Color(0xFF00BCD4),
|
||||||
Color(0xFF9E9E9E), // GREY 500
|
// TEAL 500
|
||||||
|
Color(0xFF009688),
|
||||||
|
// GREEN 500
|
||||||
|
Color(0xFF4CAF50),
|
||||||
|
// LIGHT GREEN 500
|
||||||
|
Color(0xFF8BC34A),
|
||||||
|
// LIME 500
|
||||||
|
Color(0xFFCDDC39),
|
||||||
|
// YELLOW 500
|
||||||
|
Color(0xFFFFEB3B),
|
||||||
|
// AMBER 500
|
||||||
|
Color(0xFFFFC107),
|
||||||
|
// ORANGE 500
|
||||||
|
Color(0xFFFF9800),
|
||||||
|
// BROWN 500
|
||||||
|
Color(0xFF795548),
|
||||||
|
// BLUE GREY 500
|
||||||
|
Color(0xFF607D8B),
|
||||||
|
// GREY 500
|
||||||
|
Color(0xFF9E9E9E),
|
||||||
).toImmutableList()
|
).toImmutableList()
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user