From b93c96a85be9e935b1829238ddd970cd60f98539 Mon Sep 17 00:00:00 2001 From: Syer10 Date: Fri, 29 Mar 2024 00:16:52 +0000 Subject: [PATCH] Automatic Lint --- .../ca/gosyer/jui/android/ReaderActivity.kt | 5 +- .../data/download/AndroidDownloadService.kt | 10 ++-- .../data/library/AndroidLibraryService.kt | 10 ++-- .../gosyer/jui/core/lang/PriorityChannel.kt | 2 + .../gosyer/jui/core/prefs/StandardAdapters.kt | 52 +++++-------------- .../jui/core/prefs/StandardPreferenceStore.kt | 24 +++------ .../ca/gosyer/jui/core/util/ImageUtil.kt | 5 +- .../gosyer/jui/data/FlowConverterFactory.kt | 5 +- .../ca/gosyer/jui/data/base/IosDateHandler.kt | 1 + .../ca/gosyer/jui/data/base/JvmDateHandler.kt | 1 + .../main/kotlin/ca/gosyer/jui/desktop/main.kt | 5 ++ .../ca/gosyer/jui/domain/server/HttpClient.kt | 4 ++ .../domain/updates/interactor/UpdatesPager.kt | 1 + .../domain/server/service/ServerService.kt | 10 ++-- .../service/host/ServerHostPreference.kt | 4 +- .../ui/base/chapter/ChapterDownloadButtons.kt | 5 ++ .../jui/ui/base/image/ImageLoaderProvider.kt | 5 +- .../jui/ui/base/navigation/ActionMenu.kt | 5 ++ .../jui/ui/base/prefs/ColorPickerDialog.kt | 16 ++++-- .../jui/ui/base/state/SavedStateHandleFlow.kt | 9 ++-- .../ca/gosyer/jui/ui/base/theme/AppTheme.kt | 7 +-- .../components/ExtensionsScreenContent.kt | 1 + .../jui/ui/library/LibraryScreenViewModel.kt | 26 ++++++---- .../jui/ui/library/components/LibraryPager.kt | 6 +++ .../components/LibraryScreenContent.kt | 5 ++ .../ui/main/about/components/AboutContent.kt | 2 + .../ui/main/components/DownloadsExtraInfo.kt | 2 + .../components/LibraryUpdatesExtraInfo.kt | 2 + .../ca/gosyer/jui/ui/reader/ReaderMenu.kt | 4 ++ .../jui/ui/reader/ReaderMenuViewModel.kt | 6 +++ .../ui/reader/loader/TachideskPageLoader.kt | 5 +- .../gosyer/jui/ui/reader/viewer/Continuous.kt | 3 ++ .../ca/gosyer/jui/ui/reader/viewer/Pager.kt | 2 + .../jui/ui/settings/SettingsBackupScreen.kt | 2 + .../jui/ui/settings/SettingsServerScreen.kt | 2 + .../sources/browse/SourceScreenViewModel.kt | 2 + .../browse/components/SourceScreenContent.kt | 4 ++ .../jui/ui/sources/components/SourcesMenu.kt | 2 + .../components/GlobalSearchScreenContent.kt | 2 + .../components/SourceHomeScreenContent.kt | 2 + .../components/SourceSettingsScreenContent.kt | 3 ++ .../components/UpdatesScreenContent.kt | 1 + .../gosyer/jui/ui/util/lang/StringFormat.kt | 10 ++++ .../jui/uicore/components/AndroidScrollbar.kt | 25 ++++----- .../jui/uicore/image/ImageLoaderImage.kt | 5 ++ .../ca/gosyer/jui/uicore/pager/Pager.kt | 6 +-- .../jui/uicore/components/IosScrollbar.kt | 25 ++++----- .../jui/uicore/resources/IosImageResource.kt | 8 +-- 48 files changed, 204 insertions(+), 145 deletions(-) diff --git a/android/src/main/kotlin/ca/gosyer/jui/android/ReaderActivity.kt b/android/src/main/kotlin/ca/gosyer/jui/android/ReaderActivity.kt index 5d8da2327..e63e4ce13 100644 --- a/android/src/main/kotlin/ca/gosyer/jui/android/ReaderActivity.kt +++ b/android/src/main/kotlin/ca/gosyer/jui/android/ReaderActivity.kt @@ -21,13 +21,12 @@ class ReaderActivity : AppCompatActivity() { context: Context, mangaId: Long, chapterIndex: Int, - ): Intent { - return Intent(context, ReaderActivity::class.java).apply { + ): Intent = + Intent(context, ReaderActivity::class.java).apply { putExtra("manga", mangaId) putExtra("chapter", chapterIndex) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) } - } } override fun onCreate(savedInstanceState: Bundle?) { diff --git a/android/src/main/kotlin/ca/gosyer/jui/android/data/download/AndroidDownloadService.kt b/android/src/main/kotlin/ca/gosyer/jui/android/data/download/AndroidDownloadService.kt index 600b518a9..ead56026e 100644 --- a/android/src/main/kotlin/ca/gosyer/jui/android/data/download/AndroidDownloadService.kt +++ b/android/src/main/kotlin/ca/gosyer/jui/android/data/download/AndroidDownloadService.kt @@ -74,9 +74,7 @@ class AndroidDownloadService : Service() { context.stopService(Intent(context, AndroidDownloadService::class.java)) } - fun isRunning(): Boolean { - return instance != null - } + fun isRunning(): Boolean = instance != null private val json = Json { ignoreUnknownKeys = true @@ -87,9 +85,7 @@ class AndroidDownloadService : Service() { private lateinit var ioScope: CoroutineScope - override fun onBind(intent: Intent): IBinder? { - return null - } + override fun onBind(intent: Intent): IBinder? = null override fun onCreate() { super.onCreate() @@ -123,7 +119,9 @@ class AndroidDownloadService : Service() { Actions.START.name, Actions.RESTART.name, -> startWebsocket() + Actions.STOP.name -> stopSelf() + else -> log.info { "This should never happen. No action in the received intent" } } } else { diff --git a/android/src/main/kotlin/ca/gosyer/jui/android/data/library/AndroidLibraryService.kt b/android/src/main/kotlin/ca/gosyer/jui/android/data/library/AndroidLibraryService.kt index b0ada0ad7..fdbe33d87 100644 --- a/android/src/main/kotlin/ca/gosyer/jui/android/data/library/AndroidLibraryService.kt +++ b/android/src/main/kotlin/ca/gosyer/jui/android/data/library/AndroidLibraryService.kt @@ -73,9 +73,7 @@ class AndroidLibraryService : Service() { context.stopService(Intent(context, AndroidLibraryService::class.java)) } - fun isRunning(): Boolean { - return instance != null - } + fun isRunning(): Boolean = instance != null private val json = Json { ignoreUnknownKeys = true @@ -86,9 +84,7 @@ class AndroidLibraryService : Service() { private lateinit var ioScope: CoroutineScope - override fun onBind(intent: Intent): IBinder? { - return null - } + override fun onBind(intent: Intent): IBinder? = null override fun onCreate() { super.onCreate() @@ -122,7 +118,9 @@ class AndroidLibraryService : Service() { Actions.START.name, Actions.RESTART.name, -> startWebsocket() + Actions.STOP.name -> stopSelf() + else -> log.info { "This should never happen. No action in the received intent" } } } else { diff --git a/core/src/commonMain/kotlin/ca/gosyer/jui/core/lang/PriorityChannel.kt b/core/src/commonMain/kotlin/ca/gosyer/jui/core/lang/PriorityChannel.kt index 94ddc7216..fcb5cfc89 100644 --- a/core/src/commonMain/kotlin/ca/gosyer/jui/core/lang/PriorityChannel.kt +++ b/core/src/commonMain/kotlin/ca/gosyer/jui/core/lang/PriorityChannel.kt @@ -152,9 +152,11 @@ internal class PriorityChannelImpl( yield() buffer.add(inChannel.receive()) } + buffer.isFull() -> { outChannel.send(buffer.removeHead()) } + else -> { while (buffer.isNotEmpty() && outChannel.trySend(buffer.head).isSuccess) { buffer.removeHead() diff --git a/core/src/commonMain/kotlin/ca/gosyer/jui/core/prefs/StandardAdapters.kt b/core/src/commonMain/kotlin/ca/gosyer/jui/core/prefs/StandardAdapters.kt index 3aa3419aa..5fb91cd2f 100644 --- a/core/src/commonMain/kotlin/ca/gosyer/jui/core/prefs/StandardAdapters.kt +++ b/core/src/commonMain/kotlin/ca/gosyer/jui/core/prefs/StandardAdapters.kt @@ -60,18 +60,14 @@ internal object StringAdapter : Adapter { key: String, preferences: ObservableSettings, callback: () -> Unit, - ): SettingsListener { - return preferences.addStringOrNullListener(key) { callback() } - } + ): SettingsListener = preferences.addStringOrNullListener(key) { callback() } } internal object LongAdapter : Adapter { override fun get( key: String, preferences: ObservableSettings, - ): Long { - return preferences.getLong(key, 0) - } + ): Long = preferences.getLong(key, 0) override fun set( key: String, @@ -85,18 +81,14 @@ internal object LongAdapter : Adapter { key: String, preferences: ObservableSettings, callback: () -> Unit, - ): SettingsListener { - return preferences.addLongOrNullListener(key) { callback() } - } + ): SettingsListener = preferences.addLongOrNullListener(key) { callback() } } internal object IntAdapter : Adapter { override fun get( key: String, preferences: ObservableSettings, - ): Int { - return preferences.getInt(key, 0) - } + ): Int = preferences.getInt(key, 0) override fun set( key: String, @@ -110,18 +102,14 @@ internal object IntAdapter : Adapter { key: String, preferences: ObservableSettings, callback: () -> Unit, - ): SettingsListener { - return preferences.addIntOrNullListener(key) { callback() } - } + ): SettingsListener = preferences.addIntOrNullListener(key) { callback() } } internal object FloatAdapter : Adapter { override fun get( key: String, preferences: ObservableSettings, - ): Float { - return preferences.getFloat(key, 0f) - } + ): Float = preferences.getFloat(key, 0f) override fun set( key: String, @@ -135,18 +123,14 @@ internal object FloatAdapter : Adapter { key: String, preferences: ObservableSettings, callback: () -> Unit, - ): SettingsListener { - return preferences.addFloatOrNullListener(key) { callback() } - } + ): SettingsListener = preferences.addFloatOrNullListener(key) { callback() } } internal object BooleanAdapter : Adapter { override fun get( key: String, preferences: ObservableSettings, - ): Boolean { - return preferences.getBoolean(key, false) - } + ): Boolean = preferences.getBoolean(key, false) override fun set( key: String, @@ -160,9 +144,7 @@ internal object BooleanAdapter : Adapter { key: String, preferences: ObservableSettings, callback: () -> Unit, - ): SettingsListener { - return preferences.addBooleanOrNullListener(key) { callback() } - } + ): SettingsListener = preferences.addBooleanOrNullListener(key) { callback() } } internal object StringSetAdapter : Adapter> { @@ -189,9 +171,7 @@ internal object StringSetAdapter : Adapter> { override fun isSet( keys: Set, key: String, - ): Boolean { - return keys.contains("$key.size") - } + ): Boolean = keys.contains("$key.size") /** * Watching the regular key doesn't produce updates for a string set for some reason @@ -201,9 +181,7 @@ internal object StringSetAdapter : Adapter> { key: String, preferences: ObservableSettings, callback: () -> Unit, - ): SettingsListener { - return preferences.addIntOrNullListener("$key.size") { callback() } - } + ): SettingsListener = preferences.addIntOrNullListener("$key.size") { callback() } } internal class ObjectAdapter( @@ -229,9 +207,7 @@ internal class ObjectAdapter( key: String, preferences: ObservableSettings, callback: () -> Unit, - ): SettingsListener { - return preferences.addStringOrNullListener(key) { callback() } - } + ): SettingsListener = preferences.addStringOrNullListener(key) { callback() } } internal class JsonObjectAdapter( @@ -261,9 +237,7 @@ internal class JsonObjectAdapter( override fun isSet( keys: Set, key: String, - ): Boolean { - return keys.any { it.startsWith(key) } - } + ): Boolean = keys.any { it.startsWith(key) } /** * Todo doesn't work diff --git a/core/src/commonMain/kotlin/ca/gosyer/jui/core/prefs/StandardPreferenceStore.kt b/core/src/commonMain/kotlin/ca/gosyer/jui/core/prefs/StandardPreferenceStore.kt index 2394de288..a0e4529fd 100644 --- a/core/src/commonMain/kotlin/ca/gosyer/jui/core/prefs/StandardPreferenceStore.kt +++ b/core/src/commonMain/kotlin/ca/gosyer/jui/core/prefs/StandardPreferenceStore.kt @@ -19,9 +19,7 @@ class StandardPreferenceStore( override fun getString( key: String, defaultValue: String, - ): Preference { - return StandardPreference(preferences, key, defaultValue, StringAdapter) - } + ): Preference = StandardPreference(preferences, key, defaultValue, StringAdapter) /** * Returns a [Long] preference for this [key]. @@ -29,9 +27,7 @@ class StandardPreferenceStore( override fun getLong( key: String, defaultValue: Long, - ): Preference { - return StandardPreference(preferences, key, defaultValue, LongAdapter) - } + ): Preference = StandardPreference(preferences, key, defaultValue, LongAdapter) /** * Returns an [Int] preference for this [key]. @@ -39,9 +35,7 @@ class StandardPreferenceStore( override fun getInt( key: String, defaultValue: Int, - ): Preference { - return StandardPreference(preferences, key, defaultValue, IntAdapter) - } + ): Preference = StandardPreference(preferences, key, defaultValue, IntAdapter) /** * Returns a [Float] preference for this [key]. @@ -49,9 +43,7 @@ class StandardPreferenceStore( override fun getFloat( key: String, defaultValue: Float, - ): Preference { - return StandardPreference(preferences, key, defaultValue, FloatAdapter) - } + ): Preference = StandardPreference(preferences, key, defaultValue, FloatAdapter) /** * Returns a [Boolean] preference for this [key]. @@ -59,9 +51,7 @@ class StandardPreferenceStore( override fun getBoolean( key: String, defaultValue: Boolean, - ): Preference { - return StandardPreference(preferences, key, defaultValue, BooleanAdapter) - } + ): Preference = StandardPreference(preferences, key, defaultValue, BooleanAdapter) /** * Returns a [Set] preference for this [key]. @@ -69,9 +59,7 @@ class StandardPreferenceStore( override fun getStringSet( key: String, defaultValue: Set, - ): Preference> { - return StandardPreference(preferences, key, defaultValue, StringSetAdapter) - } + ): Preference> = StandardPreference(preferences, key, defaultValue, StringSetAdapter) /** * Returns preference of type [T] for this [key]. The [serializer] and [deserializer] function diff --git a/core/src/commonMain/kotlin/ca/gosyer/jui/core/util/ImageUtil.kt b/core/src/commonMain/kotlin/ca/gosyer/jui/core/util/ImageUtil.kt index be225b444..84e29f377 100644 --- a/core/src/commonMain/kotlin/ca/gosyer/jui/core/util/ImageUtil.kt +++ b/core/src/commonMain/kotlin/ca/gosyer/jui/core/util/ImageUtil.kt @@ -14,15 +14,14 @@ object ImageUtil { private val gifMagic = "GIF8".toByteArray() private val webpMagic = "RIFF".toByteArray() - fun findType(bytes: ByteArray): ImageType? { - return when { + fun findType(bytes: ByteArray): ImageType? = + when { bytes.compareWith(jpgMagic) -> ImageType.JPG bytes.compareWith(pngMagic) -> ImageType.PNG bytes.compareWith(gifMagic) -> ImageType.GIF bytes.compareWith(webpMagic) -> ImageType.WEBP else -> null } - } private fun ByteArray.compareWith(magic: ByteArray): Boolean { for (i in magic.indices) { diff --git a/data/src/commonMain/kotlin/ca/gosyer/jui/data/FlowConverterFactory.kt b/data/src/commonMain/kotlin/ca/gosyer/jui/data/FlowConverterFactory.kt index 6289557ee..2071cbfe1 100644 --- a/data/src/commonMain/kotlin/ca/gosyer/jui/data/FlowConverterFactory.kt +++ b/data/src/commonMain/kotlin/ca/gosyer/jui/data/FlowConverterFactory.kt @@ -22,8 +22,8 @@ class FlowConverterFactory : Converter.Factory { val typeData: TypeData, val ktorfit: Ktorfit, ) : Converter.ResponseConverter> { - override fun convert(getResponse: suspend () -> HttpResponse): Flow { - return flow { + override fun convert(getResponse: suspend () -> HttpResponse): Flow = + flow { val response = getResponse() val convertedBody = ktorfit.nextSuspendResponseConverter( @@ -33,7 +33,6 @@ class FlowConverterFactory : Converter.Factory { ?: response.body(typeData.typeArgs.first().typeInfo) emit(convertedBody) }.flowOn(Dispatchers.IO) - } } override fun responseConverter( diff --git a/data/src/iosMain/kotlin/ca/gosyer/jui/data/base/IosDateHandler.kt b/data/src/iosMain/kotlin/ca/gosyer/jui/data/base/IosDateHandler.kt index 13e367d03..db09671f2 100644 --- a/data/src/iosMain/kotlin/ca/gosyer/jui/data/base/IosDateHandler.kt +++ b/data/src/iosMain/kotlin/ca/gosyer/jui/data/base/IosDateHandler.kt @@ -35,6 +35,7 @@ actual class DateHandler setTimeStyle(NSDateFormatterNoStyle) setLocale(Locale.current.toPlatform()) } + else -> NSDateFormatter() .apply { setDateFormat(format) diff --git a/data/src/jvmMain/kotlin/ca/gosyer/jui/data/base/JvmDateHandler.kt b/data/src/jvmMain/kotlin/ca/gosyer/jui/data/base/JvmDateHandler.kt index e4ee2f367..8118d2377 100644 --- a/data/src/jvmMain/kotlin/ca/gosyer/jui/data/base/JvmDateHandler.kt +++ b/data/src/jvmMain/kotlin/ca/gosyer/jui/data/base/JvmDateHandler.kt @@ -32,6 +32,7 @@ actual class DateHandler "" -> DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT) .withLocale(Locale.current.toPlatform()) .withZone(ZoneId.systemDefault()) + else -> DateTimeFormatter.ofPattern(format) .withZone(ZoneId.systemDefault()) }.let { formatter -> diff --git a/desktop/src/main/kotlin/ca/gosyer/jui/desktop/main.kt b/desktop/src/main/kotlin/ca/gosyer/jui/desktop/main.kt index a5c3c7776..90280ac01 100644 --- a/desktop/src/main/kotlin/ca/gosyer/jui/desktop/main.kt +++ b/desktop/src/main/kotlin/ca/gosyer/jui/desktop/main.kt @@ -130,7 +130,9 @@ suspend fun main() { SystemTheme.LIGHT, SystemTheme.UNKNOWN -> IntelliJTheme() SystemTheme.DARK -> DarculaTheme() } + ThemeMode.Light -> IntelliJTheme() + ThemeMode.Dark -> DarculaTheme() } withUIContext { @@ -188,10 +190,12 @@ suspend fun main() { // backPressHandler.handle() false } + Key.F3 -> { displayDebugInfoFlow.value = !displayDebugInfoFlow.value true } + else -> false } } else { @@ -220,6 +224,7 @@ suspend fun main() { ) } } + ServerResult.STARTING, ServerResult.FAILED -> { Surface { LoadingScreen( diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/server/HttpClient.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/server/HttpClient.kt index b20022c5b..fedd319a2 100644 --- a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/server/HttpClient.kt +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/server/HttpClient.kt @@ -57,12 +57,14 @@ fun httpClient( engine { proxy = when (serverPreferences.proxy().get()) { Proxy.NO_PROXY -> null + Proxy.HTTP_PROXY -> ProxyBuilder.http( URLBuilder( host = serverPreferences.proxyHttpHost().get(), port = serverPreferences.proxyHttpPort().get(), ).build(), ) + Proxy.SOCKS_PROXY -> ProxyBuilder.socks( serverPreferences.proxySocksHost().get(), serverPreferences.proxySocksPort().get(), @@ -71,6 +73,7 @@ fun httpClient( } when (serverPreferences.auth().get()) { Auth.NONE -> Unit + Auth.BASIC -> AuthPlugin { basic { sendWithoutRequest { @@ -84,6 +87,7 @@ fun httpClient( } } } + Auth.DIGEST -> AuthPlugin { digest { credentials { diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/updates/interactor/UpdatesPager.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/updates/interactor/UpdatesPager.kt index 1d6ecb68b..0afed9a90 100644 --- a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/updates/interactor/UpdatesPager.kt +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/updates/interactor/UpdatesPager.kt @@ -143,6 +143,7 @@ class UpdatesPager updates.map { when (it) { is Updates.Date -> it + is Updates.Update -> it.copy( manga = changedManga[it.manga.id] ?: it.manga, chapter = changedChapters[it.chapter.id] ?: it.chapter, diff --git a/domain/src/desktopMain/kotlin/ca/gosyer/jui/domain/server/service/ServerService.kt b/domain/src/desktopMain/kotlin/ca/gosyer/jui/domain/server/service/ServerService.kt index df340039b..81b7ee0ff 100644 --- a/domain/src/desktopMain/kotlin/ca/gosyer/jui/domain/server/service/ServerService.kt +++ b/domain/src/desktopMain/kotlin/ca/gosyer/jui/domain/server/service/ServerService.kt @@ -77,12 +77,10 @@ class ServerService } } - private fun getRuntimeJava(): String? { - return System.getProperty("java.home")?.let { getJavaFromPath(it.toPath().resolve("bin")) } - } + private fun getRuntimeJava(): String? = System.getProperty("java.home")?.let { getJavaFromPath(it.toPath().resolve("bin")) } - private fun getPossibleJava(): String? { - return System.getProperty("java.library.path")?.split(pathSeparatorChar) + private fun getPossibleJava(): String? = + System.getProperty("java.library.path")?.split(pathSeparatorChar) .orEmpty() .asSequence() .mapNotNull { @@ -99,7 +97,6 @@ class ServerService } .mapNotNull { getJavaFromPath(it) } .firstOrNull() - } private suspend fun runService() { process?.destroy() @@ -154,6 +151,7 @@ class ServerService when { it.contains("Javalin started") -> _initialized.value = ServerResult.STARTED + it.contains("Javalin has stopped") -> _initialized.value = ServerResult.FAILED } diff --git a/domain/src/desktopMain/kotlin/ca/gosyer/jui/domain/server/service/host/ServerHostPreference.kt b/domain/src/desktopMain/kotlin/ca/gosyer/jui/domain/server/service/host/ServerHostPreference.kt index 0c48e551a..a1dc1ff64 100644 --- a/domain/src/desktopMain/kotlin/ca/gosyer/jui/domain/server/service/host/ServerHostPreference.kt +++ b/domain/src/desktopMain/kotlin/ca/gosyer/jui/domain/server/service/host/ServerHostPreference.kt @@ -17,9 +17,7 @@ sealed class ServerHostPreference { protected abstract val defaultValue: T protected abstract val serverValue: T - private fun validate(value: T): Boolean { - return value != serverValue - } + private fun validate(value: T): Boolean = value != serverValue fun getProperty(): String? { val preference = preference().get().takeIf(::validate) diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt index 281114afe..be5af43da 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt @@ -117,12 +117,14 @@ fun ChapterDownloadIcon( onClick = { onClickDelete(chapter.chapter) }, ) } + ChapterDownloadState.Downloading -> { DownloadingIconButton( downloadChapter, onClick = { onClickStop(chapter.chapter) }, ) } + ChapterDownloadState.NotDownloaded -> { DownloadIconButton(onClick = { onClickDownload(chapter.chapter) }) } @@ -172,6 +174,7 @@ private fun DownloadingIconButton( LocalContentColor.current.copy(alpha = ContentAlpha.disabled), 2.dp, ) + DownloadState.Downloading -> if (downloadChapter.progress != 0.0F) { val animatedProgress by animateFloatAsState( targetValue = downloadChapter.progress, @@ -202,6 +205,7 @@ private fun DownloadingIconButton( 2.dp, ) } + DownloadState.Error -> Surface(shape = CircleShape, color = LocalContentColor.current) { Icon( Icons.Rounded.Error, @@ -212,6 +216,7 @@ private fun DownloadingIconButton( Color.Red, ) } + DownloadState.Finished -> Surface(shape = CircleShape, color = LocalContentColor.current) { Icon( Icons.Rounded.Check, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/image/ImageLoaderProvider.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/image/ImageLoaderProvider.kt index 087bf835e..43c961a00 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/image/ImageLoaderProvider.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/image/ImageLoaderProvider.kt @@ -40,8 +40,8 @@ class ImageLoaderProvider @OptIn(DelicateCoroutinesApi::class) val serverUrl = serverPreferences.serverUrl().stateIn(GlobalScope) - fun get(imageCache: ImageCache): ImageLoader { - return ImageLoader { + fun get(imageCache: ImageCache): ImageLoader = + ImageLoader { components { register(context, http) add(MokoResourceFetcher.Factory()) @@ -60,7 +60,6 @@ class ImageLoaderProvider bitmapMemoryCacheConfig { configure(context) } } } - } inner class MangaCoverMapper : Mapper { override fun map( diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/navigation/ActionMenu.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/navigation/ActionMenu.kt index 0d644059c..4a2c8bb24 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/navigation/ActionMenu.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/navigation/ActionMenu.kt @@ -103,6 +103,7 @@ fun ActionMenu( is ActionGroup -> { { openGroup = item } } + is ActionItem -> item.doAction }, enabled = item.enabled, @@ -158,6 +159,7 @@ fun ActionMenu( onClick = { when (item) { is ActionGroup -> openGroup = item + is ActionItem -> { openGroup = null item() @@ -200,9 +202,11 @@ private fun separateIntoIconAndOverflow( OverflowMode.NEVER_OVERFLOW -> { iconActions.add(item) } + OverflowMode.ALWAYS_OVERFLOW -> { overflowActions.add(item) } + OverflowMode.IF_NECESSARY -> { if (iconsAvailableBeforeOverflow > 0) { iconActions.add(item) @@ -211,6 +215,7 @@ private fun separateIntoIconAndOverflow( overflowActions.add(item) } } + OverflowMode.NOT_SHOWN -> { // skip } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/prefs/ColorPickerDialog.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/prefs/ColorPickerDialog.kt index 9a0de8ded..fcf58e4a7 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/prefs/ColorPickerDialog.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/prefs/ColorPickerDialog.kt @@ -208,10 +208,18 @@ private fun ColorPresetItem( private fun getColorShades(color: Color): ImmutableList { val f = color.toLong() return listOf( - shadeColor(f, 0.9), shadeColor(f, 0.7), shadeColor(f, 0.5), - shadeColor(f, 0.333), shadeColor(f, 0.166), shadeColor(f, -0.125), - shadeColor(f, -0.25), shadeColor(f, -0.375), shadeColor(f, -0.5), - shadeColor(f, -0.675), shadeColor(f, -0.7), shadeColor(f, -0.775), + shadeColor(f, 0.9), + shadeColor(f, 0.7), + shadeColor(f, 0.5), + shadeColor(f, 0.333), + shadeColor(f, 0.166), + shadeColor(f, -0.125), + shadeColor(f, -0.25), + shadeColor(f, -0.375), + shadeColor(f, -0.5), + shadeColor(f, -0.675), + shadeColor(f, -0.7), + shadeColor(f, -0.775), ).toImmutableList() } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/state/SavedStateHandleFlow.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/state/SavedStateHandleFlow.kt index 5fc57f3e1..d5b71eb4e 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/state/SavedStateHandleFlow.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/state/SavedStateHandleFlow.kt @@ -14,9 +14,7 @@ import kotlinx.coroutines.internal.synchronized import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty -fun SavedStateHandle.getStateFlow(initialValue: () -> T): SavedStateHandleDelegate { - return SavedStateHandleDelegate(this, initialValue) -} +fun SavedStateHandle.getStateFlow(initialValue: () -> T): SavedStateHandleDelegate = SavedStateHandleDelegate(this, initialValue) @OptIn(InternalCoroutinesApi::class) class SavedStateHandleDelegate( @@ -30,8 +28,8 @@ class SavedStateHandleDelegate( override fun getValue( thisRef: ViewModel, property: KProperty<*>, - ): SavedStateHandleStateFlow { - return item ?: synchronized(synchronizedObject) { + ): SavedStateHandleStateFlow = + item ?: synchronized(synchronizedObject) { if (item == null) { savedStateHandle.getSavedStateFlow(property.name, initialValue) .also { item = it } @@ -39,7 +37,6 @@ class SavedStateHandleDelegate( item!! } } - } } class SavedStateHandleStateFlow( diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/theme/AppTheme.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/theme/AppTheme.kt index ce9bbc430..426babed7 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/theme/AppTheme.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/theme/AppTheme.kt @@ -107,10 +107,9 @@ class AppThemeViewModel fun getTheme( id: Int, isLight: Boolean, - ): Theme { - return themes.find { it.id == id && it.colors.isLight == isLight } + ): Theme = + themes.find { it.id == id && it.colors.isLight == isLight } ?: themes.first { it.colors.isLight == isLight } - } return when (themeMode) { ThemeMode.System -> if (!isSystemInDarkTheme()) { @@ -118,7 +117,9 @@ class AppThemeViewModel } else { getTheme(darkTheme, false) } + ThemeMode.Light -> getTheme(lightTheme, true) + ThemeMode.Dark -> getTheme(darkTheme, false) } } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/extensions/components/ExtensionsScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/extensions/components/ExtensionsScreenContent.kt index 02fd4468d..3b04c16e5 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/extensions/components/ExtensionsScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/extensions/components/ExtensionsScreenContent.kt @@ -148,6 +148,7 @@ fun ExtensionsScreenContent( modifier = Modifier.animateItemPlacement() .padding(16.dp, 16.dp, 16.dp, 4.dp), ) + is ExtensionUI.ExtensionItem -> Column { ExtensionItem( Modifier.animateItemPlacement(), diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/LibraryScreenViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/LibraryScreenViewModel.kt index e53103776..0b60af30c 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/LibraryScreenViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/LibraryScreenViewModel.kt @@ -111,6 +111,7 @@ private fun LibraryMap.setManga( val flow = getManga(id) when (val state = flow.value) { is CategoryState.Loaded -> state.unfilteredItems.value = manga + else -> { val unfilteredItems = MutableStateFlow(manga) flow.value = CategoryState.Loaded(getItemsFlow(unfilteredItems), unfilteredItems) @@ -160,15 +161,17 @@ class LibraryScreenViewModel FilterState.EXCLUDED -> manga.downloadCount == null || manga.downloadCount == 0 FilterState.INCLUDED -> manga.downloadCount != null && (manga.downloadCount ?: 0) > 0 FilterState.IGNORED -> true - } && when (unread) { - FilterState.EXCLUDED -> manga.unreadCount == null || manga.unreadCount == 0 - FilterState.INCLUDED -> manga.unreadCount != null && (manga.unreadCount ?: 0) > 0 - FilterState.IGNORED -> true - } && when (completed) { - FilterState.EXCLUDED -> manga.status != MangaStatus.COMPLETED - FilterState.INCLUDED -> manga.status == MangaStatus.COMPLETED - FilterState.IGNORED -> true - } + } && + when (unread) { + FilterState.EXCLUDED -> manga.unreadCount == null || manga.unreadCount == 0 + FilterState.INCLUDED -> manga.unreadCount != null && (manga.unreadCount ?: 0) > 0 + FilterState.IGNORED -> true + } && + when (completed) { + FilterState.EXCLUDED -> manga.status != MangaStatus.COMPLETED + FilterState.INCLUDED -> manga.status == MangaStatus.COMPLETED + FilterState.IGNORED -> true + } } } @@ -238,17 +241,22 @@ class LibraryScreenViewModel collator.compare(a.title.toLowerCase(locale), b.title.toLowerCase(locale)) } } + Sort.UNREAD -> { { a, b -> when { // Ensure unread content comes first (a.unreadCount ?: 0) == (b.unreadCount ?: 0) -> 0 + a.unreadCount == null || a.unreadCount == 0 -> if (ascending) 1 else -1 + b.unreadCount == null || b.unreadCount == 0 -> if (ascending) -1 else 1 + else -> (a.unreadCount ?: 0).compareTo(b.unreadCount ?: 0) } } } + Sort.DATE_ADDED -> { { a, b -> a.inLibraryAt.compareTo(b.inLibraryAt) diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryPager.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryPager.kt index 328001e13..065edb811 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryPager.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryPager.kt @@ -40,7 +40,9 @@ fun LibraryPager( HorizontalPager(state = pagerState) { when (val library = getLibraryForPage(categories[it].id).value) { CategoryState.Loading -> LoadingScreen() + is CategoryState.Failed -> ErrorScreen(library.e.message) + is CategoryState.Loaded -> LibraryLoadedPage( library = library, displayMode = displayMode, @@ -83,6 +85,7 @@ private fun LibraryLoadedPage( showLanguage = showLanguage, showLocal = showLocal, ) + DisplayMode.ComfortableGrid -> LibraryMangaComfortableGrid( library = items, gridColumns = gridColumns, @@ -94,6 +97,7 @@ private fun LibraryLoadedPage( showLanguage = showLanguage, showLocal = showLocal, ) + DisplayMode.CoverOnlyGrid -> LibraryMangaCoverOnlyGrid( library = items, gridColumns = gridColumns, @@ -105,6 +109,7 @@ private fun LibraryLoadedPage( showLanguage = showLanguage, showLocal = showLocal, ) + DisplayMode.List -> LibraryMangaList( library = items, onClickManga = onClickManga, @@ -114,6 +119,7 @@ private fun LibraryLoadedPage( showLanguage = showLanguage, showLocal = showLocal, ) + else -> Box {} } } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryScreenContent.kt index b0450943e..65c6cdea2 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryScreenContent.kt @@ -220,9 +220,11 @@ fun WideLibraryScreenContent( is LibraryState.Failed -> { ErrorScreen(libraryState.e.message) } + LibraryState.Loading -> { LoadingScreen(true) } + is LibraryState.Loaded -> { LibraryPager( pagerState = pagerState, @@ -296,6 +298,7 @@ fun ThinLibraryScreenContent( confirmValueChange = { when (it) { ModalBottomSheetValue.Hidden -> setShowingSheet(false) + ModalBottomSheetValue.Expanded, ModalBottomSheetValue.HalfExpanded, -> setShowingSheet(true) @@ -359,9 +362,11 @@ fun ThinLibraryScreenContent( LibraryState.Loading -> { LoadingScreen(true) } + is LibraryState.Failed -> { ErrorScreen(libraryState.e.message) } + is LibraryState.Loaded -> { LibraryPager( pagerState = pagerState, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/components/AboutContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/components/AboutContent.kt index 670c8057d..b28316d0a 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/components/AboutContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/components/AboutContent.kt @@ -265,6 +265,7 @@ private fun LinkDisplay() { contentDescription = name, modifier = modifier, ) + is LinkIcon.Icon -> Icon( imageVector = it.icon.icon, contentDescription = name, @@ -288,6 +289,7 @@ private fun LinkDisplay() { contentDescription = name, modifier = Modifier.fillMaxSize(), ) + is LinkIcon.Icon -> Icon( imageVector = it.icon.icon, contentDescription = name, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/components/DownloadsExtraInfo.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/components/DownloadsExtraInfo.kt index 00dc737e4..76f68c183 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/components/DownloadsExtraInfo.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/components/DownloadsExtraInfo.kt @@ -39,6 +39,7 @@ fun DownloadsExtraInfo() { val list by vm.downloadQueue.collectAsState() val text = when (serviceStatus) { WebsocketService.Status.STARTING -> stringResource(MR.strings.downloads_loading) + WebsocketService.Status.RUNNING -> { if (list.isNotEmpty()) { val remainingDownloads = stringResource(MR.strings.downloads_remaining, list.size) @@ -51,6 +52,7 @@ fun DownloadsExtraInfo() { null } } + WebsocketService.Status.STOPPED -> null } if (!text.isNullOrBlank()) { diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/components/LibraryUpdatesExtraInfo.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/components/LibraryUpdatesExtraInfo.kt index 8d98dce85..f941d56f6 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/components/LibraryUpdatesExtraInfo.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/components/LibraryUpdatesExtraInfo.kt @@ -55,6 +55,7 @@ fun LibraryUpdatesExtraInfo() { val text = when (serviceStatus) { WebsocketService.Status.STARTING -> stringResource(MR.strings.downloads_loading) + WebsocketService.Status.RUNNING -> { if (updateStatus.running) { stringResource(MR.strings.notification_updating, current, total) @@ -62,6 +63,7 @@ fun LibraryUpdatesExtraInfo() { null } } + WebsocketService.Status.STOPPED -> null } if (!text.isNullOrBlank()) { diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/ReaderMenu.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/ReaderMenu.kt index 47adb0452..f322ef343 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/ReaderMenu.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/ReaderMenu.kt @@ -615,6 +615,7 @@ fun ChapterSeparator( previousChapter == null && nextChapter != null -> { Text(stringResource(MR.strings.no_previous_chapter)) } + previousChapter != null && nextChapter != null -> { val prevChapter by previousChapter.stateObserver.collectAsState() when (prevChapter) { @@ -624,6 +625,7 @@ fun ChapterSeparator( } CircularProgressIndicator() } + else -> Unit } Text(stringResource(MR.strings.previous_chapter, previousChapter.chapter.name)) @@ -637,9 +639,11 @@ fun ChapterSeparator( } CircularProgressIndicator() } + else -> Unit } } + previousChapter != null && nextChapter == null -> { Text(stringResource(MR.strings.no_next_chapter)) } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/ReaderMenuViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/ReaderMenuViewModel.kt index cb7f27781..e9d73a771 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/ReaderMenuViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/ReaderMenuViewModel.kt @@ -208,20 +208,26 @@ class ReaderMenuViewModel setReaderSettingsMenuOpen(!readerSettingsMenuOpen.value) null } + Navigation.NEXT -> MoveTo.Next + Navigation.PREV -> MoveTo.Previous + Navigation.RIGHT -> when (readerModeSettings.direction.value) { Direction.Left -> MoveTo.Previous else -> MoveTo.Next } + Navigation.LEFT -> when (readerModeSettings.direction.value) { Direction.Left -> MoveTo.Next else -> MoveTo.Previous } + Navigation.DOWN -> when (readerModeSettings.direction.value) { Direction.Up -> MoveTo.Previous else -> MoveTo.Next } + Navigation.UP -> when (readerModeSettings.direction.value) { Direction.Up -> MoveTo.Next else -> MoveTo.Previous diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/loader/TachideskPageLoader.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/loader/TachideskPageLoader.kt index 70aca2222..28c3d8c43 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/loader/TachideskPageLoader.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/loader/TachideskPageLoader.kt @@ -154,8 +154,8 @@ class TachideskPageLoader( } } - private suspend fun getImageFromCache(page: ReaderPage): ReaderPage.ImageDecodeState { - return chapterCache.openSnapshot(page.cacheKey)?.use { + private suspend fun getImageFromCache(page: ReaderPage): ReaderPage.ImageDecodeState = + chapterCache.openSnapshot(page.cacheKey)?.use { it.source().use { source -> val decoder = bitmapDecoderFactory.create( ImageResult.OfSource( @@ -183,7 +183,6 @@ class TachideskPageLoader( } } } ?: ReaderPage.ImageDecodeState.FailedToGetSnapShot - } /** * Preloads the given [amount] of pages after the [currentPage] with a lower priority. diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/viewer/Continuous.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/viewer/Continuous.kt index 8e58f1db4..395bd2df5 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/viewer/Continuous.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/viewer/Continuous.kt @@ -86,6 +86,7 @@ fun ContinuousReader( ) Unit } + is PageMove.Page -> { val pageNumber = pages.indexOf(pageMove.page) if (pageNumber > -1) { @@ -155,6 +156,7 @@ fun ContinuousReader( reverseLayout = direction == Direction.Up, ) } + false -> { LazyRow( state = state, @@ -217,6 +219,7 @@ private fun LazyListScope.items( retry = retry, ) } + is ReaderPageSeparator -> ChapterSeparator( previousChapter = image.previousChapter, nextChapter = image.nextChapter, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/viewer/Pager.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/viewer/Pager.kt index 90cfa644c..f717647db 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/viewer/Pager.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/reader/viewer/Pager.kt @@ -63,6 +63,7 @@ fun PagerReader( state.animateScrollToPage(page) } } + is PageMove.Page -> { val pageNumber = pages.indexOf(pageMove.page) if (pageNumber > -1) { @@ -158,6 +159,7 @@ fun HandlePager( contentScale = pageContentScale, ) } + is ReaderPageSeparator -> ChapterSeparator( previousChapter = image.previousChapter, nextChapter = image.nextChapter, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/settings/SettingsBackupScreen.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/settings/SettingsBackupScreen.kt index e35f4e731..8be51a15c 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/settings/SettingsBackupScreen.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/settings/SettingsBackupScreen.kt @@ -434,11 +434,13 @@ private fun PreferenceFile( modifier = modifier, tint = Color.Red, ) + Status.Success -> Icon( Icons.Rounded.Check, contentDescription = null, modifier = modifier, ) + else -> Unit } } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/settings/SettingsServerScreen.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/settings/SettingsServerScreen.kt index 7c8327476..53ff2a07a 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/settings/SettingsServerScreen.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/settings/SettingsServerScreen.kt @@ -210,6 +210,7 @@ fun SettingsServerScreenContent( } when (proxyValue) { Proxy.NO_PROXY -> Unit + Proxy.HTTP_PROXY -> { item { EditTextPreference( @@ -226,6 +227,7 @@ fun SettingsServerScreenContent( ) } } + Proxy.SOCKS_PROXY -> { item { EditTextPreference( diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreenViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreenViewModel.kt index 493abd6f6..da2212377 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreenViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreenViewModel.kt @@ -119,6 +119,7 @@ class SourceScreenViewModel( ) } } + isLatest.value -> { { page -> getLatestManga.await( @@ -128,6 +129,7 @@ class SourceScreenViewModel( ) } } + else -> { { page -> getPopularManga.await( diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceScreenContent.kt index 9f74155d2..d8914e36e 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceScreenContent.kt @@ -285,6 +285,7 @@ private fun SourceThinScreenContent( confirmValueChange = { when (it) { ModalBottomSheetValue.Hidden -> setShowingFilters(false) + ModalBottomSheetValue.Expanded, ModalBottomSheetValue.HalfExpanded, -> setShowingFilters(true) @@ -492,6 +493,7 @@ private fun MangaTable( hasNextPage = hasNextPage, onLoadNextPage = onLoadNextPage, ) + DisplayMode.ComfortableGrid -> SourceMangaComfortableGrid( mangas = mangas, gridColumns = gridColumns, @@ -500,12 +502,14 @@ private fun MangaTable( hasNextPage = hasNextPage, onLoadNextPage = onLoadNextPage, ) + DisplayMode.List -> SourceMangaList( mangas = mangas, onClickManga = onMangaClick, hasNextPage = hasNextPage, onLoadNextPage = onLoadNextPage, ) + else -> Box {} } } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/components/SourcesMenu.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/components/SourcesMenu.kt index 673e50508..ac4c2e815 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/components/SourcesMenu.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/components/SourcesMenu.kt @@ -155,11 +155,13 @@ fun SourcesSideMenu( contentDescription = stringResource(MR.strings.sources_home), modifier = modifier, ) + SourceNavigatorScreen.SearchScreen -> Icon( imageVector = Icons.Rounded.Search, contentDescription = stringResource(MR.strings.location_global_search), modifier = modifier, ) + is SourceNavigatorScreen.SourceScreen -> Box(Modifier.align(Alignment.Center)) { ImageLoaderImage( data = screen.source, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchScreenContent.kt index 06fe1a971..120cc2d5e 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchScreenContent.kt @@ -196,12 +196,14 @@ fun GlobalSearchItem( ) { ErrorScreen(search.e) } + Search.Searching -> Box( Modifier.fillMaxWidth().padding(vertical = 8.dp, horizontal = 16.dp), contentAlignment = Alignment.Center, ) { CircularProgressIndicator() } + is Search.Success -> Box( Modifier .fillMaxWidth() diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/home/components/SourceHomeScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/home/components/SourceHomeScreenContent.kt index e5bf0757a..a86cf678f 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/home/components/SourceHomeScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/home/components/SourceHomeScreenContent.kt @@ -185,6 +185,7 @@ fun WideSourcesMenu( sourceUI.header, modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp), ) + is SourceUI.SourceItem -> WideSourceItem( sourceUI, onSourceClicked = onAddSource, @@ -285,6 +286,7 @@ fun ThinSourcesMenu( sourceUI.header, modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp), ) + is SourceUI.SourceItem -> ThinSourceItem( sourceUI, onSourceClicked = onAddSource, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/components/SourceSettingsScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/components/SourceSettingsScreenContent.kt index e6a23463a..097f1a80a 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/components/SourceSettingsScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/components/SourceSettingsScreenContent.kt @@ -87,12 +87,15 @@ fun SourceSettingsScreenContent(settings: ImmutableList is CheckBox, is Switch -> { TwoStatePreference(it as TwoState, it is CheckBox) } + is List -> { ListPreference(it) } + is EditText -> { EditTextPreference(it) } + is MultiSelect -> { MultiSelectPreference(it) } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/updates/components/UpdatesScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/updates/components/UpdatesScreenContent.kt index 1f525de06..dc72974aa 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/updates/components/UpdatesScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/updates/components/UpdatesScreenContent.kt @@ -184,6 +184,7 @@ fun UpdatesScreenContent( modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), fontWeight = FontWeight.Medium, ) + is UpdatesUI.Item -> { val manga = item.chapterDownloadItem.manga!! val chapter = item.chapterDownloadItem.chapter diff --git a/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/util/lang/StringFormat.kt b/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/util/lang/StringFormat.kt index 4e1c8e85d..1dd9b8556 100644 --- a/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/util/lang/StringFormat.kt +++ b/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/util/lang/StringFormat.kt @@ -21,11 +21,17 @@ actual fun stringFormat( @Suppress("MagicNumber") return when (args.size) { 0 -> NSString.stringWithFormat(objcFormat) + 1 -> NSString.stringWithFormat(objcFormat, args[0]) + 2 -> NSString.stringWithFormat(objcFormat, args[0], args[1]) + 3 -> NSString.stringWithFormat(objcFormat, args[0], args[1], args[2]) + 4 -> NSString.stringWithFormat(objcFormat, args[0], args[1], args[2], args[3]) + 5 -> NSString.stringWithFormat(objcFormat, args[0], args[1], args[2], args[3], args[4]) + 6 -> NSString.stringWithFormat( objcFormat, args[0], @@ -35,6 +41,7 @@ actual fun stringFormat( args[4], args[5], ) + 7 -> NSString.stringWithFormat( objcFormat, args[0], @@ -45,6 +52,7 @@ actual fun stringFormat( args[5], args[6], ) + 8 -> NSString.stringWithFormat( objcFormat, args[0], @@ -56,6 +64,7 @@ actual fun stringFormat( args[6], args[7], ) + 9 -> NSString.stringWithFormat( objcFormat, args[0], @@ -68,6 +77,7 @@ actual fun stringFormat( args[7], args[8], ) + else -> throw IllegalArgumentException("can't handle more then 9 arguments now") } } diff --git a/ui-core/src/androidMain/kotlin/ca/gosyer/jui/uicore/components/AndroidScrollbar.kt b/ui-core/src/androidMain/kotlin/ca/gosyer/jui/uicore/components/AndroidScrollbar.kt index 3e5881d17..7e5e187ae 100644 --- a/ui-core/src/androidMain/kotlin/ca/gosyer/jui/uicore/components/AndroidScrollbar.kt +++ b/ui-core/src/androidMain/kotlin/ca/gosyer/jui/uicore/components/AndroidScrollbar.kt @@ -82,12 +82,15 @@ internal actual fun RealVerticalScrollbar( is ScrollStateScrollbarAdapter -> { Modifier.drawScrollbar(adapter.scrollState, Orientation.Vertical, reverseLayout) } + is LazyListStateScrollbarAdapter -> { Modifier.drawScrollbar(adapter.lazyListState, Orientation.Vertical, reverseLayout) } + is LazyGridStateScrollbarAdapter -> { Modifier.drawScrollbar(adapter.lazyGridState, adapter.gridCells, adapter.spacing, Orientation.Vertical, reverseLayout) } + else -> Modifier } Box(modifier then Modifier.fillMaxSize() then scrollbarModifier) @@ -105,49 +108,47 @@ internal actual fun RealHorizontalScrollbar( is ScrollStateScrollbarAdapter -> { Modifier.drawScrollbar(adapter.scrollState, Orientation.Horizontal, reverseLayout) } + is LazyListStateScrollbarAdapter -> { Modifier.drawScrollbar(adapter.lazyListState, Orientation.Horizontal, reverseLayout) } + else -> Modifier } Box(modifier then Modifier.fillMaxSize() then scrollbarModifier) } @Composable -actual fun rememberScrollbarAdapter(scrollState: ScrollState): ScrollbarAdapter { - return remember(scrollState) { +actual fun rememberScrollbarAdapter(scrollState: ScrollState): ScrollbarAdapter = + remember(scrollState) { ScrollStateScrollbarAdapter(scrollState) } -} @Composable -actual fun rememberScrollbarAdapter(scrollState: LazyListState): ScrollbarAdapter { - return remember(scrollState) { +actual fun rememberScrollbarAdapter(scrollState: LazyListState): ScrollbarAdapter = + remember(scrollState) { LazyListStateScrollbarAdapter(scrollState) } -} @Composable internal actual fun realRememberVerticalScrollbarAdapter( scrollState: LazyGridState, gridCells: GridCells, arrangement: Arrangement.Vertical?, -): ScrollbarAdapter { - return remember(scrollState, gridCells) { +): ScrollbarAdapter = + remember(scrollState, gridCells) { LazyGridStateScrollbarAdapter(scrollState, gridCells, arrangement?.spacing ?: Dp.Hairline) } -} @Composable internal actual fun realRememberHorizontalScrollbarAdapter( scrollState: LazyGridState, gridCells: GridCells, arrangement: Arrangement.Horizontal?, -): ScrollbarAdapter { - return remember(scrollState, gridCells) { +): ScrollbarAdapter = + remember(scrollState, gridCells) { LazyGridStateScrollbarAdapter(scrollState, gridCells, arrangement?.spacing ?: Dp.Hairline) } -} actual fun Modifier.scrollbarPadding() = this diff --git a/ui-core/src/commonMain/kotlin/ca/gosyer/jui/uicore/image/ImageLoaderImage.kt b/ui-core/src/commonMain/kotlin/ca/gosyer/jui/uicore/image/ImageLoaderImage.kt index 13357a6d5..e691f204b 100644 --- a/ui-core/src/commonMain/kotlin/ca/gosyer/jui/uicore/image/ImageLoaderImage.kt +++ b/ui-core/src/commonMain/kotlin/ca/gosyer/jui/uicore/image/ImageLoaderImage.kt @@ -98,14 +98,17 @@ fun ImageLoaderImage( error.value = action.error ImageLoaderImageState.Failure } + is ImageAction.Loading -> { progress.value = 0.0F ImageLoaderImageState.Loading } + is ImageAction.Success -> { progress.value = 1.0F ImageLoaderImageState.Success } + else -> { ImageLoaderImageState.Loading } @@ -117,6 +120,7 @@ fun ImageLoaderImage( ImageLoaderImageState.Loading -> if (onLoading != null) { onLoading(progress.value) } + ImageLoaderImageState.Success -> Image( painter = rememberImageActionPainter( imageAction, @@ -129,6 +133,7 @@ fun ImageLoaderImage( alpha = alpha, colorFilter = colorFilter, ) + ImageLoaderImageState.Failure -> { if (onFailure != null) { onFailure(error.value ?: return@Crossfade) diff --git a/ui-core/src/commonMain/kotlin/ca/gosyer/jui/uicore/pager/Pager.kt b/ui-core/src/commonMain/kotlin/ca/gosyer/jui/uicore/pager/Pager.kt index d96715466..0a3f17e26 100644 --- a/ui-core/src/commonMain/kotlin/ca/gosyer/jui/uicore/pager/Pager.kt +++ b/ui-core/src/commonMain/kotlin/ca/gosyer/jui/uicore/pager/Pager.kt @@ -300,9 +300,7 @@ private fun lazyListSnapLayoutInfoProvider( lowerBound: Float, upperBound: Float, ): Float { - fun Float.isValidDistance(): Boolean { - return this != Float.POSITIVE_INFINITY && this != Float.NEGATIVE_INFINITY - } + fun Float.isValidDistance(): Boolean = this != Float.POSITIVE_INFINITY && this != Float.NEGATIVE_INFINITY val finalDistance = when (sign(velocity)) { 0f -> { @@ -314,7 +312,9 @@ private fun lazyListSnapLayoutInfoProvider( } 1f -> upperBound + -1f -> lowerBound + else -> 0f } diff --git a/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/components/IosScrollbar.kt b/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/components/IosScrollbar.kt index 9192ba4d4..4b0fa64ad 100644 --- a/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/components/IosScrollbar.kt +++ b/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/components/IosScrollbar.kt @@ -81,12 +81,15 @@ internal actual fun RealVerticalScrollbar( is ScrollStateScrollbarAdapter -> { Modifier.drawScrollbar(adapter.scrollState, Orientation.Vertical, reverseLayout) } + is LazyListStateScrollbarAdapter -> { Modifier.drawScrollbar(adapter.lazyListState, Orientation.Vertical, reverseLayout) } + is LazyGridStateScrollbarAdapter -> { Modifier.drawScrollbar(adapter.lazyGridState, adapter.gridCells, adapter.spacing, Orientation.Vertical, reverseLayout) } + else -> Modifier } Box(modifier then Modifier.fillMaxSize() then scrollbarModifier) @@ -104,49 +107,47 @@ internal actual fun RealHorizontalScrollbar( is ScrollStateScrollbarAdapter -> { Modifier.drawScrollbar(adapter.scrollState, Orientation.Horizontal, reverseLayout) } + is LazyListStateScrollbarAdapter -> { Modifier.drawScrollbar(adapter.lazyListState, Orientation.Horizontal, reverseLayout) } + else -> Modifier } Box(modifier then Modifier.fillMaxSize() then scrollbarModifier) } @Composable -actual fun rememberScrollbarAdapter(scrollState: ScrollState): ScrollbarAdapter { - return remember(scrollState) { +actual fun rememberScrollbarAdapter(scrollState: ScrollState): ScrollbarAdapter = + remember(scrollState) { ScrollStateScrollbarAdapter(scrollState) } -} @Composable -actual fun rememberScrollbarAdapter(scrollState: LazyListState): ScrollbarAdapter { - return remember(scrollState) { +actual fun rememberScrollbarAdapter(scrollState: LazyListState): ScrollbarAdapter = + remember(scrollState) { LazyListStateScrollbarAdapter(scrollState) } -} @Composable internal actual fun realRememberVerticalScrollbarAdapter( scrollState: LazyGridState, gridCells: GridCells, arrangement: Arrangement.Vertical?, -): ScrollbarAdapter { - return remember(scrollState, gridCells) { +): ScrollbarAdapter = + remember(scrollState, gridCells) { LazyGridStateScrollbarAdapter(scrollState, gridCells, arrangement?.spacing ?: Dp.Hairline) } -} @Composable internal actual fun realRememberHorizontalScrollbarAdapter( scrollState: LazyGridState, gridCells: GridCells, arrangement: Arrangement.Horizontal?, -): ScrollbarAdapter { - return remember(scrollState, gridCells) { +): ScrollbarAdapter = + remember(scrollState, gridCells) { LazyGridStateScrollbarAdapter(scrollState, gridCells, arrangement?.spacing ?: Dp.Hairline) } -} actual fun Modifier.scrollbarPadding() = this diff --git a/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/resources/IosImageResource.kt b/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/resources/IosImageResource.kt index 87e3dc5aa..f2e805ecb 100644 --- a/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/resources/IosImageResource.kt +++ b/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/resources/IosImageResource.kt @@ -36,10 +36,9 @@ import platform.CoreGraphics.CGImageGetWidth import platform.UIKit.UIImage @Composable -actual fun ImageResource.toPainter(): Painter { - return remember { toUIImage()?.toSkiaImage()?.toComposeImageBitmap()?.let(::BitmapPainter) } +actual fun ImageResource.toPainter(): Painter = + remember { toUIImage()?.toSkiaImage()?.toComposeImageBitmap()?.let(::BitmapPainter) } ?: rememberVectorPainter(Icons.Rounded.BrokenImage) -} // Taken from https://github.com/touchlab/DroidconKotlin/blob/main/shared-ui/src/iosMain/kotlin/co/touchlab/droidcon/ui/util/ToSkiaImage.kt // TODO: Add support for remaining color spaces when the Skia library supports them. @@ -60,13 +59,16 @@ private fun UIImage.toSkiaImage(): Image? { CGImageAlphaInfo.kCGImageAlphaPremultipliedFirst, CGImageAlphaInfo.kCGImageAlphaPremultipliedLast, -> ColorAlphaType.PREMUL + CGImageAlphaInfo.kCGImageAlphaFirst, CGImageAlphaInfo.kCGImageAlphaLast, -> ColorAlphaType.UNPREMUL + CGImageAlphaInfo.kCGImageAlphaNone, CGImageAlphaInfo.kCGImageAlphaNoneSkipFirst, CGImageAlphaInfo.kCGImageAlphaNoneSkipLast, -> ColorAlphaType.OPAQUE + else -> ColorAlphaType.UNKNOWN }