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 ead56026..942cbfd4 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 @@ -49,7 +49,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.job -import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import org.lighthousegames.logging.logging import java.util.regex.Pattern diff --git a/build.gradle.kts b/build.gradle.kts index 06e21d5d..bf6d606c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -67,7 +67,13 @@ subprojects { } tasks.withType { source(files("src")) - exclude("ca/gosyer/jui/*/build", "ca/gosyer/jui/*/build") + exclude( + "ca/gosyer/jui/*/build", + "ca/gosyer/jui/*/build", + "**/generated/**", + "ca/gosyer/jui/data/graphql", + "ca/gosyer/jui/uicore/icons/juiassets", + ) } plugins.withType { configure { diff --git a/core/src/desktopMain/kotlin/ca/gosyer/jui/core/prefs/PreferenceStoreFactory.kt b/core/src/desktopMain/kotlin/ca/gosyer/jui/core/prefs/PreferenceStoreFactory.kt index 0eccc50a..2f5443ff 100644 --- a/core/src/desktopMain/kotlin/ca/gosyer/jui/core/prefs/PreferenceStoreFactory.kt +++ b/core/src/desktopMain/kotlin/ca/gosyer/jui/core/prefs/PreferenceStoreFactory.kt @@ -10,8 +10,10 @@ import com.russhwolf.settings.PreferencesSettings import me.tatarka.inject.annotations.Inject import java.util.prefs.Preferences -@Inject -actual class PreferenceStoreFactory() { +actual class PreferenceStoreFactory { + @Inject + constructor() + private val rootNode: Preferences = Preferences.userRoot() .node("ca/gosyer/tachideskjui") diff --git a/core/src/iosMain/kotlin/ca/gosyer/jui/core/prefs/PreferenceStoreFactory.kt b/core/src/iosMain/kotlin/ca/gosyer/jui/core/prefs/PreferenceStoreFactory.kt index 6b241ea2..836b3942 100644 --- a/core/src/iosMain/kotlin/ca/gosyer/jui/core/prefs/PreferenceStoreFactory.kt +++ b/core/src/iosMain/kotlin/ca/gosyer/jui/core/prefs/PreferenceStoreFactory.kt @@ -10,8 +10,10 @@ import com.russhwolf.settings.NSUserDefaultsSettings import me.tatarka.inject.annotations.Inject import platform.Foundation.NSUserDefaults -@Inject -actual class PreferenceStoreFactory() { +actual class PreferenceStoreFactory { + @Inject + constructor() + actual fun create(vararg names: String): PreferenceStore = StandardPreferenceStore( NSUserDefaultsSettings( diff --git a/core/src/iosMain/kotlin/ca/gosyer/jui/core/util/DateHandler.kt b/core/src/iosMain/kotlin/ca/gosyer/jui/core/util/DateHandler.kt index 2de2f507..4533fa85 100644 --- a/core/src/iosMain/kotlin/ca/gosyer/jui/core/util/DateHandler.kt +++ b/core/src/iosMain/kotlin/ca/gosyer/jui/core/util/DateHandler.kt @@ -5,8 +5,10 @@ import ca.gosyer.jui.core.lang.toPlatform import kotlinx.datetime.Instant import me.tatarka.inject.annotations.Inject -@Inject -actual class DateHandler() { +actual class DateHandler { + @Inject + constructor() + actual val formatOptions by lazy { listOf( "", diff --git a/core/src/jvmMain/kotlin/ca/gosyer/jui/core/util/DateHandler.kt b/core/src/jvmMain/kotlin/ca/gosyer/jui/core/util/DateHandler.kt index 17ac7930..3dac192c 100644 --- a/core/src/jvmMain/kotlin/ca/gosyer/jui/core/util/DateHandler.kt +++ b/core/src/jvmMain/kotlin/ca/gosyer/jui/core/util/DateHandler.kt @@ -9,8 +9,10 @@ import java.time.ZoneId import java.time.format.DateTimeFormatter import java.time.format.FormatStyle -@Inject -actual class DateHandler() { +actual class DateHandler { + @Inject + constructor() + actual val formatOptions by lazy { listOf( "", diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/base/WebsocketService.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/base/WebsocketService.kt index 1fe5c78b..c2e5cb74 100644 --- a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/base/WebsocketService.kt +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/base/WebsocketService.kt @@ -34,7 +34,7 @@ abstract class WebsocketService( protected val json = Json { ignoreUnknownKeys = true } - protected abstract val _status: MutableStateFlow + protected abstract val status: MutableStateFlow protected val serverUrl = serverPreferences.serverUrl().stateIn(GlobalScope) @@ -47,10 +47,10 @@ abstract class WebsocketService( job?.cancel() job = serverUrl .mapLatest { serverUrl -> - _status.value = Status.STARTING + status.value = Status.STARTING while (true) { if (errorConnectionCount > 3) { - _status.value = Status.STOPPED + status.value = Status.STOPPED throw CancellationException("Finish") } runCatching { @@ -65,7 +65,7 @@ abstract class WebsocketService( }, ) { errorConnectionCount = 0 - _status.value = Status.RUNNING + status.value = Status.RUNNING send(Frame.Text("STATUS")) incoming.receiveAsFlow() @@ -77,13 +77,13 @@ abstract class WebsocketService( .collect() } }.throwIfCancellation().isFailure.let { - _status.value = Status.STARTING + status.value = Status.STARTING if (it) errorConnectionCount++ } } } .catch { - _status.value = Status.STOPPED + status.value = Status.STOPPED log.warn(it) { "Error while running websocket service" } } .launchIn(GlobalScope) diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/service/DownloadService.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/service/DownloadService.kt index 87398cea..06b07405 100644 --- a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/service/DownloadService.kt +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/service/DownloadService.kt @@ -23,8 +23,8 @@ class DownloadService( serverPreferences: ServerPreferences, client: Http, ) : WebsocketService(serverPreferences, client) { - override val _status: MutableStateFlow - get() = status + override val status: MutableStateFlow + get() = DownloadService.status override val query: String get() = "/api/v1/downloads" diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/library/service/LibraryUpdateService.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/library/service/LibraryUpdateService.kt index 096672ba..bdab2835 100644 --- a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/library/service/LibraryUpdateService.kt +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/library/service/LibraryUpdateService.kt @@ -21,8 +21,8 @@ class LibraryUpdateService( serverPreferences: ServerPreferences, client: Http, ) : WebsocketService(serverPreferences, client) { - override val _status: MutableStateFlow - get() = status + override val status: MutableStateFlow + get() = LibraryUpdateService.status override val query: String get() = "/api/v1/update" diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/source/interactor/SourcePager.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/source/interactor/SourcePager.kt index d0de2aa8..4186387c 100644 --- a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/source/interactor/SourcePager.kt +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/source/interactor/SourcePager.kt @@ -41,9 +41,9 @@ class SourcePager( ) : CoroutineScope by CoroutineScope(Dispatchers.Default + SupervisorJob()) { private val sourceMutex = Mutex() - private val _sourceManga = MutableStateFlow>(emptyList()) + private val sourceManga = MutableStateFlow>(emptyList()) - private val mangaIds = _sourceManga.map { mangas -> mangas.map { it.id } } + private val mangaIds = sourceManga.map { mangas -> mangas.map { it.id } } .stateIn(this, SharingStarted.Eagerly, emptyList()) private val changedManga = @@ -57,7 +57,7 @@ class SourcePager( } }.stateIn(this, SharingStarted.Eagerly, emptyMap()) - val mangas = combine(_sourceManga, changedManga) { sourceManga, changedManga -> + val mangas = combine(sourceManga, changedManga) { sourceManga, changedManga -> sourceManga.map { changedManga[it.id] ?: it } }.stateIn(this, SharingStarted.Eagerly, emptyList()) @@ -76,7 +76,7 @@ class SourcePager( _pageNum.value++ val page = fetcher.get(_pageNum.value) if (page != null) { - _sourceManga.value = _sourceManga.value + page.mangaList + sourceManga.value += page.mangaList _hasNextPage.value = page.hasNextPage } else { _pageNum.value-- diff --git a/ios/src/uikitArm64Main/kotlin/ca/gosyer/jui/ios/AppComponent.arm64.kt b/ios/src/uikitArm64Main/kotlin/ca/gosyer/jui/ios/AppComponent.arm64.kt index 3febd83a..379aeccc 100644 --- a/ios/src/uikitArm64Main/kotlin/ca/gosyer/jui/ios/AppComponent.arm64.kt +++ b/ios/src/uikitArm64Main/kotlin/ca/gosyer/jui/ios/AppComponent.arm64.kt @@ -8,6 +8,4 @@ package ca.gosyer.jui.ios import ca.gosyer.jui.uicore.vm.ContextWrapper -actual fun create(context: ContextWrapper): AppComponent { - return AppComponent.create(context) -} +actual fun create(context: ContextWrapper): AppComponent = AppComponent.create(context) diff --git a/ios/src/uikitSimulatorArm64Main/kotlin/ca/gosyer/jui/ios/AppComponent.simArm64.kt b/ios/src/uikitSimulatorArm64Main/kotlin/ca/gosyer/jui/ios/AppComponent.simArm64.kt index 3febd83a..379aeccc 100644 --- a/ios/src/uikitSimulatorArm64Main/kotlin/ca/gosyer/jui/ios/AppComponent.simArm64.kt +++ b/ios/src/uikitSimulatorArm64Main/kotlin/ca/gosyer/jui/ios/AppComponent.simArm64.kt @@ -8,6 +8,4 @@ package ca.gosyer.jui.ios import ca.gosyer.jui.uicore.vm.ContextWrapper -actual fun create(context: ContextWrapper): AppComponent { - return AppComponent.create(context) -} +actual fun create(context: ContextWrapper): AppComponent = AppComponent.create(context) diff --git a/ios/src/uikitX64Main/kotlin/ca/gosyer/jui/ios/AppComponent.x64.kt b/ios/src/uikitX64Main/kotlin/ca/gosyer/jui/ios/AppComponent.x64.kt index 3febd83a..379aeccc 100644 --- a/ios/src/uikitX64Main/kotlin/ca/gosyer/jui/ios/AppComponent.x64.kt +++ b/ios/src/uikitX64Main/kotlin/ca/gosyer/jui/ios/AppComponent.x64.kt @@ -8,6 +8,4 @@ package ca.gosyer.jui.ios import ca.gosyer.jui.uicore.vm.ContextWrapper -actual fun create(context: ContextWrapper): AppComponent { - return AppComponent.create(context) -} +actual fun create(context: ContextWrapper): AppComponent = AppComponent.create(context) 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 9859fcfc..1c146d40 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 @@ -113,7 +113,7 @@ class ReaderMenuViewModel( cur.orEmpty() + ReaderPageSeparator(viewerChapters.currChapter, viewerChapters.nextChapter) + next.orEmpty() - ).toImmutableList() + ).toImmutableList() } }.stateIn(scope, SharingStarted.Eagerly, persistentListOf()) 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 5a6db719..164c740d 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 @@ -185,16 +185,17 @@ class SettingsBackupViewModel( .launchIn(scope) } - private fun RestoreStatus.toStatus() = when (state) { - RestoreState.IDLE -> Status.Success - RestoreState.SUCCESS -> Status.Success - RestoreState.FAILURE -> Status.Error - RestoreState.RESTORING_CATEGORIES -> Status.InProgress(0.01f) - RestoreState.RESTORING_SETTINGS -> Status.InProgress(0.02f) - RestoreState.RESTORING_MANGA -> Status.InProgress((completed.toFloat() / total).coerceIn(0f, 0.99f)) - RestoreState.RESTORING_META -> Status.InProgress(1f) - RestoreState.UNKNOWN -> Status.Error - } + private fun RestoreStatus.toStatus() = + when (state) { + RestoreState.IDLE -> Status.Success + RestoreState.SUCCESS -> Status.Success + RestoreState.FAILURE -> Status.Error + RestoreState.RESTORING_CATEGORIES -> Status.InProgress(0.01f) + RestoreState.RESTORING_SETTINGS -> Status.InProgress(0.02f) + RestoreState.RESTORING_MANGA -> Status.InProgress((completed.toFloat() / total).coerceIn(0f, 0.99f)) + RestoreState.RESTORING_META -> Status.InProgress(1f) + RestoreState.UNKNOWN -> Status.Error + } fun stopRestore() { _restoreStatus.value = Status.Error @@ -206,7 +207,8 @@ class SettingsBackupViewModel( fun exportBackup() { exportBackupFile .asFlow( - true, true, // todo + true, + true, // todo ) { onDownload { bytesSentTotal, contentLength -> _creatingStatus.value = Status.InProgress( 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 ee2d5f78..234a3153 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 @@ -887,7 +887,7 @@ private val repoRegex = ( "https:\\/\\/(?>www\\.|raw\\.)?(github|githubusercontent)\\.com" + "\\/([^\\/]+)\\/([^\\/]+)(?>(?>\\/tree|\\/blob)?\\/([^\\/\\n]*))?(?>\\/([^\\/\\n]*\\.json)?)?" - ).toRegex() + ).toRegex() @Composable fun ExtensionReposDialog( diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreen.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreen.kt index aad89bc9..bb93703b 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreen.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreen.kt @@ -26,8 +26,8 @@ import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.merge -private fun SourceFiltersView<*, *>.toSourceFilter(): SourceFilter { - return when (this) { +private fun SourceFiltersView<*, *>.toSourceFilter(): SourceFilter = + when (this) { is SourceFiltersView.CheckBox -> filter.copy(value = state.value) is SourceFiltersView.Group -> filter.copy(value = state.value.map { it.toSourceFilter() }) is SourceFiltersView.Header -> filter @@ -37,7 +37,6 @@ private fun SourceFiltersView<*, *>.toSourceFilter(): SourceFilter { is SourceFiltersView.Text -> filter.copy(value = state.value) is SourceFiltersView.TriState -> filter.copy(value = state.value) } -} class SourceScreen( val source: Source, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/model/SourceSettingsView.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/model/SourceSettingsView.kt index a0454625..dfb2f823 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/model/SourceSettingsView.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/model/SourceSettingsView.kt @@ -45,7 +45,7 @@ sealed class SourceSettingsView { override val title: String?, override val subtitle: String?, override val props: CheckBoxSourcePreference, - ) : SourceSettingsView(){ + ) : SourceSettingsView() { private val _state = MutableStateFlow( props.currentValue ?: props.default, ) diff --git a/presentation/src/desktopMain/kotlin/ca/gosyer/jui/ui/main/components/TrayViewModel.kt b/presentation/src/desktopMain/kotlin/ca/gosyer/jui/ui/main/components/TrayViewModel.kt index 85c8d1c9..064d30de 100644 --- a/presentation/src/desktopMain/kotlin/ca/gosyer/jui/ui/main/components/TrayViewModel.kt +++ b/presentation/src/desktopMain/kotlin/ca/gosyer/jui/ui/main/components/TrayViewModel.kt @@ -19,8 +19,7 @@ import me.tatarka.inject.annotations.Inject import org.lighthousegames.logging.logging @Inject -class TrayViewModel -constructor( +class TrayViewModel( updateChecker: UpdateChecker, contextWrapper: ContextWrapper, ) : ViewModel(contextWrapper) { diff --git a/presentation/src/desktopMain/kotlin/ca/gosyer/jui/ui/settings/DesktopSettingsServerScreen.kt b/presentation/src/desktopMain/kotlin/ca/gosyer/jui/ui/settings/DesktopSettingsServerScreen.kt index 13bf0b7c..2252c690 100644 --- a/presentation/src/desktopMain/kotlin/ca/gosyer/jui/ui/settings/DesktopSettingsServerScreen.kt +++ b/presentation/src/desktopMain/kotlin/ca/gosyer/jui/ui/settings/DesktopSettingsServerScreen.kt @@ -67,8 +67,7 @@ actual fun getServerHostItems(viewModel: @Composable () -> SettingsServerHostVie } @Inject -actual class SettingsServerHostViewModel -constructor( +actual class SettingsServerHostViewModel( serverPreferences: ServerPreferences, serverHostPreferences: ServerHostPreferences, private val serverService: ServerService, diff --git a/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/main/components/DebugOverlayViewModel.kt b/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/main/components/DebugOverlayViewModel.kt index c7da53ff..b8159fa0 100644 --- a/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/main/components/DebugOverlayViewModel.kt +++ b/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/main/components/DebugOverlayViewModel.kt @@ -12,8 +12,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import me.tatarka.inject.annotations.Inject @Inject -actual class DebugOverlayViewModel -constructor( +actual class DebugOverlayViewModel( contextWrapper: ContextWrapper, ) : ViewModel(contextWrapper) { actual val maxMemory: String diff --git a/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/settings/IosSettingsServerScreen.kt b/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/settings/IosSettingsServerScreen.kt index 95ad494d..e3e49b24 100644 --- a/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/settings/IosSettingsServerScreen.kt +++ b/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/settings/IosSettingsServerScreen.kt @@ -16,7 +16,6 @@ import me.tatarka.inject.annotations.Inject actual fun getServerHostItems(viewModel: @Composable () -> SettingsServerHostViewModel): LazyListScope.() -> Unit = {} @Inject -actual class SettingsServerHostViewModel -constructor( +actual class SettingsServerHostViewModel( contextWrapper: ContextWrapper, ) : ViewModel(contextWrapper) diff --git a/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/util/lang/Collator.kt b/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/util/lang/Collator.kt index 1104b563..2d0c0a71 100644 --- a/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/util/lang/Collator.kt +++ b/presentation/src/iosMain/kotlin/ca/gosyer/jui/ui/util/lang/Collator.kt @@ -10,7 +10,8 @@ import androidx.compose.ui.text.intl.Locale import platform.Foundation.NSString import platform.Foundation.localizedCaseInsensitiveCompare -actual class CollatorComparator() : Comparator { +actual class CollatorComparator : Comparator { + constructor() actual constructor(locale: Locale) : this() actual override fun compare( diff --git a/presentation/src/jvmMain/kotlin/ca/gosyer/jui/ui/main/components/DebugOverlayViewModel.kt b/presentation/src/jvmMain/kotlin/ca/gosyer/jui/ui/main/components/DebugOverlayViewModel.kt index 80951bb0..7aded689 100644 --- a/presentation/src/jvmMain/kotlin/ca/gosyer/jui/ui/main/components/DebugOverlayViewModel.kt +++ b/presentation/src/jvmMain/kotlin/ca/gosyer/jui/ui/main/components/DebugOverlayViewModel.kt @@ -17,8 +17,7 @@ import me.tatarka.inject.annotations.Inject import kotlin.time.Duration.Companion.milliseconds @Inject -actual class DebugOverlayViewModel -constructor( +actual class DebugOverlayViewModel( contextWrapper: ContextWrapper, ) : ViewModel(contextWrapper) { override val scope = MainScope() diff --git a/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/vm/ContextWrapper.kt b/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/vm/ContextWrapper.kt index 3cb32b97..90eb7eac 100644 --- a/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/vm/ContextWrapper.kt +++ b/ui-core/src/iosMain/kotlin/ca/gosyer/jui/uicore/vm/ContextWrapper.kt @@ -15,8 +15,10 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow import me.tatarka.inject.annotations.Inject -@Inject -actual class ContextWrapper() { +actual class ContextWrapper { + @Inject + constructor() + private val _toasts = MutableSharedFlow>() val toasts = _toasts.asSharedFlow()