mirror of
https://github.com/Suwayomi/TachideskJUI.git
synced 2025-12-12 15:52:03 +01:00
Automatic Lint
This commit is contained in:
@@ -21,7 +21,6 @@ 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()
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ abstract class AppComponent(
|
|||||||
@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
|
||||||
@@ -39,7 +38,8 @@ abstract class AppComponent(
|
|||||||
private var appComponentInstance: AppComponent? = null
|
private var appComponentInstance: AppComponent? = null
|
||||||
|
|
||||||
@Suppress("UNRESOLVED_REFERENCE", "EXPRESSION_EXPECTED_PACKAGE_FOUND")
|
@Suppress("UNRESOLVED_REFERENCE", "EXPRESSION_EXPECTED_PACKAGE_FOUND")
|
||||||
fun getInstance(context: Context) = appComponentInstance ?: create(context)
|
fun getInstance(context: Context) =
|
||||||
|
appComponentInstance ?: create(context)
|
||||||
.also { appComponentInstance = it }
|
.also { appComponentInstance = it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,12 @@ import ca.gosyer.jui.domain.migration.service.MigrationPreferences
|
|||||||
import ca.gosyer.jui.uicore.vm.ContextWrapper
|
import ca.gosyer.jui.uicore.vm.ContextWrapper
|
||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
|
||||||
class AppMigrations @Inject constructor(
|
class AppMigrations
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val migrationPreferences: MigrationPreferences,
|
private val migrationPreferences: MigrationPreferences,
|
||||||
private val contextWrapper: ContextWrapper,
|
private val contextWrapper: ContextWrapper,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun runMigrations(): Boolean {
|
fun runMigrations(): Boolean {
|
||||||
val oldVersion = migrationPreferences.appVersion().get()
|
val oldVersion = migrationPreferences.appVersion().get()
|
||||||
if (oldVersion < BuildConfig.VERSION_CODE) {
|
if (oldVersion < BuildConfig.VERSION_CODE) {
|
||||||
@@ -31,4 +32,4 @@ class AppMigrations @Inject constructor(
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,12 @@ import ca.gosyer.jui.ui.base.theme.AppTheme
|
|||||||
import ca.gosyer.jui.ui.reader.ReaderMenu
|
import ca.gosyer.jui.ui.reader.ReaderMenu
|
||||||
|
|
||||||
class ReaderActivity : AppCompatActivity() {
|
class ReaderActivity : AppCompatActivity() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newIntent(context: Context, mangaId: Long, chapterIndex: Int): Intent {
|
fun newIntent(
|
||||||
|
context: Context,
|
||||||
|
mangaId: Long,
|
||||||
|
chapterIndex: Int,
|
||||||
|
): Intent {
|
||||||
return Intent(context, ReaderActivity::class.java).apply {
|
return Intent(context, ReaderActivity::class.java).apply {
|
||||||
putExtra("manga", mangaId)
|
putExtra("manga", mangaId)
|
||||||
putExtra("chapter", chapterIndex)
|
putExtra("chapter", chapterIndex)
|
||||||
|
|||||||
@@ -55,11 +55,13 @@ import org.lighthousegames.logging.logging
|
|||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
class AndroidDownloadService : Service() {
|
class AndroidDownloadService : Service() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private var instance: AndroidDownloadService? = null
|
private var instance: AndroidDownloadService? = null
|
||||||
|
|
||||||
fun start(context: Context, actions: Actions) {
|
fun start(
|
||||||
|
context: Context,
|
||||||
|
actions: Actions,
|
||||||
|
) {
|
||||||
if (!isRunning() && actions != Actions.STOP) {
|
if (!isRunning() && actions != Actions.STOP) {
|
||||||
val intent = Intent(context, AndroidDownloadService::class.java).apply {
|
val intent = Intent(context, AndroidDownloadService::class.java).apply {
|
||||||
action = actions.name
|
action = actions.name
|
||||||
@@ -106,7 +108,11 @@ class AndroidDownloadService : Service() {
|
|||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(
|
||||||
|
intent: Intent?,
|
||||||
|
flags: Int,
|
||||||
|
startId: Int,
|
||||||
|
): Int {
|
||||||
instance = this
|
instance = this
|
||||||
ioScope.coroutineContext.job.cancelChildren()
|
ioScope.coroutineContext.job.cancelChildren()
|
||||||
|
|
||||||
|
|||||||
@@ -55,11 +55,13 @@ import kotlinx.serialization.json.Json
|
|||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class AndroidLibraryService : Service() {
|
class AndroidLibraryService : Service() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private var instance: AndroidLibraryService? = null
|
private var instance: AndroidLibraryService? = null
|
||||||
|
|
||||||
fun start(context: Context, actions: Actions) {
|
fun start(
|
||||||
|
context: Context,
|
||||||
|
actions: Actions,
|
||||||
|
) {
|
||||||
if (!isRunning() && actions != Actions.STOP) {
|
if (!isRunning() && actions != Actions.STOP) {
|
||||||
val intent = Intent(context, AndroidLibraryService::class.java).apply {
|
val intent = Intent(context, AndroidLibraryService::class.java).apply {
|
||||||
action = actions.name
|
action = actions.name
|
||||||
@@ -106,7 +108,11 @@ class AndroidLibraryService : Service() {
|
|||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(
|
||||||
|
intent: Intent?,
|
||||||
|
flags: Int,
|
||||||
|
startId: Int,
|
||||||
|
): Int {
|
||||||
instance = this
|
instance = this
|
||||||
ioScope.coroutineContext.job.cancelChildren()
|
ioScope.coroutineContext.job.cancelChildren()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import ca.gosyer.jui.i18n.MR
|
|||||||
import dev.icerock.moko.resources.desc.desc
|
import dev.icerock.moko.resources.desc.desc
|
||||||
|
|
||||||
object Notifications {
|
object Notifications {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification channel and ids used by the downloader.
|
* Notification channel and ids used by the downloader.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -37,7 +37,10 @@ fun Context.acquireWakeLock(tag: String): PowerManager.WakeLock {
|
|||||||
* @param block the function that will execute inside the builder.
|
* @param block the function that will execute inside the builder.
|
||||||
* @return a notification to be displayed or updated.
|
* @return a notification to be displayed or updated.
|
||||||
*/
|
*/
|
||||||
fun Context.notificationBuilder(channelId: String, block: (NotificationCompat.Builder.() -> Unit)? = null): NotificationCompat.Builder {
|
fun Context.notificationBuilder(
|
||||||
|
channelId: String,
|
||||||
|
block: (NotificationCompat.Builder.() -> Unit)? = null,
|
||||||
|
): NotificationCompat.Builder {
|
||||||
val builder = NotificationCompat.Builder(this, channelId)
|
val builder = NotificationCompat.Builder(this, channelId)
|
||||||
// .setColor(getColor(R.color.accent_blue))
|
// .setColor(getColor(R.color.accent_blue))
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
@@ -53,7 +56,10 @@ fun Context.notificationBuilder(channelId: String, block: (NotificationCompat.Bu
|
|||||||
* @param block the function that will execute inside the builder.
|
* @param block the function that will execute inside the builder.
|
||||||
* @return a notification to be displayed or updated.
|
* @return a notification to be displayed or updated.
|
||||||
*/
|
*/
|
||||||
fun Context.notification(channelId: String, block: (NotificationCompat.Builder.() -> Unit)?): Notification {
|
fun Context.notification(
|
||||||
|
channelId: String,
|
||||||
|
block: (NotificationCompat.Builder.() -> Unit)?,
|
||||||
|
): Notification {
|
||||||
val builder = notificationBuilder(channelId, block)
|
val builder = notificationBuilder(channelId, block)
|
||||||
return builder.build()
|
return builder.build()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import android.content.Context
|
|||||||
import com.russhwolf.settings.SharedPreferencesSettings
|
import com.russhwolf.settings.SharedPreferencesSettings
|
||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
|
||||||
actual class PreferenceStoreFactory @Inject constructor(private val context: Context) {
|
actual class PreferenceStoreFactory
|
||||||
|
@Inject
|
||||||
|
constructor(private val context: Context) {
|
||||||
actual fun create(vararg names: String): PreferenceStore {
|
actual fun create(vararg names: String): PreferenceStore {
|
||||||
return StandardPreferenceStore(
|
return StandardPreferenceStore(
|
||||||
SharedPreferencesSettings(
|
SharedPreferencesSettings(
|
||||||
@@ -21,4 +23,4 @@ actual class PreferenceStoreFactory @Inject constructor(private val context: Con
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,17 +48,11 @@ fun CoroutineScope.launchIO(
|
|||||||
block: suspend CoroutineScope.() -> Unit,
|
block: suspend CoroutineScope.() -> Unit,
|
||||||
) = launch(Dispatchers.IO, start, block)
|
) = launch(Dispatchers.IO, start, block)
|
||||||
|
|
||||||
suspend fun <T> withDefaultContext(
|
suspend fun <T> withDefaultContext(block: suspend CoroutineScope.() -> T): T = withContext(Dispatchers.Default, block)
|
||||||
block: suspend CoroutineScope.() -> T,
|
|
||||||
): T = withContext(Dispatchers.Default, block)
|
|
||||||
|
|
||||||
suspend fun <T> withUIContext(
|
suspend fun <T> withUIContext(block: suspend CoroutineScope.() -> T): T = withContext(Dispatchers.Main, block)
|
||||||
block: suspend CoroutineScope.() -> T,
|
|
||||||
): T = withContext(Dispatchers.Main, block)
|
|
||||||
|
|
||||||
suspend fun <T> withIOContext(
|
suspend fun <T> withIOContext(block: suspend CoroutineScope.() -> T): T = withContext(Dispatchers.IO, block)
|
||||||
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 }
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ internal open class ProcessChannel<T>(
|
|||||||
internal val inChannel: Channel<T>,
|
internal val inChannel: Channel<T>,
|
||||||
internal val outChannel: Channel<T>,
|
internal val outChannel: Channel<T>,
|
||||||
) : Channel<T> {
|
) : Channel<T> {
|
||||||
|
|
||||||
@DelicateCoroutinesApi
|
@DelicateCoroutinesApi
|
||||||
override val isClosedForReceive: Boolean
|
override val isClosedForReceive: Boolean
|
||||||
get() = outChannel.isClosedForReceive
|
get() = outChannel.isClosedForReceive
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ package ca.gosyer.jui.core.lang
|
|||||||
* Replaces the given string to have at most [count] characters using [replacement] at its end.
|
* Replaces the given string to have at most [count] characters using [replacement] at its end.
|
||||||
* If [replacement] is longer than [count] an exception will be thrown when `length > count`.
|
* If [replacement] is longer than [count] an exception will be thrown when `length > count`.
|
||||||
*/
|
*/
|
||||||
fun String.chop(count: Int, replacement: String = "…"): String {
|
fun String.chop(
|
||||||
|
count: Int,
|
||||||
|
replacement: String = "…",
|
||||||
|
): String {
|
||||||
return if (length > count) {
|
return if (length > count) {
|
||||||
take(count - replacement.length) + replacement
|
take(count - replacement.length) + replacement
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -16,46 +16,63 @@ import kotlinx.serialization.modules.SerializersModule
|
|||||||
class LazyPreferenceStore(
|
class LazyPreferenceStore(
|
||||||
private val lazyStore: Lazy<PreferenceStore>,
|
private val lazyStore: Lazy<PreferenceStore>,
|
||||||
) : PreferenceStore {
|
) : PreferenceStore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an [String] preference for this [key].
|
* Returns an [String] preference for this [key].
|
||||||
*/
|
*/
|
||||||
override fun getString(key: String, defaultValue: String): Preference<String> {
|
override fun getString(
|
||||||
|
key: String,
|
||||||
|
defaultValue: String,
|
||||||
|
): Preference<String> {
|
||||||
return 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].
|
||||||
*/
|
*/
|
||||||
override fun getLong(key: String, defaultValue: Long): Preference<Long> {
|
override fun getLong(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Long,
|
||||||
|
): Preference<Long> {
|
||||||
return 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].
|
||||||
*/
|
*/
|
||||||
override fun getInt(key: String, defaultValue: Int): Preference<Int> {
|
override fun getInt(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Int,
|
||||||
|
): Preference<Int> {
|
||||||
return 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].
|
||||||
*/
|
*/
|
||||||
override fun getFloat(key: String, defaultValue: Float): Preference<Float> {
|
override fun getFloat(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Float,
|
||||||
|
): Preference<Float> {
|
||||||
return 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].
|
||||||
*/
|
*/
|
||||||
override fun getBoolean(key: String, defaultValue: Boolean): Preference<Boolean> {
|
override fun getBoolean(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Boolean,
|
||||||
|
): Preference<Boolean> {
|
||||||
return 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].
|
||||||
*/
|
*/
|
||||||
override fun getStringSet(key: String, defaultValue: Set<String>): Preference<Set<String>> {
|
override fun getStringSet(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Set<String>,
|
||||||
|
): Preference<Set<String>> {
|
||||||
return lazyStore.value.getStringSet(key, defaultValue)
|
return lazyStore.value.getStringSet(key, defaultValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import kotlinx.coroutines.flow.onStart
|
|||||||
* this interface must be provided through a [PreferenceStore].
|
* this interface must be provided through a [PreferenceStore].
|
||||||
*/
|
*/
|
||||||
interface Preference<T> {
|
interface Preference<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the key of this preference.
|
* Returns the key of this preference.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,36 +15,53 @@ import kotlinx.serialization.modules.SerializersModule
|
|||||||
* persist these preferences on disk.
|
* persist these preferences on disk.
|
||||||
*/
|
*/
|
||||||
interface PreferenceStore {
|
interface PreferenceStore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an [String] preference for this [key].
|
* Returns an [String] preference for this [key].
|
||||||
*/
|
*/
|
||||||
fun getString(key: String, defaultValue: String = ""): Preference<String>
|
fun getString(
|
||||||
|
key: String,
|
||||||
|
defaultValue: String = "",
|
||||||
|
): Preference<String>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Long] preference for this [key].
|
* Returns a [Long] preference for this [key].
|
||||||
*/
|
*/
|
||||||
fun getLong(key: String, defaultValue: Long = 0): Preference<Long>
|
fun getLong(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Long = 0,
|
||||||
|
): Preference<Long>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an [Int] preference for this [key].
|
* Returns an [Int] preference for this [key].
|
||||||
*/
|
*/
|
||||||
fun getInt(key: String, defaultValue: Int = 0): Preference<Int>
|
fun getInt(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Int = 0,
|
||||||
|
): Preference<Int>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Float] preference for this [key].
|
* Returns a [Float] preference for this [key].
|
||||||
*/
|
*/
|
||||||
fun getFloat(key: String, defaultValue: Float = 0f): Preference<Float>
|
fun getFloat(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Float = 0f,
|
||||||
|
): Preference<Float>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Boolean] preference for this [key].
|
* Returns a [Boolean] preference for this [key].
|
||||||
*/
|
*/
|
||||||
fun getBoolean(key: String, defaultValue: Boolean = false): Preference<Boolean>
|
fun getBoolean(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Boolean = false,
|
||||||
|
): Preference<Boolean>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Set<String>] preference for this [key].
|
* Returns a [Set<String>] preference for this [key].
|
||||||
*/
|
*/
|
||||||
fun getStringSet(key: String, defaultValue: Set<String> = emptySet()): Preference<Set<String>>
|
fun getStringSet(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Set<String> = emptySet(),
|
||||||
|
): Preference<Set<String>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
|||||||
@@ -17,81 +17,150 @@ import kotlinx.serialization.modules.EmptySerializersModule
|
|||||||
import kotlinx.serialization.modules.SerializersModule
|
import kotlinx.serialization.modules.SerializersModule
|
||||||
|
|
||||||
interface Adapter<T> {
|
interface Adapter<T> {
|
||||||
fun get(key: String, preferences: ObservableSettings): T
|
fun get(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
): T
|
||||||
|
|
||||||
fun set(key: String, value: T, editor: ObservableSettings)
|
fun set(
|
||||||
|
key: String,
|
||||||
|
value: T,
|
||||||
|
editor: ObservableSettings,
|
||||||
|
)
|
||||||
|
|
||||||
fun isSet(keys: Set<String>, key: String): Boolean = key in keys
|
fun isSet(
|
||||||
|
keys: Set<String>,
|
||||||
|
key: String,
|
||||||
|
): Boolean = key in keys
|
||||||
|
|
||||||
fun addListener(key: String, preferences: ObservableSettings, callback: () -> Unit): SettingsListener
|
fun addListener(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
callback: () -> Unit,
|
||||||
|
): SettingsListener
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object StringAdapter : Adapter<String> {
|
internal object StringAdapter : Adapter<String> {
|
||||||
override fun get(key: String, preferences: ObservableSettings): String {
|
override fun get(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
): String {
|
||||||
return preferences.getString(key, "") // Not called unless key is present.
|
return preferences.getString(key, "") // Not called unless key is present.
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: String, value: String, editor: ObservableSettings) {
|
override fun set(
|
||||||
|
key: String,
|
||||||
|
value: String,
|
||||||
|
editor: ObservableSettings,
|
||||||
|
) {
|
||||||
editor.putString(key, value)
|
editor.putString(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addListener(key: String, preferences: ObservableSettings, callback: () -> Unit): SettingsListener {
|
override fun addListener(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
callback: () -> Unit,
|
||||||
|
): SettingsListener {
|
||||||
return preferences.addStringOrNullListener(key) { callback() }
|
return preferences.addStringOrNullListener(key) { callback() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object LongAdapter : Adapter<Long> {
|
internal object LongAdapter : Adapter<Long> {
|
||||||
override fun get(key: String, preferences: ObservableSettings): Long {
|
override fun get(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
): Long {
|
||||||
return preferences.getLong(key, 0)
|
return preferences.getLong(key, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: String, value: Long, editor: ObservableSettings) {
|
override fun set(
|
||||||
|
key: String,
|
||||||
|
value: Long,
|
||||||
|
editor: ObservableSettings,
|
||||||
|
) {
|
||||||
editor.putLong(key, value)
|
editor.putLong(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addListener(key: String, preferences: ObservableSettings, callback: () -> Unit): SettingsListener {
|
override fun addListener(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
callback: () -> Unit,
|
||||||
|
): SettingsListener {
|
||||||
return preferences.addLongOrNullListener(key) { callback() }
|
return preferences.addLongOrNullListener(key) { callback() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object IntAdapter : Adapter<Int> {
|
internal object IntAdapter : Adapter<Int> {
|
||||||
override fun get(key: String, preferences: ObservableSettings): Int {
|
override fun get(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
): Int {
|
||||||
return preferences.getInt(key, 0)
|
return preferences.getInt(key, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: String, value: Int, editor: ObservableSettings) {
|
override fun set(
|
||||||
|
key: String,
|
||||||
|
value: Int,
|
||||||
|
editor: ObservableSettings,
|
||||||
|
) {
|
||||||
editor.putInt(key, value)
|
editor.putInt(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addListener(key: String, preferences: ObservableSettings, callback: () -> Unit): SettingsListener {
|
override fun addListener(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
callback: () -> Unit,
|
||||||
|
): SettingsListener {
|
||||||
return preferences.addIntOrNullListener(key) { callback() }
|
return preferences.addIntOrNullListener(key) { callback() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object FloatAdapter : Adapter<Float> {
|
internal object FloatAdapter : Adapter<Float> {
|
||||||
override fun get(key: String, preferences: ObservableSettings): Float {
|
override fun get(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
): Float {
|
||||||
return preferences.getFloat(key, 0f)
|
return preferences.getFloat(key, 0f)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: String, value: Float, editor: ObservableSettings) {
|
override fun set(
|
||||||
|
key: String,
|
||||||
|
value: Float,
|
||||||
|
editor: ObservableSettings,
|
||||||
|
) {
|
||||||
editor.putFloat(key, value)
|
editor.putFloat(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addListener(key: String, preferences: ObservableSettings, callback: () -> Unit): SettingsListener {
|
override fun addListener(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
callback: () -> Unit,
|
||||||
|
): SettingsListener {
|
||||||
return preferences.addFloatOrNullListener(key) { callback() }
|
return preferences.addFloatOrNullListener(key) { callback() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object BooleanAdapter : Adapter<Boolean> {
|
internal object BooleanAdapter : Adapter<Boolean> {
|
||||||
override fun get(key: String, preferences: ObservableSettings): Boolean {
|
override fun get(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
): Boolean {
|
||||||
return preferences.getBoolean(key, false)
|
return preferences.getBoolean(key, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: String, value: Boolean, editor: ObservableSettings) {
|
override fun set(
|
||||||
|
key: String,
|
||||||
|
value: Boolean,
|
||||||
|
editor: ObservableSettings,
|
||||||
|
) {
|
||||||
editor.putBoolean(key, value)
|
editor.putBoolean(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addListener(key: String, preferences: ObservableSettings, callback: () -> Unit): SettingsListener {
|
override fun addListener(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
callback: () -> Unit,
|
||||||
|
): SettingsListener {
|
||||||
return preferences.addBooleanOrNullListener(key) { callback() }
|
return preferences.addBooleanOrNullListener(key) { callback() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,18 +168,28 @@ internal object BooleanAdapter : Adapter<Boolean> {
|
|||||||
internal object StringSetAdapter : Adapter<Set<String>> {
|
internal object StringSetAdapter : Adapter<Set<String>> {
|
||||||
private val serializer = SetSerializer(String.serializer())
|
private val serializer = SetSerializer(String.serializer())
|
||||||
|
|
||||||
override fun get(key: String, preferences: ObservableSettings): Set<String> {
|
override fun get(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
): Set<String> {
|
||||||
return preferences.decodeValue(serializer, key, emptySet()) // Not called unless key is present.
|
return preferences.decodeValue(serializer, key, emptySet()) // Not called unless key is present.
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: String, value: Set<String>, editor: ObservableSettings) {
|
override fun set(
|
||||||
|
key: String,
|
||||||
|
value: Set<String>,
|
||||||
|
editor: ObservableSettings,
|
||||||
|
) {
|
||||||
editor.encodeValue(serializer, key, value)
|
editor.encodeValue(serializer, key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encoding a string set makes a list of keys and a size key, such as key.size and key.0-size
|
* Encoding a string set makes a list of keys and a size key, such as key.size and key.0-size
|
||||||
*/
|
*/
|
||||||
override fun isSet(keys: Set<String>, key: String): Boolean {
|
override fun isSet(
|
||||||
|
keys: Set<String>,
|
||||||
|
key: String,
|
||||||
|
): Boolean {
|
||||||
return keys.contains("$key.size")
|
return keys.contains("$key.size")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +197,11 @@ internal object StringSetAdapter : Adapter<Set<String>> {
|
|||||||
* Watching the regular key doesn't produce updates for a string set for some reason
|
* Watching the regular key doesn't produce updates for a string set for some reason
|
||||||
* TODO make better, doesn't produce updates when you add something and remove something
|
* TODO make better, doesn't produce updates when you add something and remove something
|
||||||
*/
|
*/
|
||||||
override fun addListener(key: String, preferences: ObservableSettings, callback: () -> Unit): SettingsListener {
|
override fun addListener(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
callback: () -> Unit,
|
||||||
|
): SettingsListener {
|
||||||
return preferences.addIntOrNullListener("$key.size") { callback() }
|
return preferences.addIntOrNullListener("$key.size") { callback() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,16 +210,26 @@ internal class ObjectAdapter<T>(
|
|||||||
private val serializer: (T) -> String,
|
private val serializer: (T) -> String,
|
||||||
private val deserializer: (String) -> T,
|
private val deserializer: (String) -> T,
|
||||||
) : Adapter<T> {
|
) : Adapter<T> {
|
||||||
|
override fun get(
|
||||||
override fun get(key: String, preferences: ObservableSettings): T {
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
): T {
|
||||||
return deserializer(preferences.getString(key, "")) // Not called unless key is present.
|
return deserializer(preferences.getString(key, "")) // Not called unless key is present.
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: String, value: T, editor: ObservableSettings) {
|
override fun set(
|
||||||
|
key: String,
|
||||||
|
value: T,
|
||||||
|
editor: ObservableSettings,
|
||||||
|
) {
|
||||||
editor.putString(key, serializer(value))
|
editor.putString(key, serializer(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addListener(key: String, preferences: ObservableSettings, callback: () -> Unit): SettingsListener {
|
override fun addListener(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
callback: () -> Unit,
|
||||||
|
): SettingsListener {
|
||||||
return preferences.addStringOrNullListener(key) { callback() }
|
return preferences.addStringOrNullListener(key) { callback() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,12 +239,18 @@ internal class JsonObjectAdapter<T>(
|
|||||||
private val serializer: KSerializer<T>,
|
private val serializer: KSerializer<T>,
|
||||||
private val serializersModule: SerializersModule = EmptySerializersModule(),
|
private val serializersModule: SerializersModule = EmptySerializersModule(),
|
||||||
) : Adapter<T> {
|
) : Adapter<T> {
|
||||||
|
override fun get(
|
||||||
override fun get(key: String, preferences: ObservableSettings): T {
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
): T {
|
||||||
return preferences.decodeValue(serializer, key, defaultValue, serializersModule) // Not called unless key is present.
|
return preferences.decodeValue(serializer, key, defaultValue, serializersModule) // Not called unless key is present.
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: String, value: T, editor: ObservableSettings) {
|
override fun set(
|
||||||
|
key: String,
|
||||||
|
value: T,
|
||||||
|
editor: ObservableSettings,
|
||||||
|
) {
|
||||||
editor.encodeValue(serializer, key, value, serializersModule)
|
editor.encodeValue(serializer, key, value, serializersModule)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,14 +258,21 @@ internal class JsonObjectAdapter<T>(
|
|||||||
* Encoding a structure makes keys start with the [key] and adds extensions for values,
|
* Encoding a structure makes keys start with the [key] and adds extensions for values,
|
||||||
* for a pair it would be like [key].first [key].second.
|
* for a pair it would be like [key].first [key].second.
|
||||||
*/
|
*/
|
||||||
override fun isSet(keys: Set<String>, key: String): Boolean {
|
override fun isSet(
|
||||||
|
keys: Set<String>,
|
||||||
|
key: String,
|
||||||
|
): Boolean {
|
||||||
return keys.any { it.startsWith(key) }
|
return keys.any { it.startsWith(key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Todo doesn't work
|
* Todo doesn't work
|
||||||
*/
|
*/
|
||||||
override fun addListener(key: String, preferences: ObservableSettings, callback: () -> Unit): SettingsListener {
|
override fun addListener(
|
||||||
|
key: String,
|
||||||
|
preferences: ObservableSettings,
|
||||||
|
callback: () -> Unit,
|
||||||
|
): SettingsListener {
|
||||||
@Suppress("DEPRECATION") // Because we don't care about the type, and it crashes with any other listener
|
@Suppress("DEPRECATION") // Because we don't care about the type, and it crashes with any other listener
|
||||||
return preferences.addListener(key) { callback() }
|
return preferences.addListener(key) { callback() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ internal class StandardPreference<T>(
|
|||||||
private val defaultValue: T,
|
private val defaultValue: T,
|
||||||
private val adapter: Adapter<T>,
|
private val adapter: Adapter<T>,
|
||||||
) : Preference<T> {
|
) : Preference<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the key of this preference.
|
* Returns the key of this preference.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -11,46 +11,63 @@ 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].
|
||||||
*/
|
*/
|
||||||
override fun getString(key: String, defaultValue: String): Preference<String> {
|
override fun getString(
|
||||||
|
key: String,
|
||||||
|
defaultValue: String,
|
||||||
|
): Preference<String> {
|
||||||
return StandardPreference(preferences, key, defaultValue, StringAdapter)
|
return StandardPreference(preferences, key, defaultValue, StringAdapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Long] preference for this [key].
|
* Returns a [Long] preference for this [key].
|
||||||
*/
|
*/
|
||||||
override fun getLong(key: String, defaultValue: Long): Preference<Long> {
|
override fun getLong(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Long,
|
||||||
|
): Preference<Long> {
|
||||||
return StandardPreference(preferences, key, defaultValue, LongAdapter)
|
return StandardPreference(preferences, key, defaultValue, LongAdapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an [Int] preference for this [key].
|
* Returns an [Int] preference for this [key].
|
||||||
*/
|
*/
|
||||||
override fun getInt(key: String, defaultValue: Int): Preference<Int> {
|
override fun getInt(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Int,
|
||||||
|
): Preference<Int> {
|
||||||
return StandardPreference(preferences, key, defaultValue, IntAdapter)
|
return StandardPreference(preferences, key, defaultValue, IntAdapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Float] preference for this [key].
|
* Returns a [Float] preference for this [key].
|
||||||
*/
|
*/
|
||||||
override fun getFloat(key: String, defaultValue: Float): Preference<Float> {
|
override fun getFloat(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Float,
|
||||||
|
): Preference<Float> {
|
||||||
return StandardPreference(preferences, key, defaultValue, FloatAdapter)
|
return StandardPreference(preferences, key, defaultValue, FloatAdapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Boolean] preference for this [key].
|
* Returns a [Boolean] preference for this [key].
|
||||||
*/
|
*/
|
||||||
override fun getBoolean(key: String, defaultValue: Boolean): Preference<Boolean> {
|
override fun getBoolean(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Boolean,
|
||||||
|
): Preference<Boolean> {
|
||||||
return StandardPreference(preferences, key, defaultValue, BooleanAdapter)
|
return StandardPreference(preferences, key, defaultValue, BooleanAdapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Set<String>] preference for this [key].
|
* Returns a [Set<String>] preference for this [key].
|
||||||
*/
|
*/
|
||||||
override fun getStringSet(key: String, defaultValue: Set<String>): Preference<Set<String>> {
|
override fun getStringSet(
|
||||||
|
key: String,
|
||||||
|
defaultValue: Set<String>,
|
||||||
|
): Preference<Set<String>> {
|
||||||
return StandardPreference(preferences, key, defaultValue, StringSetAdapter)
|
return StandardPreference(preferences, key, defaultValue, StringSetAdapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ package ca.gosyer.jui.core.util
|
|||||||
/**
|
/**
|
||||||
* Returns a new list that replaces the item at the given [position] with [newItem].
|
* Returns a new list that replaces the item at the given [position] with [newItem].
|
||||||
*/
|
*/
|
||||||
fun <T> List<T>.replace(position: Int, newItem: T): List<T> {
|
fun <T> List<T>.replace(
|
||||||
|
position: Int,
|
||||||
|
newItem: T,
|
||||||
|
): List<T> {
|
||||||
val newList = toMutableList()
|
val newList = toMutableList()
|
||||||
newList[position] = newItem
|
newList[position] = newItem
|
||||||
return newList
|
return newList
|
||||||
@@ -19,7 +22,10 @@ fun <T> List<T>.replace(position: Int, newItem: T): List<T> {
|
|||||||
* Returns a new list that replaces the first occurrence that matches the given [predicate] with
|
* Returns a new list that replaces the first occurrence that matches the given [predicate] with
|
||||||
* [newItem]. If no item matches the predicate, the same list is returned (and unmodified).
|
* [newItem]. If no item matches the predicate, the same list is returned (and unmodified).
|
||||||
*/
|
*/
|
||||||
inline fun <T> List<T>.replaceFirst(predicate: (T) -> Boolean, newItem: T): List<T> {
|
inline fun <T> List<T>.replaceFirst(
|
||||||
|
predicate: (T) -> Boolean,
|
||||||
|
newItem: T,
|
||||||
|
): List<T> {
|
||||||
forEachIndexed { index, element ->
|
forEachIndexed { index, element ->
|
||||||
if (predicate(element)) {
|
if (predicate(element)) {
|
||||||
return replace(index, newItem)
|
return replace(index, newItem)
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ package ca.gosyer.jui.core.util
|
|||||||
import io.ktor.utils.io.core.toByteArray
|
import io.ktor.utils.io.core.toByteArray
|
||||||
|
|
||||||
object ImageUtil {
|
object ImageUtil {
|
||||||
|
|
||||||
private val jpgMagic = charByteArrayOf(0xFF, 0xD8, 0xFF)
|
private val jpgMagic = charByteArrayOf(0xFF, 0xD8, 0xFF)
|
||||||
private val pngMagic = charByteArrayOf(0x89, 0x50, 0x4E, 0x47)
|
private val pngMagic = charByteArrayOf(0x89, 0x50, 0x4E, 0x47)
|
||||||
private val gifMagic = "GIF8".toByteArray()
|
private val gifMagic = "GIF8".toByteArray()
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import com.russhwolf.settings.PreferencesSettings
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import java.util.prefs.Preferences
|
import java.util.prefs.Preferences
|
||||||
|
|
||||||
actual class PreferenceStoreFactory @Inject constructor() {
|
actual class PreferenceStoreFactory
|
||||||
|
@Inject
|
||||||
|
constructor() {
|
||||||
private val rootNode: Preferences = Preferences.userRoot()
|
private val rootNode: Preferences = Preferences.userRoot()
|
||||||
.node("ca/gosyer/tachideskjui")
|
.node("ca/gosyer/tachideskjui")
|
||||||
|
|
||||||
@@ -21,4 +23,4 @@ actual class PreferenceStoreFactory @Inject constructor() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,16 @@ fun Locale.toPlatform(): PlatformLocale = PlatformLocale(toLanguageTag())
|
|||||||
* First Locale: en_IN
|
* First Locale: en_IN
|
||||||
* Language: English
|
* Language: English
|
||||||
*/
|
*/
|
||||||
actual fun Locale.getDisplayLanguage(displayLocale: Locale): String = toPlatform()
|
actual fun Locale.getDisplayLanguage(displayLocale: Locale): String =
|
||||||
|
toPlatform()
|
||||||
.localizedStringForLanguageCode(displayLocale.toLanguageTag())!!
|
.localizedStringForLanguageCode(displayLocale.toLanguageTag())!!
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* First Locale: en_US
|
* First Locale: en_US
|
||||||
* Language: English (United States)
|
* Language: English (United States)
|
||||||
*/
|
*/
|
||||||
actual fun Locale.getDisplayName(displayLocale: Locale): String = toPlatform()
|
actual fun Locale.getDisplayName(displayLocale: Locale): String =
|
||||||
|
toPlatform()
|
||||||
.localizedStringForLocaleIdentifier(displayLocale.toLanguageTag())
|
.localizedStringForLocaleIdentifier(displayLocale.toLanguageTag())
|
||||||
|
|
||||||
actual val Locale.displayName: String get() = getDisplayLanguage(this)
|
actual val Locale.displayName: String get() = getDisplayLanguage(this)
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import com.russhwolf.settings.NSUserDefaultsSettings
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import platform.Foundation.NSUserDefaults
|
import platform.Foundation.NSUserDefaults
|
||||||
|
|
||||||
actual class PreferenceStoreFactory @Inject constructor() {
|
actual class PreferenceStoreFactory
|
||||||
|
@Inject
|
||||||
|
constructor() {
|
||||||
actual fun create(vararg names: String): PreferenceStore {
|
actual fun create(vararg names: String): PreferenceStore {
|
||||||
return StandardPreferenceStore(
|
return StandardPreferenceStore(
|
||||||
NSUserDefaultsSettings(
|
NSUserDefaultsSettings(
|
||||||
@@ -18,4 +20,4 @@ actual class PreferenceStoreFactory @Inject constructor() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ import java.util.Locale as PlatformLocale
|
|||||||
|
|
||||||
fun Locale.toPlatform(): PlatformLocale = PlatformLocale.forLanguageTag(toLanguageTag())
|
fun Locale.toPlatform(): PlatformLocale = PlatformLocale.forLanguageTag(toLanguageTag())
|
||||||
|
|
||||||
actual fun Locale.getDisplayLanguage(displayLocale: Locale): String = toPlatform()
|
actual fun Locale.getDisplayLanguage(displayLocale: Locale): String =
|
||||||
|
toPlatform()
|
||||||
.getDisplayLanguage(displayLocale.toPlatform())
|
.getDisplayLanguage(displayLocale.toPlatform())
|
||||||
|
|
||||||
actual fun Locale.getDisplayName(displayLocale: Locale): String = toPlatform()
|
actual fun Locale.getDisplayName(displayLocale: Locale): String =
|
||||||
|
toPlatform()
|
||||||
.getDisplayName(displayLocale.toPlatform())
|
.getDisplayName(displayLocale.toPlatform())
|
||||||
|
|
||||||
actual val Locale.displayName: String get() = toPlatform().displayName
|
actual val Locale.displayName: String get() = toPlatform().displayName
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ import de.jensklingenberg.ktorfit.Ktorfit
|
|||||||
import me.tatarka.inject.annotations.Provides
|
import me.tatarka.inject.annotations.Provides
|
||||||
|
|
||||||
interface DataComponent {
|
interface DataComponent {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
fun ktorfit(http: Http, serverPreferences: ServerPreferences) = Ktorfit
|
fun ktorfit(
|
||||||
|
http: Http,
|
||||||
|
serverPreferences: ServerPreferences,
|
||||||
|
) = Ktorfit
|
||||||
.Builder()
|
.Builder()
|
||||||
.httpClient(http)
|
.httpClient(http)
|
||||||
.converterFactories(FlowConverterFactory())
|
.converterFactories(FlowConverterFactory())
|
||||||
|
|||||||
@@ -18,19 +18,17 @@ import kotlinx.coroutines.flow.flow
|
|||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
|
|
||||||
class FlowConverterFactory : Converter.Factory {
|
class FlowConverterFactory : Converter.Factory {
|
||||||
|
|
||||||
private class FlowResponseConverter(
|
private class FlowResponseConverter(
|
||||||
val typeData: TypeData,
|
val typeData: TypeData,
|
||||||
val ktorfit: Ktorfit
|
val ktorfit: Ktorfit,
|
||||||
) : Converter.ResponseConverter<HttpResponse, Flow<Any?>> {
|
) : Converter.ResponseConverter<HttpResponse, Flow<Any?>> {
|
||||||
|
|
||||||
override fun convert(getResponse: suspend () -> HttpResponse): Flow<Any?> {
|
override fun convert(getResponse: suspend () -> HttpResponse): Flow<Any?> {
|
||||||
return flow {
|
return flow {
|
||||||
val response = getResponse()
|
val response = getResponse()
|
||||||
|
|
||||||
val convertedBody = ktorfit.nextSuspendResponseConverter(
|
val convertedBody = ktorfit.nextSuspendResponseConverter(
|
||||||
null,
|
null,
|
||||||
typeData.typeArgs.first()
|
typeData.typeArgs.first(),
|
||||||
)?.convert(response)
|
)?.convert(response)
|
||||||
?: response.body(typeData.typeArgs.first().typeInfo)
|
?: response.body(typeData.typeArgs.first().typeInfo)
|
||||||
emit(convertedBody)
|
emit(convertedBody)
|
||||||
@@ -40,7 +38,7 @@ class FlowConverterFactory : Converter.Factory {
|
|||||||
|
|
||||||
override fun responseConverter(
|
override fun responseConverter(
|
||||||
typeData: TypeData,
|
typeData: TypeData,
|
||||||
ktorfit: Ktorfit
|
ktorfit: Ktorfit,
|
||||||
): Converter.ResponseConverter<HttpResponse, *>? {
|
): Converter.ResponseConverter<HttpResponse, *>? {
|
||||||
if (typeData.typeInfo.type == Flow::class) {
|
if (typeData.typeInfo.type == Flow::class) {
|
||||||
return FlowResponseConverter(typeData, ktorfit)
|
return FlowResponseConverter(typeData, ktorfit)
|
||||||
@@ -50,9 +48,8 @@ class FlowConverterFactory : Converter.Factory {
|
|||||||
|
|
||||||
override fun suspendResponseConverter(
|
override fun suspendResponseConverter(
|
||||||
typeData: TypeData,
|
typeData: TypeData,
|
||||||
ktorfit: Ktorfit
|
ktorfit: Ktorfit,
|
||||||
): Converter.SuspendResponseConverter<HttpResponse, *>? {
|
): Converter.SuspendResponseConverter<HttpResponse, *>? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import platform.Foundation.NSDateFormatter
|
|||||||
import platform.Foundation.NSDateFormatterNoStyle
|
import platform.Foundation.NSDateFormatterNoStyle
|
||||||
import platform.Foundation.NSDateFormatterShortStyle
|
import platform.Foundation.NSDateFormatterShortStyle
|
||||||
|
|
||||||
actual class DateHandler @Inject constructor() {
|
actual class DateHandler
|
||||||
|
@Inject
|
||||||
|
constructor() {
|
||||||
actual val formatOptions by lazy {
|
actual val formatOptions by lazy {
|
||||||
listOf(
|
listOf(
|
||||||
"",
|
"",
|
||||||
@@ -25,7 +27,8 @@ actual class DateHandler @Inject constructor() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun getDateFormat(format: String): (Instant) -> String = when (format) {
|
actual fun getDateFormat(format: String): (Instant) -> String =
|
||||||
|
when (format) {
|
||||||
"" -> NSDateFormatter()
|
"" -> NSDateFormatter()
|
||||||
.apply {
|
.apply {
|
||||||
setDateStyle(NSDateFormatterShortStyle)
|
setDateStyle(NSDateFormatterShortStyle)
|
||||||
@@ -55,4 +58,4 @@ actual class DateHandler @Inject constructor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import java.time.ZoneId
|
|||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import java.time.format.FormatStyle
|
import java.time.format.FormatStyle
|
||||||
|
|
||||||
actual class DateHandler @Inject constructor() {
|
actual class DateHandler
|
||||||
|
@Inject
|
||||||
|
constructor() {
|
||||||
actual val formatOptions by lazy {
|
actual val formatOptions by lazy {
|
||||||
listOf(
|
listOf(
|
||||||
"",
|
"",
|
||||||
@@ -25,7 +27,8 @@ actual class DateHandler @Inject constructor() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun getDateFormat(format: String): (Instant) -> String = when (format) {
|
actual fun getDateFormat(format: String): (Instant) -> String =
|
||||||
|
when (format) {
|
||||||
"" -> DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
|
"" -> DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
|
||||||
.withLocale(Locale.current.toPlatform())
|
.withLocale(Locale.current.toPlatform())
|
||||||
.withZone(ZoneId.systemDefault())
|
.withZone(ZoneId.systemDefault())
|
||||||
@@ -48,4 +51,4 @@ actual class DateHandler @Inject constructor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ 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
|
||||||
@@ -35,7 +34,8 @@ abstract class AppComponent(
|
|||||||
companion object {
|
companion object {
|
||||||
private var appComponentInstance: AppComponent? = null
|
private var appComponentInstance: AppComponent? = null
|
||||||
|
|
||||||
fun getInstance(context: ContextWrapper) = appComponentInstance ?: create(context)
|
fun getInstance(context: ContextWrapper) =
|
||||||
|
appComponentInstance ?: create(context)
|
||||||
.also { appComponentInstance = it }
|
.also { appComponentInstance = it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,12 @@ import ca.gosyer.jui.domain.migration.service.MigrationPreferences
|
|||||||
import ca.gosyer.jui.uicore.vm.ContextWrapper
|
import ca.gosyer.jui.uicore.vm.ContextWrapper
|
||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
|
||||||
class AppMigrations @Inject constructor(
|
class AppMigrations
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val migrationPreferences: MigrationPreferences,
|
private val migrationPreferences: MigrationPreferences,
|
||||||
private val contextWrapper: ContextWrapper,
|
private val contextWrapper: ContextWrapper,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun runMigrations(): Boolean {
|
fun runMigrations(): Boolean {
|
||||||
val oldVersion = migrationPreferences.appVersion().get()
|
val oldVersion = migrationPreferences.appVersion().get()
|
||||||
if (oldVersion < BuildConfig.MIGRATION_CODE) {
|
if (oldVersion < BuildConfig.MIGRATION_CODE) {
|
||||||
@@ -29,4 +30,4 @@ class AppMigrations @Inject constructor(
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,32 +12,46 @@ import org.slf4j.Logger
|
|||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
class Slf4jLogFactory : LogFactory {
|
class Slf4jLogFactory : LogFactory {
|
||||||
|
override fun createKmLog(
|
||||||
override fun createKmLog(tag: String, className: String): KmLog {
|
tag: String,
|
||||||
|
className: String,
|
||||||
|
): KmLog {
|
||||||
return 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(tag: String, msg: String) {
|
override fun verbose(
|
||||||
|
tag: String,
|
||||||
|
msg: String,
|
||||||
|
) {
|
||||||
super.verbose(tag, msg)
|
super.verbose(tag, msg)
|
||||||
logger.trace(msg)
|
logger.trace(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun debug(tag: String, msg: String) {
|
override fun debug(
|
||||||
|
tag: String,
|
||||||
|
msg: String,
|
||||||
|
) {
|
||||||
super.debug(tag, msg)
|
super.debug(tag, msg)
|
||||||
logger.debug(msg)
|
logger.debug(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun info(tag: String, msg: String) {
|
override fun info(
|
||||||
|
tag: String,
|
||||||
|
msg: String,
|
||||||
|
) {
|
||||||
super.info(tag, msg)
|
super.info(tag, msg)
|
||||||
logger.info(msg)
|
logger.info(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun warn(tag: String, msg: String, t: Throwable?) {
|
override fun warn(
|
||||||
|
tag: String,
|
||||||
|
msg: String,
|
||||||
|
t: Throwable?,
|
||||||
|
) {
|
||||||
super.warn(tag, msg, t)
|
super.warn(tag, msg, t)
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
logger.warn(msg, t)
|
logger.warn(msg, t)
|
||||||
@@ -46,7 +60,11 @@ class Slf4jLog(tag: String) : KmLog(tag) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun error(tag: String, msg: String, t: Throwable?) {
|
override fun error(
|
||||||
|
tag: String,
|
||||||
|
msg: String,
|
||||||
|
t: Throwable?,
|
||||||
|
) {
|
||||||
super.error(tag, msg, t)
|
super.error(tag, msg, t)
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
logger.error(msg, t)
|
logger.error(msg, t)
|
||||||
|
|||||||
@@ -253,7 +253,10 @@ suspend fun main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ToastOverlay(modifier: Modifier, context: ContextWrapper) {
|
fun ToastOverlay(
|
||||||
|
modifier: Modifier,
|
||||||
|
context: ContextWrapper,
|
||||||
|
) {
|
||||||
var toast by remember { mutableStateOf<Pair<String, Length>?>(null) }
|
var toast by remember { mutableStateOf<Pair<String, Length>?>(null) }
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
context.toasts
|
context.toasts
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ import kotlinx.coroutines.launch
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class ServerListeners @Inject constructor() {
|
class ServerListeners
|
||||||
|
@Inject
|
||||||
|
constructor() {
|
||||||
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
||||||
|
|
||||||
private fun <T> Flow<T>.startWith(value: T) = onStart { emit(value) }
|
private fun <T> Flow<T>.startWith(value: T) = onStart { emit(value) }
|
||||||
@@ -51,8 +53,10 @@ class ServerListeners @Inject constructor() {
|
|||||||
extraBufferCapacity = Channel.UNLIMITED,
|
extraBufferCapacity = Channel.UNLIMITED,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun <T> combineMangaUpdates(flow: Flow<T>, predate: (suspend (List<Long>) -> Boolean)? = null) =
|
fun <T> combineMangaUpdates(
|
||||||
if (predate != null) {
|
flow: Flow<T>,
|
||||||
|
predate: (suspend (List<Long>) -> Boolean)? = null,
|
||||||
|
) = if (predate != null) {
|
||||||
_mangaListener
|
_mangaListener
|
||||||
.filter(predate)
|
.filter(predate)
|
||||||
.startWith(Unit)
|
.startWith(Unit)
|
||||||
@@ -68,8 +72,10 @@ class ServerListeners @Inject constructor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> combineCategoryManga(flow: Flow<T>, predate: (suspend (Long) -> Boolean)? = null) =
|
fun <T> combineCategoryManga(
|
||||||
if (predate != null) {
|
flow: Flow<T>,
|
||||||
|
predate: (suspend (Long) -> Boolean)? = null,
|
||||||
|
) = if (predate != null) {
|
||||||
categoryMangaListener.filter(predate).startWith(-1)
|
categoryMangaListener.filter(predate).startWith(-1)
|
||||||
} else {
|
} else {
|
||||||
categoryMangaListener.startWith(-1)
|
categoryMangaListener.startWith(-1)
|
||||||
@@ -104,25 +110,37 @@ class ServerListeners @Inject constructor() {
|
|||||||
.flatMapLatest { flow }
|
.flatMapLatest { flow }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateChapters(mangaId: Long, chapterIndexes: List<Int>) {
|
fun updateChapters(
|
||||||
|
mangaId: Long,
|
||||||
|
chapterIndexes: List<Int>,
|
||||||
|
) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
_chapterIndexesListener.emit(mangaId to chapterIndexes.ifEmpty { null })
|
_chapterIndexesListener.emit(mangaId to chapterIndexes.ifEmpty { null })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateChapters(mangaId: Long, vararg chapterIndexes: Int) {
|
fun updateChapters(
|
||||||
|
mangaId: Long,
|
||||||
|
vararg chapterIndexes: Int,
|
||||||
|
) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
_chapterIndexesListener.emit(mangaId to chapterIndexes.toList().ifEmpty { null })
|
_chapterIndexesListener.emit(mangaId to chapterIndexes.toList().ifEmpty { null })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateChapters(mangaId: Long?, chapterIds: List<Long>) {
|
fun updateChapters(
|
||||||
|
mangaId: Long?,
|
||||||
|
chapterIds: List<Long>,
|
||||||
|
) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
_chapterIdsListener.emit(mangaId to chapterIds)
|
_chapterIdsListener.emit(mangaId to chapterIds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateChapters(mangaId: Long?, vararg chapterIds: Long) {
|
fun updateChapters(
|
||||||
|
mangaId: Long?,
|
||||||
|
vararg chapterIds: Long,
|
||||||
|
) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
_chapterIdsListener.emit(mangaId to chapterIds.toList())
|
_chapterIdsListener.emit(mangaId to chapterIds.toList())
|
||||||
}
|
}
|
||||||
@@ -131,4 +149,4 @@ class ServerListeners @Inject constructor() {
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,8 +60,10 @@ interface SharedDomainComponent : CoreComponent {
|
|||||||
|
|
||||||
@AppScope
|
@AppScope
|
||||||
@Provides
|
@Provides
|
||||||
fun httpFactory(serverPreferences: ServerPreferences, json: Json) =
|
fun httpFactory(
|
||||||
httpClient(serverPreferences, json)
|
serverPreferences: ServerPreferences,
|
||||||
|
json: Json,
|
||||||
|
) = httpClient(serverPreferences, json)
|
||||||
|
|
||||||
@get:AppScope
|
@get:AppScope
|
||||||
@get:Provides
|
@get:Provides
|
||||||
|
|||||||
@@ -13,19 +13,22 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class ExportBackupFile @Inject constructor(private val backupRepository: BackupRepository) {
|
class ExportBackupFile
|
||||||
|
@Inject
|
||||||
suspend fun await(block: HttpRequestBuilder.() -> Unit = {}, onError: suspend (Throwable) -> Unit = {}) = asFlow(block)
|
constructor(private val backupRepository: BackupRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
block: HttpRequestBuilder.() -> Unit = {},
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(block)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to export backup" }
|
log.warn(it) { "Failed to export backup" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(block: HttpRequestBuilder.() -> Unit = {}) =
|
fun asFlow(block: HttpRequestBuilder.() -> Unit = {}) = backupRepository.exportBackupFile(block)
|
||||||
backupRepository.exportBackupFile(block)
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,19 +14,26 @@ import me.tatarka.inject.annotations.Inject
|
|||||||
import okio.Path
|
import okio.Path
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class ImportBackupFile @Inject constructor(private val backupRepository: BackupRepository) {
|
class ImportBackupFile
|
||||||
|
@Inject
|
||||||
suspend fun await(file: Path, block: HttpRequestBuilder.() -> Unit = {}, onError: suspend (Throwable) -> Unit = {}) = asFlow(file, block)
|
constructor(private val backupRepository: BackupRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
file: Path,
|
||||||
|
block: HttpRequestBuilder.() -> Unit = {},
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(file, block)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to import backup ${file.name}" }
|
log.warn(it) { "Failed to import backup ${file.name}" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(file: Path, block: HttpRequestBuilder.() -> Unit = {}) =
|
fun asFlow(
|
||||||
backupRepository.importBackupFile(BackupRepository.buildBackupFormData(file), block)
|
file: Path,
|
||||||
|
block: HttpRequestBuilder.() -> Unit = {},
|
||||||
|
) = backupRepository.importBackupFile(BackupRepository.buildBackupFormData(file), block)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,19 +14,26 @@ import me.tatarka.inject.annotations.Inject
|
|||||||
import okio.Path
|
import okio.Path
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class ValidateBackupFile @Inject constructor(private val backupRepository: BackupRepository) {
|
class ValidateBackupFile
|
||||||
|
@Inject
|
||||||
suspend fun await(file: Path, block: HttpRequestBuilder.() -> Unit = {}, onError: suspend (Throwable) -> Unit = {}) = asFlow(file, block)
|
constructor(private val backupRepository: BackupRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
file: Path,
|
||||||
|
block: HttpRequestBuilder.() -> Unit = {},
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(file, block)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to validate backup ${file.name}" }
|
log.warn(it) { "Failed to validate backup ${file.name}" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(file: Path, block: HttpRequestBuilder.() -> Unit = {}) =
|
fun asFlow(
|
||||||
backupRepository.validateBackupFile(BackupRepository.buildBackupFormData(file), block)
|
file: Path,
|
||||||
|
block: HttpRequestBuilder.() -> Unit = {},
|
||||||
|
) = backupRepository.validateBackupFile(BackupRepository.buildBackupFormData(file), block)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import okio.Path
|
|||||||
import okio.buffer
|
import okio.buffer
|
||||||
|
|
||||||
interface BackupRepository {
|
interface BackupRepository {
|
||||||
|
|
||||||
@Multipart
|
@Multipart
|
||||||
@POST("api/v1/backup/import/file")
|
@POST("api/v1/backup/import/file")
|
||||||
fun importBackupFile(
|
fun importBackupFile(
|
||||||
@@ -47,7 +46,8 @@ interface BackupRepository {
|
|||||||
): Flow<HttpResponse>
|
): Flow<HttpResponse>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun buildBackupFormData(file: Path) = formData {
|
fun buildBackupFormData(file: Path) =
|
||||||
|
formData {
|
||||||
append(
|
append(
|
||||||
"backup.proto.gz",
|
"backup.proto.gz",
|
||||||
FileSystem.SYSTEM.source(file).buffer().readByteArray(),
|
FileSystem.SYSTEM.source(file).buffer().readByteArray(),
|
||||||
|
|||||||
@@ -17,26 +17,38 @@ import kotlinx.coroutines.flow.map
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class AddMangaToCategory @Inject constructor(
|
class AddMangaToCategory
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val categoryRepository: CategoryRepository,
|
private val categoryRepository: CategoryRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, categoryId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId, categoryId)
|
mangaId: Long,
|
||||||
|
categoryId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId, categoryId)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to add $mangaId to category $categoryId" }
|
log.warn(it) { "Failed to add $mangaId to category $categoryId" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, category: Category, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga, category)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
category: Category,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga, category)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to add ${manga.title}(${manga.id}) to category ${category.name}" }
|
log.warn(it) { "Failed to add ${manga.title}(${manga.id}) to category ${category.name}" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long, categoryId: Long) = if (categoryId != 0L) {
|
fun asFlow(
|
||||||
|
mangaId: Long,
|
||||||
|
categoryId: Long,
|
||||||
|
) = if (categoryId != 0L) {
|
||||||
categoryRepository.addMangaToCategory(mangaId, categoryId)
|
categoryRepository.addMangaToCategory(mangaId, categoryId)
|
||||||
.map { serverListeners.updateCategoryManga(categoryId) }
|
.map { serverListeners.updateCategoryManga(categoryId) }
|
||||||
} else {
|
} else {
|
||||||
@@ -46,7 +58,10 @@ class AddMangaToCategory @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun asFlow(manga: Manga, category: Category) = if (category.id != 0L) {
|
fun asFlow(
|
||||||
|
manga: Manga,
|
||||||
|
category: Category,
|
||||||
|
) = if (category.id != 0L) {
|
||||||
categoryRepository.addMangaToCategory(manga.id, category.id)
|
categoryRepository.addMangaToCategory(manga.id, category.id)
|
||||||
.map { serverListeners.updateCategoryManga(category.id) }
|
.map { serverListeners.updateCategoryManga(category.id) }
|
||||||
} else {
|
} else {
|
||||||
@@ -59,4 +74,4 @@ class AddMangaToCategory @Inject constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,13 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class CreateCategory @Inject constructor(private val categoryRepository: CategoryRepository) {
|
class CreateCategory
|
||||||
|
@Inject
|
||||||
suspend fun await(name: String, onError: suspend (Throwable) -> Unit = {}) = asFlow(name)
|
constructor(private val categoryRepository: CategoryRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
name: String,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(name)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to create category $name" }
|
log.warn(it) { "Failed to create category $name" }
|
||||||
@@ -26,4 +30,4 @@ class CreateCategory @Inject constructor(private val categoryRepository: Categor
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,16 +13,23 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class DeleteCategory @Inject constructor(private val categoryRepository: CategoryRepository) {
|
class DeleteCategory
|
||||||
|
@Inject
|
||||||
suspend fun await(categoryId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(categoryId)
|
constructor(private val categoryRepository: CategoryRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
categoryId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(categoryId)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to delete category $categoryId" }
|
log.warn(it) { "Failed to delete category $categoryId" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(category: Category, onError: suspend (Throwable) -> Unit = {}) = asFlow(category)
|
suspend fun await(
|
||||||
|
category: Category,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(category)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to delete category ${category.name}" }
|
log.warn(it) { "Failed to delete category ${category.name}" }
|
||||||
@@ -36,4 +43,4 @@ class DeleteCategory @Inject constructor(private val categoryRepository: Categor
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,16 +13,21 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetCategories @Inject constructor(private val categoryRepository: CategoryRepository) {
|
class GetCategories
|
||||||
|
@Inject
|
||||||
suspend fun await(dropDefault: Boolean = false, onError: suspend (Throwable) -> Unit = {}) = asFlow(dropDefault)
|
constructor(private val categoryRepository: CategoryRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
dropDefault: Boolean = false,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(dropDefault)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to get categories" }
|
log.warn(it) { "Failed to get categories" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(dropDefault: Boolean = false) = categoryRepository.getCategories()
|
fun asFlow(dropDefault: Boolean = false) =
|
||||||
|
categoryRepository.getCategories()
|
||||||
.map { categories ->
|
.map { categories ->
|
||||||
if (dropDefault) {
|
if (dropDefault) {
|
||||||
categories.filterNot { it.name.equals("default", true) }
|
categories.filterNot { it.name.equals("default", true) }
|
||||||
@@ -34,4 +39,4 @@ class GetCategories @Inject constructor(private val categoryRepository: Category
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,16 +13,23 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetMangaCategories @Inject constructor(private val categoryRepository: CategoryRepository) {
|
class GetMangaCategories
|
||||||
|
@Inject
|
||||||
suspend fun await(mangaId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId)
|
constructor(private val categoryRepository: CategoryRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
mangaId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to get categories for $mangaId" }
|
log.warn(it) { "Failed to get categories for $mangaId" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to get categories for ${manga.title}(${manga.id})" }
|
log.warn(it) { "Failed to get categories for ${manga.title}(${manga.id})" }
|
||||||
@@ -36,4 +43,4 @@ class GetMangaCategories @Inject constructor(private val categoryRepository: Cat
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,16 @@ import kotlinx.coroutines.flow.take
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetMangaListFromCategory @Inject constructor(
|
class GetMangaListFromCategory
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val categoryRepository: CategoryRepository,
|
private val categoryRepository: CategoryRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(categoryId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(categoryId)
|
categoryId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(categoryId)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -28,7 +32,10 @@ class GetMangaListFromCategory @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(category: Category, onError: suspend (Throwable) -> Unit = {}) = asFlow(category)
|
suspend fun await(
|
||||||
|
category: Category,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(category)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -36,15 +43,17 @@ class GetMangaListFromCategory @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(categoryId: Long) = serverListeners.combineCategoryManga(
|
fun asFlow(categoryId: Long) =
|
||||||
|
serverListeners.combineCategoryManga(
|
||||||
categoryRepository.getMangaFromCategory(categoryId),
|
categoryRepository.getMangaFromCategory(categoryId),
|
||||||
) { categoryId == it }
|
) { categoryId == it }
|
||||||
|
|
||||||
fun asFlow(category: Category) = serverListeners.combineCategoryManga(
|
fun asFlow(category: Category) =
|
||||||
|
serverListeners.combineCategoryManga(
|
||||||
categoryRepository.getMangaFromCategory(category.id),
|
categoryRepository.getMangaFromCategory(category.id),
|
||||||
) { category.id == it }
|
) { category.id == it }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,14 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class ModifyCategory @Inject constructor(private val categoryRepository: CategoryRepository) {
|
class ModifyCategory
|
||||||
|
@Inject
|
||||||
suspend fun await(categoryId: Long, name: String, onError: suspend (Throwable) -> Unit = {}) = asFlow(
|
constructor(private val categoryRepository: CategoryRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
categoryId: Long,
|
||||||
|
name: String,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(
|
||||||
categoryId = categoryId,
|
categoryId = categoryId,
|
||||||
name = name,
|
name = name,
|
||||||
).catch {
|
).catch {
|
||||||
@@ -23,7 +28,11 @@ class ModifyCategory @Inject constructor(private val categoryRepository: Categor
|
|||||||
log.warn(it) { "Failed to modify category $categoryId with options: name=$name" }
|
log.warn(it) { "Failed to modify category $categoryId with options: name=$name" }
|
||||||
}.collect()
|
}.collect()
|
||||||
|
|
||||||
suspend fun await(category: Category, name: String? = null, onError: suspend (Throwable) -> Unit = {}) = asFlow(
|
suspend fun await(
|
||||||
|
category: Category,
|
||||||
|
name: String? = null,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(
|
||||||
category = category,
|
category = category,
|
||||||
name = name,
|
name = name,
|
||||||
).catch {
|
).catch {
|
||||||
@@ -31,12 +40,18 @@ class ModifyCategory @Inject constructor(private val categoryRepository: Categor
|
|||||||
log.warn(it) { "Failed to modify category ${category.name} with options: name=$name" }
|
log.warn(it) { "Failed to modify category ${category.name} with options: name=$name" }
|
||||||
}.collect()
|
}.collect()
|
||||||
|
|
||||||
fun asFlow(categoryId: Long, name: String) = categoryRepository.modifyCategory(
|
fun asFlow(
|
||||||
|
categoryId: Long,
|
||||||
|
name: String,
|
||||||
|
) = categoryRepository.modifyCategory(
|
||||||
categoryId = categoryId,
|
categoryId = categoryId,
|
||||||
name = name,
|
name = name,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun asFlow(category: Category, name: String? = null) = categoryRepository.modifyCategory(
|
fun asFlow(
|
||||||
|
category: Category,
|
||||||
|
name: String? = null,
|
||||||
|
) = categoryRepository.modifyCategory(
|
||||||
categoryId = category.id,
|
categoryId = category.id,
|
||||||
name = name ?: category.name,
|
name = name ?: category.name,
|
||||||
)
|
)
|
||||||
@@ -44,4 +59,4 @@ class ModifyCategory @Inject constructor(private val categoryRepository: Categor
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,26 +17,38 @@ import kotlinx.coroutines.flow.map
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class RemoveMangaFromCategory @Inject constructor(
|
class RemoveMangaFromCategory
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val categoryRepository: CategoryRepository,
|
private val categoryRepository: CategoryRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, categoryId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId, categoryId)
|
mangaId: Long,
|
||||||
|
categoryId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId, categoryId)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to remove $mangaId from category $categoryId" }
|
log.warn(it) { "Failed to remove $mangaId from category $categoryId" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, category: Category, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga, category)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
category: Category,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga, category)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to remove ${manga.title}(${manga.id}) from category ${category.name}" }
|
log.warn(it) { "Failed to remove ${manga.title}(${manga.id}) from category ${category.name}" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long, categoryId: Long) = if (categoryId != 0L) {
|
fun asFlow(
|
||||||
|
mangaId: Long,
|
||||||
|
categoryId: Long,
|
||||||
|
) = if (categoryId != 0L) {
|
||||||
categoryRepository.removeMangaFromCategory(mangaId, categoryId)
|
categoryRepository.removeMangaFromCategory(mangaId, categoryId)
|
||||||
.map { serverListeners.updateCategoryManga(categoryId) }
|
.map { serverListeners.updateCategoryManga(categoryId) }
|
||||||
} else {
|
} else {
|
||||||
@@ -46,7 +58,10 @@ class RemoveMangaFromCategory @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun asFlow(manga: Manga, category: Category) = if (category.id != 0L) {
|
fun asFlow(
|
||||||
|
manga: Manga,
|
||||||
|
category: Category,
|
||||||
|
) = if (category.id != 0L) {
|
||||||
categoryRepository.removeMangaFromCategory(manga.id, category.id)
|
categoryRepository.removeMangaFromCategory(manga.id, category.id)
|
||||||
.map { serverListeners.updateCategoryManga(category.id) }
|
.map { serverListeners.updateCategoryManga(category.id) }
|
||||||
} else {
|
} else {
|
||||||
@@ -59,4 +74,4 @@ class RemoveMangaFromCategory @Inject constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,18 +12,26 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class ReorderCategory @Inject constructor(private val categoryRepository: CategoryRepository) {
|
class ReorderCategory
|
||||||
|
@Inject
|
||||||
suspend fun await(to: Int, from: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(to, from)
|
constructor(private val categoryRepository: CategoryRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
to: Int,
|
||||||
|
from: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(to, from)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to move category from $from to $to" }
|
log.warn(it) { "Failed to move category from $from to $to" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
fun asFlow(to: Int, from: Int) = categoryRepository.reorderCategory(to, from)
|
fun asFlow(
|
||||||
|
to: Int,
|
||||||
|
from: Int,
|
||||||
|
) = categoryRepository.reorderCategory(to, from)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ import kotlinx.coroutines.flow.flow
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class UpdateCategoryMeta @Inject constructor(private val categoryRepository: CategoryRepository) {
|
class UpdateCategoryMeta
|
||||||
|
@Inject
|
||||||
|
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,
|
||||||
@@ -44,4 +45,4 @@ class UpdateCategoryMeta @Inject constructor(private val categoryRepository: Cat
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,12 @@ import me.tatarka.inject.annotations.Inject
|
|||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
|
|
||||||
class BatchUpdateChapter @Inject constructor(
|
class BatchUpdateChapter
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@JvmName("awaitChapters")
|
@JvmName("awaitChapters")
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
@@ -252,4 +253,4 @@ class BatchUpdateChapter @Inject constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,42 +16,61 @@ import kotlinx.coroutines.flow.onEach
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class DeleteChapterDownload @Inject constructor(
|
class DeleteChapterDownload
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, index: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId, index)
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId, index)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to delete chapter download for $index of $mangaId" }
|
log.warn(it) { "Failed to delete chapter download for $index of $mangaId" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, index: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga, index)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga, index)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to delete chapter download for $index of ${manga.title}(${manga.id})" }
|
log.warn(it) { "Failed to delete chapter download for $index of ${manga.title}(${manga.id})" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(chapter: Chapter, onError: suspend (Throwable) -> Unit = {}) = asFlow(chapter)
|
suspend fun await(
|
||||||
|
chapter: Chapter,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(chapter)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to delete chapter download for ${chapter.index} of ${chapter.mangaId}" }
|
log.warn(it) { "Failed to delete chapter download for ${chapter.index} of ${chapter.mangaId}" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long, index: Int) = chapterRepository.deleteChapterDownload(mangaId, index)
|
fun asFlow(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
) = chapterRepository.deleteChapterDownload(mangaId, index)
|
||||||
.onEach { serverListeners.updateChapters(mangaId, index) }
|
.onEach { serverListeners.updateChapters(mangaId, index) }
|
||||||
|
|
||||||
fun asFlow(manga: Manga, index: Int) = chapterRepository.deleteChapterDownload(manga.id, index)
|
fun asFlow(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
) = chapterRepository.deleteChapterDownload(manga.id, index)
|
||||||
.onEach { serverListeners.updateChapters(manga.id, index) }
|
.onEach { serverListeners.updateChapters(manga.id, index) }
|
||||||
|
|
||||||
fun asFlow(chapter: Chapter) = chapterRepository.deleteChapterDownload(chapter.mangaId, chapter.index)
|
fun asFlow(chapter: Chapter) =
|
||||||
|
chapterRepository.deleteChapterDownload(chapter.mangaId, chapter.index)
|
||||||
.onEach { serverListeners.updateChapters(chapter.mangaId, chapter.index) }
|
.onEach { serverListeners.updateChapters(chapter.mangaId, chapter.index) }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,17 @@ import kotlinx.coroutines.flow.take
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetChapter @Inject constructor(
|
class GetChapter
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, index: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId, index)
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId, index)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -29,7 +34,11 @@ class GetChapter @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, index: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga, index)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga, index)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -37,7 +46,10 @@ class GetChapter @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(chapter: Chapter, onError: suspend (Throwable) -> Unit = {}) = asFlow(chapter)
|
suspend fun await(
|
||||||
|
chapter: Chapter,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(chapter)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -45,7 +57,10 @@ class GetChapter @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long, index: Int) = serverListeners.combineChapters(
|
fun asFlow(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
) = serverListeners.combineChapters(
|
||||||
chapterRepository.getChapter(mangaId, index),
|
chapterRepository.getChapter(mangaId, index),
|
||||||
indexPredate = { id, chapterIndexes ->
|
indexPredate = { id, chapterIndexes ->
|
||||||
id == mangaId && (chapterIndexes == null || index in chapterIndexes)
|
id == mangaId && (chapterIndexes == null || index in chapterIndexes)
|
||||||
@@ -53,7 +68,10 @@ class GetChapter @Inject constructor(
|
|||||||
idPredate = { id, _ -> id == mangaId },
|
idPredate = { id, _ -> id == mangaId },
|
||||||
)
|
)
|
||||||
|
|
||||||
fun asFlow(manga: Manga, index: Int) = serverListeners.combineChapters(
|
fun asFlow(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
) = serverListeners.combineChapters(
|
||||||
chapterRepository.getChapter(manga.id, index),
|
chapterRepository.getChapter(manga.id, index),
|
||||||
indexPredate = { id, chapterIndexes ->
|
indexPredate = { id, chapterIndexes ->
|
||||||
id == manga.id && (chapterIndexes == null || index in chapterIndexes)
|
id == manga.id && (chapterIndexes == null || index in chapterIndexes)
|
||||||
@@ -61,7 +79,8 @@ class GetChapter @Inject constructor(
|
|||||||
idPredate = { id, _ -> id == manga.id },
|
idPredate = { id, _ -> id == manga.id },
|
||||||
)
|
)
|
||||||
|
|
||||||
fun asFlow(chapter: Chapter) = serverListeners.combineChapters(
|
fun asFlow(chapter: Chapter) =
|
||||||
|
serverListeners.combineChapters(
|
||||||
chapterRepository.getChapter(chapter.mangaId, chapter.index),
|
chapterRepository.getChapter(chapter.mangaId, chapter.index),
|
||||||
indexPredate = { id, chapterIndexes ->
|
indexPredate = { id, chapterIndexes ->
|
||||||
id == chapter.mangaId && (chapterIndexes == null || chapter.index in chapterIndexes)
|
id == chapter.mangaId && (chapterIndexes == null || chapter.index in chapterIndexes)
|
||||||
@@ -72,4 +91,4 @@ class GetChapter @Inject constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,9 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetChapterPage @Inject constructor(private val chapterRepository: ChapterRepository) {
|
class GetChapterPage
|
||||||
|
@Inject
|
||||||
|
constructor(private val chapterRepository: ChapterRepository) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
index: Int,
|
index: Int,
|
||||||
@@ -78,4 +79,4 @@ class GetChapterPage @Inject constructor(private val chapterRepository: ChapterR
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,16 @@ import kotlinx.coroutines.flow.take
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetChapters @Inject constructor(
|
class GetChapters
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId)
|
mangaId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -28,7 +32,10 @@ class GetChapters @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -36,13 +43,15 @@ class GetChapters @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long) = serverListeners.combineChapters(
|
fun asFlow(mangaId: Long) =
|
||||||
|
serverListeners.combineChapters(
|
||||||
chapterRepository.getChapters(mangaId),
|
chapterRepository.getChapters(mangaId),
|
||||||
indexPredate = { id, _ -> id == mangaId },
|
indexPredate = { id, _ -> id == mangaId },
|
||||||
idPredate = { id, _ -> id == mangaId },
|
idPredate = { id, _ -> id == mangaId },
|
||||||
)
|
)
|
||||||
|
|
||||||
fun asFlow(manga: Manga) = serverListeners.combineChapters(
|
fun asFlow(manga: Manga) =
|
||||||
|
serverListeners.combineChapters(
|
||||||
chapterRepository.getChapters(manga.id),
|
chapterRepository.getChapters(manga.id),
|
||||||
indexPredate = { id, _ -> id == manga.id },
|
indexPredate = { id, _ -> id == manga.id },
|
||||||
idPredate = { id, _ -> id == manga.id },
|
idPredate = { id, _ -> id == manga.id },
|
||||||
@@ -51,4 +60,4 @@ class GetChapters @Inject constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,32 +15,41 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class RefreshChapters @Inject constructor(
|
class RefreshChapters
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId)
|
mangaId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to refresh chapters for $mangaId" }
|
log.warn(it) { "Failed to refresh chapters for $mangaId" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to refresh chapters for ${manga.title}(${manga.id})" }
|
log.warn(it) { "Failed to refresh chapters for ${manga.title}(${manga.id})" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long) = chapterRepository.getChapters(mangaId, true)
|
fun asFlow(mangaId: Long) =
|
||||||
|
chapterRepository.getChapters(mangaId, true)
|
||||||
.onEach { serverListeners.updateChapters(mangaId) }
|
.onEach { serverListeners.updateChapters(mangaId) }
|
||||||
|
|
||||||
fun asFlow(manga: Manga) = chapterRepository.getChapters(manga.id, true)
|
fun asFlow(manga: Manga) =
|
||||||
|
chapterRepository.getChapters(manga.id, true)
|
||||||
.onEach { serverListeners.updateChapters(manga.id) }
|
.onEach { serverListeners.updateChapters(manga.id) }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,12 @@ import kotlinx.coroutines.flow.onEach
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class UpdateChapterBookmarked @Inject constructor(
|
class UpdateChapterBookmarked
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
index: Int,
|
index: Int,
|
||||||
@@ -88,4 +89,4 @@ class UpdateChapterBookmarked @Inject constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,12 @@ import kotlinx.coroutines.flow.onEach
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class UpdateChapterLastPageRead @Inject constructor(
|
class UpdateChapterLastPageRead
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
index: Int,
|
index: Int,
|
||||||
@@ -88,4 +89,4 @@ class UpdateChapterLastPageRead @Inject constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,12 @@ import kotlinx.coroutines.flow.onEach
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class UpdateChapterMarkPreviousRead @Inject constructor(
|
class UpdateChapterMarkPreviousRead
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
index: Int,
|
index: Int,
|
||||||
@@ -71,9 +72,8 @@ class UpdateChapterMarkPreviousRead @Inject constructor(
|
|||||||
markPreviousRead = true,
|
markPreviousRead = true,
|
||||||
).onEach { serverListeners.updateChapters(manga.id, index) }
|
).onEach { serverListeners.updateChapters(manga.id, index) }
|
||||||
|
|
||||||
fun asFlow(
|
fun asFlow(chapter: Chapter) =
|
||||||
chapter: Chapter,
|
chapterRepository.updateChapter(
|
||||||
) = chapterRepository.updateChapter(
|
|
||||||
mangaId = chapter.mangaId,
|
mangaId = chapter.mangaId,
|
||||||
chapterIndex = chapter.index,
|
chapterIndex = chapter.index,
|
||||||
markPreviousRead = true,
|
markPreviousRead = true,
|
||||||
@@ -82,4 +82,4 @@ class UpdateChapterMarkPreviousRead @Inject constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,12 @@ import kotlinx.coroutines.flow.flow
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class UpdateChapterMeta @Inject constructor(
|
class UpdateChapterMeta
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
chapter: Chapter,
|
chapter: Chapter,
|
||||||
pageOffset: Int = chapter.meta.juiPageOffset,
|
pageOffset: Int = chapter.meta.juiPageOffset,
|
||||||
@@ -50,4 +51,4 @@ class UpdateChapterMeta @Inject constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,12 @@ import kotlinx.coroutines.flow.onEach
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class UpdateChapterRead @Inject constructor(
|
class UpdateChapterRead
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
mangaId: Long,
|
mangaId: Long,
|
||||||
index: Int,
|
index: Int,
|
||||||
@@ -88,4 +89,4 @@ class UpdateChapterRead @Inject constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import io.ktor.client.statement.HttpResponse
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface ChapterRepository {
|
interface ChapterRepository {
|
||||||
|
|
||||||
@GET("api/v1/manga/{mangaId}/chapters")
|
@GET("api/v1/manga/{mangaId}/chapters")
|
||||||
fun getChapters(
|
fun getChapters(
|
||||||
@Path("mangaId") mangaId: Long,
|
@Path("mangaId") mangaId: Long,
|
||||||
|
|||||||
@@ -13,16 +13,23 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class BatchChapterDownload @Inject constructor(private val downloadRepository: DownloadRepository) {
|
class BatchChapterDownload
|
||||||
|
@Inject
|
||||||
suspend fun await(chapterIds: List<Long>, onError: suspend (Throwable) -> Unit = {}) = asFlow(chapterIds)
|
constructor(private val downloadRepository: DownloadRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
chapterIds: List<Long>,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(chapterIds)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to queue chapters $chapterIds for a download" }
|
log.warn(it) { "Failed to queue chapters $chapterIds for a download" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(vararg chapterIds: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(*chapterIds)
|
suspend fun await(
|
||||||
|
vararg chapterIds: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(*chapterIds)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to queue chapters ${chapterIds.asList()} for a download" }
|
log.warn(it) { "Failed to queue chapters ${chapterIds.asList()} for a download" }
|
||||||
@@ -36,4 +43,4 @@ class BatchChapterDownload @Inject constructor(private val downloadRepository: D
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class ClearDownloadQueue @Inject constructor(private val downloadRepository: DownloadRepository) {
|
class ClearDownloadQueue
|
||||||
|
@Inject
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) = asFlow()
|
constructor(private val downloadRepository: DownloadRepository) {
|
||||||
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to clear download queue" }
|
log.warn(it) { "Failed to clear download queue" }
|
||||||
@@ -26,4 +28,4 @@ class ClearDownloadQueue @Inject constructor(private val downloadRepository: Dow
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,36 +14,54 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class QueueChapterDownload @Inject constructor(private val downloadRepository: DownloadRepository) {
|
class QueueChapterDownload
|
||||||
|
@Inject
|
||||||
suspend fun await(mangaId: Long, index: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId, index)
|
constructor(private val downloadRepository: DownloadRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId, index)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to queue chapter $index of $mangaId for a download" }
|
log.warn(it) { "Failed to queue chapter $index of $mangaId for a download" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, index: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga, index)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga, index)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to queue chapter $index of ${manga.title}(${manga.id}) for a download" }
|
log.warn(it) { "Failed to queue chapter $index of ${manga.title}(${manga.id}) for a download" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(chapter: Chapter, onError: suspend (Throwable) -> Unit = {}) = asFlow(chapter)
|
suspend fun await(
|
||||||
|
chapter: Chapter,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(chapter)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to queue chapter ${chapter.index} of ${chapter.mangaId} for a download" }
|
log.warn(it) { "Failed to queue chapter ${chapter.index} of ${chapter.mangaId} for a download" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long, index: Int) = downloadRepository.queueChapterDownload(mangaId, index)
|
fun asFlow(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
) = downloadRepository.queueChapterDownload(mangaId, index)
|
||||||
|
|
||||||
fun asFlow(manga: Manga, index: Int) = downloadRepository.queueChapterDownload(manga.id, index)
|
fun asFlow(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
) = downloadRepository.queueChapterDownload(manga.id, index)
|
||||||
|
|
||||||
fun asFlow(chapter: Chapter) = downloadRepository.queueChapterDownload(chapter.mangaId, chapter.index)
|
fun asFlow(chapter: Chapter) = downloadRepository.queueChapterDownload(chapter.mangaId, chapter.index)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,36 +14,62 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class ReorderChapterDownload @Inject constructor(private val downloadRepository: DownloadRepository) {
|
class ReorderChapterDownload
|
||||||
|
@Inject
|
||||||
suspend fun await(mangaId: Long, index: Int, to: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId, index, to)
|
constructor(private val downloadRepository: DownloadRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
to: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId, index, to)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to reorder chapter download for $index of $mangaId to $to" }
|
log.warn(it) { "Failed to reorder chapter download for $index of $mangaId to $to" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, index: Int, to: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga, index, to)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
to: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga, index, to)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to reorder chapter download for $index of ${manga.title}(${manga.id}) to $to" }
|
log.warn(it) { "Failed to reorder chapter download for $index of ${manga.title}(${manga.id}) to $to" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(chapter: Chapter, to: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(chapter, to)
|
suspend fun await(
|
||||||
|
chapter: Chapter,
|
||||||
|
to: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(chapter, to)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to reorder chapter download for ${chapter.index} of ${chapter.mangaId} to $to" }
|
log.warn(it) { "Failed to reorder chapter download for ${chapter.index} of ${chapter.mangaId} to $to" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long, index: Int, to: Int) = downloadRepository.reorderChapterDownload(mangaId, index, to)
|
fun asFlow(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
to: Int,
|
||||||
|
) = downloadRepository.reorderChapterDownload(mangaId, index, to)
|
||||||
|
|
||||||
fun asFlow(manga: Manga, index: Int, to: Int) = downloadRepository.reorderChapterDownload(manga.id, index, to)
|
fun asFlow(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
to: Int,
|
||||||
|
) = downloadRepository.reorderChapterDownload(manga.id, index, to)
|
||||||
|
|
||||||
fun asFlow(chapter: Chapter, to: Int) = downloadRepository.reorderChapterDownload(chapter.mangaId, chapter.index, to)
|
fun asFlow(
|
||||||
|
chapter: Chapter,
|
||||||
|
to: Int,
|
||||||
|
) = downloadRepository.reorderChapterDownload(chapter.mangaId, chapter.index, to)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class StartDownloading @Inject constructor(private val downloadRepository: DownloadRepository) {
|
class StartDownloading
|
||||||
|
@Inject
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) = asFlow()
|
constructor(private val downloadRepository: DownloadRepository) {
|
||||||
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to start downloader" }
|
log.warn(it) { "Failed to start downloader" }
|
||||||
@@ -26,4 +28,4 @@ class StartDownloading @Inject constructor(private val downloadRepository: Downl
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,36 +14,54 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class StopChapterDownload @Inject constructor(private val downloadRepository: DownloadRepository) {
|
class StopChapterDownload
|
||||||
|
@Inject
|
||||||
suspend fun await(mangaId: Long, index: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId, index)
|
constructor(private val downloadRepository: DownloadRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId, index)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to stop chapter download for $index of $mangaId" }
|
log.warn(it) { "Failed to stop chapter download for $index of $mangaId" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, index: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga, index)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga, index)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to stop chapter download for $index of ${manga.title}(${manga.id})" }
|
log.warn(it) { "Failed to stop chapter download for $index of ${manga.title}(${manga.id})" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
suspend fun await(chapter: Chapter, onError: suspend (Throwable) -> Unit = {}) = asFlow(chapter)
|
suspend fun await(
|
||||||
|
chapter: Chapter,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(chapter)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to stop chapter download for ${chapter.index} of ${chapter.mangaId}" }
|
log.warn(it) { "Failed to stop chapter download for ${chapter.index} of ${chapter.mangaId}" }
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long, index: Int) = downloadRepository.stopChapterDownload(mangaId, index)
|
fun asFlow(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
) = downloadRepository.stopChapterDownload(mangaId, index)
|
||||||
|
|
||||||
fun asFlow(manga: Manga, index: Int) = downloadRepository.stopChapterDownload(manga.id, index)
|
fun asFlow(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
) = downloadRepository.stopChapterDownload(manga.id, index)
|
||||||
|
|
||||||
fun asFlow(chapter: Chapter) = downloadRepository.stopChapterDownload(chapter.mangaId, chapter.index)
|
fun asFlow(chapter: Chapter) = downloadRepository.stopChapterDownload(chapter.mangaId, chapter.index)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class StopDownloading @Inject constructor(private val downloadRepository: DownloadRepository) {
|
class StopDownloading
|
||||||
|
@Inject
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) = asFlow()
|
constructor(private val downloadRepository: DownloadRepository) {
|
||||||
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to stop downloader" }
|
log.warn(it) { "Failed to stop downloader" }
|
||||||
@@ -26,4 +28,4 @@ class StopDownloading @Inject constructor(private val downloadRepository: Downlo
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ import kotlinx.coroutines.flow.map
|
|||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
|
||||||
class DownloadService @Inject constructor(
|
class DownloadService
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
serverPreferences: ServerPreferences,
|
serverPreferences: ServerPreferences,
|
||||||
client: Http,
|
client: Http,
|
||||||
) : WebsocketService(serverPreferences, client) {
|
) : WebsocketService(serverPreferences, client) {
|
||||||
override val _status: MutableStateFlow<Status>
|
override val _status: MutableStateFlow<Status>
|
||||||
get() = status
|
get() = status
|
||||||
|
|
||||||
@@ -51,4 +53,4 @@ class DownloadService @Inject constructor(
|
|||||||
it.filter { it.mangaId in mangaIds }
|
it.filter { it.mangaId in mangaIds }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetExtensionList @Inject constructor(private val extensionRepository: ExtensionRepository) {
|
class GetExtensionList
|
||||||
|
@Inject
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) = asFlow()
|
constructor(private val extensionRepository: ExtensionRepository) {
|
||||||
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to get extension list" }
|
log.warn(it) { "Failed to get extension list" }
|
||||||
@@ -26,4 +28,4 @@ class GetExtensionList @Inject constructor(private val extensionRepository: Exte
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,13 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class InstallExtension @Inject constructor(private val extensionRepository: ExtensionRepository) {
|
class InstallExtension
|
||||||
|
@Inject
|
||||||
suspend fun await(extension: Extension, onError: suspend (Throwable) -> Unit = {}) = asFlow(extension)
|
constructor(private val extensionRepository: ExtensionRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
extension: Extension,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(extension)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to install extension ${extension.apkName}" }
|
log.warn(it) { "Failed to install extension ${extension.apkName}" }
|
||||||
@@ -27,4 +31,4 @@ class InstallExtension @Inject constructor(private val extensionRepository: Exte
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,13 @@ import me.tatarka.inject.annotations.Inject
|
|||||||
import okio.Path
|
import okio.Path
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class InstallExtensionFile @Inject constructor(private val extensionRepository: ExtensionRepository) {
|
class InstallExtensionFile
|
||||||
|
@Inject
|
||||||
suspend fun await(path: Path, onError: suspend (Throwable) -> Unit = {}) = asFlow(path)
|
constructor(private val extensionRepository: ExtensionRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
path: Path,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(path)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to install extension from $path" }
|
log.warn(it) { "Failed to install extension from $path" }
|
||||||
@@ -27,4 +31,4 @@ class InstallExtensionFile @Inject constructor(private val extensionRepository:
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,13 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class UninstallExtension @Inject constructor(private val extensionRepository: ExtensionRepository) {
|
class UninstallExtension
|
||||||
|
@Inject
|
||||||
suspend fun await(extension: Extension, onError: suspend (Throwable) -> Unit = {}) = asFlow(extension)
|
constructor(private val extensionRepository: ExtensionRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
extension: Extension,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(extension)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to uninstall extension ${extension.apkName}" }
|
log.warn(it) { "Failed to uninstall extension ${extension.apkName}" }
|
||||||
@@ -27,4 +31,4 @@ class UninstallExtension @Inject constructor(private val extensionRepository: Ex
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,13 @@ import kotlinx.coroutines.flow.collect
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class UpdateExtension @Inject constructor(private val extensionRepository: ExtensionRepository) {
|
class UpdateExtension
|
||||||
|
@Inject
|
||||||
suspend fun await(extension: Extension, onError: suspend (Throwable) -> Unit = {}) = asFlow(extension)
|
constructor(private val extensionRepository: ExtensionRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
extension: Extension,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(extension)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to update extension ${extension.apkName}" }
|
log.warn(it) { "Failed to update extension ${extension.apkName}" }
|
||||||
@@ -27,4 +31,4 @@ class UpdateExtension @Inject constructor(private val extensionRepository: Exten
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ interface ExtensionRepository {
|
|||||||
): Flow<ByteReadChannel>
|
): Flow<ByteReadChannel>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun buildExtensionFormData(file: okio.Path) = formData {
|
fun buildExtensionFormData(file: okio.Path) =
|
||||||
|
formData {
|
||||||
append(
|
append(
|
||||||
"file",
|
"file",
|
||||||
FileSystem.SYSTEM.source(file).buffer().readByteArray(),
|
FileSystem.SYSTEM.source(file).buffer().readByteArray(),
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetGlobalMeta @Inject constructor(private val globalRepository: GlobalRepository) {
|
class GetGlobalMeta
|
||||||
|
@Inject
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) = asFlow()
|
constructor(private val globalRepository: GlobalRepository) {
|
||||||
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to get global meta" }
|
log.warn(it) { "Failed to get global meta" }
|
||||||
@@ -26,4 +28,4 @@ class GetGlobalMeta @Inject constructor(private val globalRepository: GlobalRepo
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ import kotlinx.coroutines.flow.flow
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class UpdateGlobalMeta @Inject constructor(private val globalRepository: GlobalRepository) {
|
class UpdateGlobalMeta
|
||||||
|
@Inject
|
||||||
|
constructor(private val globalRepository: GlobalRepository) {
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
globalMeta: GlobalMeta,
|
globalMeta: GlobalMeta,
|
||||||
example: Int = globalMeta.example,
|
example: Int = globalMeta.example,
|
||||||
@@ -43,4 +44,4 @@ class UpdateGlobalMeta @Inject constructor(private val globalRepository: GlobalR
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,32 +15,41 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class AddMangaToLibrary @Inject constructor(
|
class AddMangaToLibrary
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val libraryRepository: LibraryRepository,
|
private val libraryRepository: LibraryRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId)
|
mangaId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to add $mangaId to library" }
|
log.warn(it) { "Failed to add $mangaId to library" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to add ${manga.title}(${manga.id}) to library" }
|
log.warn(it) { "Failed to add ${manga.title}(${manga.id}) to library" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long) = libraryRepository.addMangaToLibrary(mangaId)
|
fun asFlow(mangaId: Long) =
|
||||||
|
libraryRepository.addMangaToLibrary(mangaId)
|
||||||
.onEach { serverListeners.updateManga(mangaId) }
|
.onEach { serverListeners.updateManga(mangaId) }
|
||||||
|
|
||||||
fun asFlow(manga: Manga) = libraryRepository.addMangaToLibrary(manga.id)
|
fun asFlow(manga: Manga) =
|
||||||
|
libraryRepository.addMangaToLibrary(manga.id)
|
||||||
.onEach { serverListeners.updateManga(manga.id) }
|
.onEach { serverListeners.updateManga(manga.id) }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,32 +15,41 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class RemoveMangaFromLibrary @Inject constructor(
|
class RemoveMangaFromLibrary
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val libraryRepository: LibraryRepository,
|
private val libraryRepository: LibraryRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId)
|
mangaId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to remove $mangaId from library" }
|
log.warn(it) { "Failed to remove $mangaId from library" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to remove ${manga.title}(${manga.id}) from library" }
|
log.warn(it) { "Failed to remove ${manga.title}(${manga.id}) from library" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long) = libraryRepository.removeMangaFromLibrary(mangaId)
|
fun asFlow(mangaId: Long) =
|
||||||
|
libraryRepository.removeMangaFromLibrary(mangaId)
|
||||||
.onEach { serverListeners.updateManga(mangaId) }
|
.onEach { serverListeners.updateManga(mangaId) }
|
||||||
|
|
||||||
fun asFlow(manga: Manga) = libraryRepository.removeMangaFromLibrary(manga.id)
|
fun asFlow(manga: Manga) =
|
||||||
|
libraryRepository.removeMangaFromLibrary(manga.id)
|
||||||
.onEach { serverListeners.updateManga(manga.id) }
|
.onEach { serverListeners.updateManga(manga.id) }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import kotlinx.serialization.Transient
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@Stable
|
@Stable
|
||||||
enum class DisplayMode(@Transient val res: StringResource) {
|
enum class DisplayMode(
|
||||||
|
@Transient val res: StringResource,
|
||||||
|
) {
|
||||||
CompactGrid(MR.strings.display_compact),
|
CompactGrid(MR.strings.display_compact),
|
||||||
ComfortableGrid(MR.strings.display_comfortable),
|
ComfortableGrid(MR.strings.display_comfortable),
|
||||||
CoverOnlyGrid(MR.strings.display_cover_only),
|
CoverOnlyGrid(MR.strings.display_cover_only),
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import kotlinx.serialization.Transient
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@Stable
|
@Stable
|
||||||
enum class Sort(@Transient val res: StringResource) {
|
enum class Sort(
|
||||||
|
@Transient val res: StringResource,
|
||||||
|
) {
|
||||||
ALPHABETICAL(MR.strings.sort_alphabetical),
|
ALPHABETICAL(MR.strings.sort_alphabetical),
|
||||||
|
|
||||||
// LAST_READ,
|
// LAST_READ,
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ 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(private val preferenceStore: PreferenceStore) {
|
||||||
|
|
||||||
fun showAllCategory(): Preference<Boolean> {
|
fun showAllCategory(): Preference<Boolean> {
|
||||||
return preferenceStore.getBoolean("show_all_category", false)
|
return preferenceStore.getBoolean("show_all_category", false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import io.ktor.client.statement.HttpResponse
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface LibraryRepository {
|
interface LibraryRepository {
|
||||||
|
|
||||||
@GET("api/v1/manga/{mangaId}/library")
|
@GET("api/v1/manga/{mangaId}/library")
|
||||||
fun addMangaToLibrary(
|
fun addMangaToLibrary(
|
||||||
@Path("mangaId") mangaId: Long,
|
@Path("mangaId") mangaId: Long,
|
||||||
|
|||||||
@@ -17,11 +17,12 @@ import kotlinx.serialization.decodeFromString
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class LibraryUpdateService @Inject constructor(
|
class LibraryUpdateService
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
serverPreferences: ServerPreferences,
|
serverPreferences: ServerPreferences,
|
||||||
client: Http,
|
client: Http,
|
||||||
) : WebsocketService(serverPreferences, client) {
|
) : WebsocketService(serverPreferences, client) {
|
||||||
|
|
||||||
override val _status: MutableStateFlow<Status>
|
override val _status: MutableStateFlow<Status>
|
||||||
get() = status
|
get() = status
|
||||||
|
|
||||||
@@ -38,4 +39,4 @@ class LibraryUpdateService @Inject constructor(
|
|||||||
val status = MutableStateFlow(Status.STARTING)
|
val status = MutableStateFlow(Status.STARTING)
|
||||||
val updateStatus = MutableStateFlow(UpdateStatus(emptyMap(), false))
|
val updateStatus = MutableStateFlow(UpdateStatus(emptyMap(), false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,16 @@ import kotlinx.coroutines.flow.take
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetManga @Inject constructor(
|
class GetManga
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId)
|
mangaId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -28,7 +32,10 @@ class GetManga @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -36,15 +43,17 @@ class GetManga @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long) = serverListeners.combineMangaUpdates(
|
fun asFlow(mangaId: Long) =
|
||||||
|
serverListeners.combineMangaUpdates(
|
||||||
mangaRepository.getManga(mangaId),
|
mangaRepository.getManga(mangaId),
|
||||||
) { mangaId in it }
|
) { mangaId in it }
|
||||||
|
|
||||||
fun asFlow(manga: Manga) = serverListeners.combineMangaUpdates(
|
fun asFlow(manga: Manga) =
|
||||||
|
serverListeners.combineMangaUpdates(
|
||||||
mangaRepository.getManga(manga.id),
|
mangaRepository.getManga(manga.id),
|
||||||
) { manga.id in it }
|
) { manga.id in it }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,16 @@ import kotlinx.coroutines.flow.take
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetMangaFull @Inject constructor(
|
class GetMangaFull
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId)
|
mangaId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -28,7 +32,10 @@ class GetMangaFull @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -36,15 +43,17 @@ class GetMangaFull @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long) = serverListeners.combineMangaUpdates(
|
fun asFlow(mangaId: Long) =
|
||||||
|
serverListeners.combineMangaUpdates(
|
||||||
mangaRepository.getMangaFull(mangaId),
|
mangaRepository.getMangaFull(mangaId),
|
||||||
) { mangaId in it }
|
) { mangaId in it }
|
||||||
|
|
||||||
fun asFlow(manga: Manga) = serverListeners.combineMangaUpdates(
|
fun asFlow(manga: Manga) =
|
||||||
|
serverListeners.combineMangaUpdates(
|
||||||
mangaRepository.getMangaFull(manga.id),
|
mangaRepository.getMangaFull(manga.id),
|
||||||
) { manga.id in it }
|
) { manga.id in it }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,16 @@ import kotlinx.coroutines.flow.take
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class RefreshManga @Inject constructor(
|
class RefreshManga
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId)
|
mangaId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -29,7 +33,10 @@ class RefreshManga @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -37,13 +44,11 @@ class RefreshManga @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long) =
|
fun asFlow(mangaId: Long) = mangaRepository.getManga(mangaId, true).onEach { serverListeners.updateManga(mangaId) }
|
||||||
mangaRepository.getManga(mangaId, true).onEach { serverListeners.updateManga(mangaId) }
|
|
||||||
|
|
||||||
fun asFlow(manga: Manga) =
|
fun asFlow(manga: Manga) = mangaRepository.getManga(manga.id, true).onEach { serverListeners.updateManga(manga.id) }
|
||||||
mangaRepository.getManga(manga.id, true).onEach { serverListeners.updateManga(manga.id) }
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,16 @@ import kotlinx.coroutines.flow.take
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class RefreshMangaFull @Inject constructor(
|
class RefreshMangaFull
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
suspend fun await(
|
||||||
suspend fun await(mangaId: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId)
|
mangaId: Long,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(mangaId)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -29,7 +33,10 @@ class RefreshMangaFull @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(manga: Manga, onError: suspend (Throwable) -> Unit = {}) = asFlow(manga)
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(manga)
|
||||||
.take(1)
|
.take(1)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
@@ -37,13 +44,11 @@ class RefreshMangaFull @Inject constructor(
|
|||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(mangaId: Long) =
|
fun asFlow(mangaId: Long) = mangaRepository.getMangaFull(mangaId, true).onEach { serverListeners.updateManga(mangaId) }
|
||||||
mangaRepository.getMangaFull(mangaId, true).onEach { serverListeners.updateManga(mangaId) }
|
|
||||||
|
|
||||||
fun asFlow(manga: Manga) =
|
fun asFlow(manga: Manga) = mangaRepository.getMangaFull(manga.id, true).onEach { serverListeners.updateManga(manga.id) }
|
||||||
mangaRepository.getMangaFull(manga.id, true).onEach { serverListeners.updateManga(manga.id) }
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,12 @@ import kotlinx.coroutines.flow.flow
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class UpdateMangaMeta @Inject constructor(
|
class UpdateMangaMeta
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
private val serverListeners: ServerListeners,
|
private val serverListeners: ServerListeners,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
manga: Manga,
|
manga: Manga,
|
||||||
readerMode: String = manga.meta.juiReaderMode,
|
readerMode: String = manga.meta.juiReaderMode,
|
||||||
@@ -51,4 +52,4 @@ class UpdateMangaMeta @Inject constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,9 @@ data class MangaMeta(
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@Stable
|
@Stable
|
||||||
enum class MangaStatus(@Transient val res: StringResource) {
|
enum class MangaStatus(
|
||||||
|
@Transient val res: StringResource,
|
||||||
|
) {
|
||||||
UNKNOWN(MR.strings.status_unknown),
|
UNKNOWN(MR.strings.status_unknown),
|
||||||
ONGOING(MR.strings.status_ongoing),
|
ONGOING(MR.strings.status_ongoing),
|
||||||
COMPLETED(MR.strings.status_completed),
|
COMPLETED(MR.strings.status_completed),
|
||||||
|
|||||||
@@ -11,11 +11,12 @@ import ca.gosyer.jui.domain.migration.service.MigrationPreferences
|
|||||||
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
|
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
|
||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
|
||||||
class RunMigrations @Inject constructor(
|
class RunMigrations
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
private val migrationPreferences: MigrationPreferences,
|
private val migrationPreferences: MigrationPreferences,
|
||||||
private val readerPreferences: ReaderPreferences,
|
private val readerPreferences: ReaderPreferences,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun runMigrations() {
|
fun runMigrations() {
|
||||||
val code = migrationPreferences.version().get()
|
val code = migrationPreferences.version().get()
|
||||||
if (code <= 0) {
|
if (code <= 0) {
|
||||||
@@ -26,4 +27,4 @@ class RunMigrations @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import kotlinx.serialization.Transient
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@Stable
|
@Stable
|
||||||
enum class Direction(@Transient val res: StringResource) {
|
enum class Direction(
|
||||||
|
@Transient val res: StringResource,
|
||||||
|
) {
|
||||||
Down(MR.strings.dir_down),
|
Down(MR.strings.dir_down),
|
||||||
Left(MR.strings.dir_rtl),
|
Left(MR.strings.dir_rtl),
|
||||||
Right(MR.strings.dir_ltr),
|
Right(MR.strings.dir_ltr),
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import kotlinx.serialization.Transient
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@Stable
|
@Stable
|
||||||
enum class ImageScale(@Transient val res: StringResource) {
|
enum class ImageScale(
|
||||||
|
@Transient val res: StringResource,
|
||||||
|
) {
|
||||||
FitScreen(MR.strings.scale_fit_screen),
|
FitScreen(MR.strings.scale_fit_screen),
|
||||||
Stretch(MR.strings.scale_stretch),
|
Stretch(MR.strings.scale_stretch),
|
||||||
FitWidth(MR.strings.scale_fit_width),
|
FitWidth(MR.strings.scale_fit_width),
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import kotlinx.serialization.Transient
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@Stable
|
@Stable
|
||||||
enum class NavigationMode(@Transient val res: StringResource) {
|
enum class NavigationMode(
|
||||||
|
@Transient val res: StringResource,
|
||||||
|
) {
|
||||||
Disabled(MR.strings.disabled),
|
Disabled(MR.strings.disabled),
|
||||||
LNavigation(MR.strings.nav_l_shaped),
|
LNavigation(MR.strings.nav_l_shaped),
|
||||||
KindlishNavigation(MR.strings.nav_kindle_ish),
|
KindlishNavigation(MR.strings.nav_kindle_ish),
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ 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(private val preferenceStore: PreferenceStore, private val factory: (String) -> PreferenceStore) {
|
||||||
|
|
||||||
fun preload(): Preference<Int> {
|
fun preload(): Preference<Int> {
|
||||||
return preferenceStore.getInt("preload", 3)
|
return preferenceStore.getInt("preload", 3)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,10 @@ expect val Engine: HttpClientEngineFactory<HttpClientEngineConfig>
|
|||||||
|
|
||||||
expect fun HttpClientConfig<HttpClientEngineConfig>.configurePlatform()
|
expect fun HttpClientConfig<HttpClientEngineConfig>.configurePlatform()
|
||||||
|
|
||||||
fun httpClient(serverPreferences: ServerPreferences, json: Json): Http {
|
fun httpClient(
|
||||||
|
serverPreferences: ServerPreferences,
|
||||||
|
json: Json,
|
||||||
|
): Http {
|
||||||
return HttpClient(Engine) {
|
return HttpClient(Engine) {
|
||||||
configurePlatform()
|
configurePlatform()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ 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(private val preferenceStore: PreferenceStore) {
|
||||||
|
|
||||||
fun server(): Preference<String> {
|
fun server(): Preference<String> {
|
||||||
return preferenceStore.getString("server_url", "http://localhost")
|
return preferenceStore.getString("server_url", "http://localhost")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class AboutServer @Inject constructor(private val settingsRepository: SettingsRepository) {
|
class AboutServer
|
||||||
|
@Inject
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) = asFlow()
|
constructor(private val settingsRepository: SettingsRepository) {
|
||||||
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to get server information" }
|
log.warn(it) { "Failed to get server information" }
|
||||||
@@ -26,4 +28,4 @@ class AboutServer @Inject constructor(private val settingsRepository: SettingsRe
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class CheckUpdate @Inject constructor(private val settingsRepository: SettingsRepository) {
|
class CheckUpdate
|
||||||
|
@Inject
|
||||||
suspend fun await(onError: suspend (Throwable) -> Unit = {}) = asFlow()
|
constructor(private val settingsRepository: SettingsRepository) {
|
||||||
|
suspend fun await(onError: suspend (Throwable) -> Unit = {}) =
|
||||||
|
asFlow()
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to check for server updates" }
|
log.warn(it) { "Failed to check for server updates" }
|
||||||
@@ -26,4 +28,4 @@ class CheckUpdate @Inject constructor(private val settingsRepository: SettingsRe
|
|||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,27 +13,42 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetFilterList @Inject constructor(private val sourceRepository: SourceRepository) {
|
class GetFilterList
|
||||||
|
@Inject
|
||||||
suspend fun await(source: Source, reset: Boolean, onError: suspend (Throwable) -> Unit = {}) = asFlow(source.id, reset)
|
constructor(private val sourceRepository: SourceRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
source: Source,
|
||||||
|
reset: Boolean,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(source.id, reset)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to get filter list for ${source.displayName} with reset = $reset" }
|
log.warn(it) { "Failed to get filter list for ${source.displayName} with reset = $reset" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(sourceId: Long, reset: Boolean, onError: suspend (Throwable) -> Unit = {}) = asFlow(sourceId, reset)
|
suspend fun await(
|
||||||
|
sourceId: Long,
|
||||||
|
reset: Boolean,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(sourceId, reset)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to get filter list for $sourceId with reset = $reset" }
|
log.warn(it) { "Failed to get filter list for $sourceId with reset = $reset" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(source: Source, reset: Boolean) = sourceRepository.getFilterList(source.id, reset)
|
fun asFlow(
|
||||||
|
source: Source,
|
||||||
|
reset: Boolean,
|
||||||
|
) = sourceRepository.getFilterList(source.id, reset)
|
||||||
|
|
||||||
fun asFlow(sourceId: Long, reset: Boolean) = sourceRepository.getFilterList(sourceId, reset)
|
fun asFlow(
|
||||||
|
sourceId: Long,
|
||||||
|
reset: Boolean,
|
||||||
|
) = sourceRepository.getFilterList(sourceId, reset)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,27 +13,42 @@ import kotlinx.coroutines.flow.singleOrNull
|
|||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class GetLatestManga @Inject constructor(private val sourceRepository: SourceRepository) {
|
class GetLatestManga
|
||||||
|
@Inject
|
||||||
suspend fun await(source: Source, page: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(source.id, page)
|
constructor(private val sourceRepository: SourceRepository) {
|
||||||
|
suspend fun await(
|
||||||
|
source: Source,
|
||||||
|
page: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(source.id, page)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to get latest manga from ${source.displayName} on page $page" }
|
log.warn(it) { "Failed to get latest manga from ${source.displayName} on page $page" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
suspend fun await(sourceId: Long, page: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(sourceId, page)
|
suspend fun await(
|
||||||
|
sourceId: Long,
|
||||||
|
page: Int,
|
||||||
|
onError: suspend (Throwable) -> Unit = {},
|
||||||
|
) = asFlow(sourceId, page)
|
||||||
.catch {
|
.catch {
|
||||||
onError(it)
|
onError(it)
|
||||||
log.warn(it) { "Failed to get latest manga from $sourceId on page $page" }
|
log.warn(it) { "Failed to get latest manga from $sourceId on page $page" }
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
|
|
||||||
fun asFlow(source: Source, page: Int) = sourceRepository.getLatestManga(source.id, page)
|
fun asFlow(
|
||||||
|
source: Source,
|
||||||
|
page: Int,
|
||||||
|
) = sourceRepository.getLatestManga(source.id, page)
|
||||||
|
|
||||||
fun asFlow(sourceId: Long, page: Int) = sourceRepository.getLatestManga(sourceId, page)
|
fun asFlow(
|
||||||
|
sourceId: Long,
|
||||||
|
page: Int,
|
||||||
|
) = sourceRepository.getLatestManga(sourceId, page)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logging()
|
private val log = logging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user