diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 2d7974b0c..5fd5037eb 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -5,6 +5,7 @@ import org.xmlpull.v1.XmlPullParserFactory import java.io.FileInputStream import java.util.Properties import com.android.build.api.dsl.ApplicationVariantDimension +import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import plugin.spmp.SpMpDeps import plugin.spmp.getDeps @@ -57,7 +58,9 @@ kotlin { val androidMain by getting { dependencies { implementation(project(":shared")) - implementation(deps.get("dev.toastbits.composekit:library")) + for (dependency in deps.getAllComposeKit()) { + implementation(dependency) + } } } } @@ -166,8 +169,9 @@ android { implementation(project(":shared")) // Widget - implementation("androidx.glance:glance-appwidget:1.1.0") - implementation("androidx.glance:glance-material3:1.1.0") + val glance_version = "1.1.1" + implementation("androidx.glance:glance-appwidget:$glance_version") + implementation("androidx.glance:glance-material3:$glance_version") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3") implementation(compose.runtime) // implementation(compose.foundation) @@ -175,7 +179,7 @@ android { // implementation(compose.ui) // implementation(compose.material) implementation(compose.material3) -// implementation(compose.components.resources) + implementation(compose.components.resources) } manifest { srcFile("src/main/AndroidManifest.xml") diff --git a/androidApp/src/main/java/com/toasterofbread/spmp/MainActivity.kt b/androidApp/src/main/java/com/toasterofbread/spmp/MainActivity.kt index fef194ea7..1578459aa 100644 --- a/androidApp/src/main/java/com/toasterofbread/spmp/MainActivity.kt +++ b/androidApp/src/main/java/com/toasterofbread/spmp/MainActivity.kt @@ -23,7 +23,7 @@ import androidx.compose.runtime.setValue import androidx.core.view.WindowCompat import com.toasterofbread.spmp.model.appaction.shortcut.ShortcutState import com.toasterofbread.spmp.platform.AppContext -import dev.toastbits.composekit.platform.ApplicationContext +import dev.toastbits.composekit.context.ApplicationContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.cancel diff --git a/androidApp/src/main/java/com/toasterofbread/spmp/widget/WidgetConfigurationActivity.kt b/androidApp/src/main/java/com/toasterofbread/spmp/widget/WidgetConfigurationActivity.kt index 4b88c413c..bd5bed2d7 100644 --- a/androidApp/src/main/java/com/toasterofbread/spmp/widget/WidgetConfigurationActivity.kt +++ b/androidApp/src/main/java/com/toasterofbread/spmp/widget/WidgetConfigurationActivity.kt @@ -18,33 +18,41 @@ import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.core.view.WindowCompat import androidx.glance.GlanceId import androidx.glance.appwidget.GlanceAppWidgetManager import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.platform.observeUiLanguage import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.ThemeMode import com.toasterofbread.spmp.widget.action.TypeWidgetClickAction import com.toasterofbread.spmp.widget.configuration.SpMpWidgetConfiguration import com.toasterofbread.spmp.widget.configuration.type.TypeWidgetConfig import com.toasterofbread.spmp.widget.configuration.ui.screen.WidgetConfigurationScreen -import dev.toastbits.composekit.navigation.Screen +import dev.toastbits.composekit.components.utils.modifier.background +import dev.toastbits.composekit.context.ApplicationContext import dev.toastbits.composekit.navigation.compositionlocal.LocalNavigator +import dev.toastbits.composekit.navigation.navigator.BaseNavigator import dev.toastbits.composekit.navigation.navigator.CurrentScreen -import dev.toastbits.composekit.navigation.navigator.ExtendableNavigator import dev.toastbits.composekit.navigation.navigator.Navigator -import dev.toastbits.composekit.platform.ApplicationContext -import dev.toastbits.composekit.platform.LocalContext -import dev.toastbits.composekit.utils.common.plus -import dev.toastbits.composekit.utils.modifier.background +import dev.toastbits.composekit.navigation.screen.Screen +import dev.toastbits.composekit.theme.core.model.NamedTheme +import dev.toastbits.composekit.theme.core.model.SerialisableTheme +import dev.toastbits.composekit.theme.core.model.ThemeReference +import dev.toastbits.composekit.theme.core.provider.ContextThemeProvider +import dev.toastbits.composekit.theme.core.provider.ThemeProvider +import dev.toastbits.composekit.theme.core.ui.LocalThemeProvider +import dev.toastbits.composekit.util.composable.plus import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.serialization.encodeToString +import org.jetbrains.compose.resources.stringResource +import spmp.shared.generated.resources.Res +import spmp.shared.generated.resources.widget_application_theme_label class WidgetConfigurationActivity: ComponentActivity() { private var app_widget_id: Int = AppWidgetManager.INVALID_APPWIDGET_ID @@ -103,7 +111,7 @@ class WidgetConfigurationActivity: ComponentActivity() { widget_type = widget_type ) } - val navigator: Navigator = ExtendableNavigator(configuration_screen) + val navigator: Navigator = BaseNavigator(configuration_screen) WindowCompat.setDecorFitsSystemWindows(window, false) window.setFlags( @@ -113,11 +121,10 @@ class WidgetConfigurationActivity: ComponentActivity() { setContent { val composable_coroutine_scope: CoroutineScope = rememberCoroutineScope() - val np_theme_mode: ThemeMode by context.settings.theme.NOWPLAYING_THEME_MODE.observe() - val swipe_sensitivity: Float by context.settings.player.EXPAND_SWIPE_SENSITIVITY.observe() + val np_theme_mode: ThemeMode by context.settings.Theme.NOWPLAYING_THEME_MODE.observe() + val swipe_sensitivity: Float by context.settings.Player.EXPAND_SWIPE_SENSITIVITY.observe() CompositionLocalProvider( - LocalContext provides context, LocalNavigator provides navigator, LocalPlayerState providesComputed { SpMp._player_state?.also { return@providesComputed it } @@ -129,20 +136,34 @@ class WidgetConfigurationActivity: ComponentActivity() { return@providesComputed dummy_player_state!! } ) { - if (!context.theme.Update()) { - return@CompositionLocalProvider - } - - val ui_language: String by context.observeUiLanguage() - - SpMp.Theme(context, ui_language) { - Scaffold { inner_padding -> - navigator.CurrentScreen( - Modifier - .fillMaxSize() - .background { context.theme.background }, - inner_padding + PaddingValues(20.dp) - ) + SpMp.Theme(context) { + val themeProvider: ThemeProvider = LocalThemeProvider.current + val applicationTheme: ThemeReference by context.settings.Theme.CURRENT_THEME.observe() + val applicationThemeName: String = stringResource(Res.string.widget_application_theme_label) + + CompositionLocalProvider( + LocalThemeProvider provides object : ContextThemeProvider(context) { + override fun getCustomTheme(index: Int): SerialisableTheme? = + if (index == -1) + NamedTheme( + NamedTheme.Type.CUSTOM, + applicationThemeName, + applicationTheme.getTheme(themeProvider) + ) + else themeProvider.getCustomTheme(index) + + override fun getCustomThemes(): List = + themeProvider.getCustomThemes() + } + ) { + Scaffold { inner_padding -> + navigator.CurrentScreen( + Modifier + .fillMaxSize() + .background { context.theme.background }, + inner_padding + PaddingValues(20.dp) + ) + } } } } @@ -176,13 +197,15 @@ class WidgetConfigurationActivity: ComponentActivity() { } }, onSetDefaultBaseConfig = { new_base_configuration -> - context.settings.widget.DEFAULT_BASE_WIDGET_CONFIGURATION.set(new_base_configuration) + coroutine_scope.launch { + context.settings.Widget.DEFAULT_BASE_WIDGET_CONFIGURATION.set(new_base_configuration) + } }, onSetDefaultTypeConfig = { new_type_configuration -> coroutine_scope.launch { val types: Map> = - context.settings.widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.get() - context.settings.widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.set( + context.settings.Widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.get() + context.settings.Widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.set( types.toMutableMap().apply { set(widget_type, new_type_configuration) } diff --git a/buildSrc/src/main/kotlin/plugins/spmp/Dependencies.kt b/buildSrc/src/main/kotlin/plugins/spmp/Dependencies.kt index 3e6d07c18..a89599b80 100644 --- a/buildSrc/src/main/kotlin/plugins/spmp/Dependencies.kt +++ b/buildSrc/src/main/kotlin/plugins/spmp/Dependencies.kt @@ -34,6 +34,21 @@ class SpMpDeps(extra: Map) { throw RuntimeException("No dependency found matching artifact '$artifact") } + fun getAllComposeKit(): List = + listOf( + "dev.toastbits:composekit-application", + "dev.toastbits:composekit-commonsettings", + "dev.toastbits:composekit-components", + "dev.toastbits:composekit-context", + "dev.toastbits:composekit-navigation", + "dev.toastbits:composekit-settings", + "dev.toastbits:composekit-settingsitem-presentation", + "dev.toastbits:composekit-theme-core", + "dev.toastbits:composekit-theme-config", + "dev.toastbits:composekit-util", + "dev.toastbits:composekit-utilKt" + ).map { get(it, "dev.toastbits:composekit") } + val dependencies: Map = mapOf( "dev.toastbits:spms" to DependencyInfo( @@ -44,8 +59,8 @@ class SpMpDeps(extra: Map) { license = "GPL-3.0", license_url = "https://github.com/toasterofbread/spmp-server/blob/6dde651ffc102d604ac7ecd5ac7471b1572fd2e6/LICENSE" ), - "dev.toastbits.composekit" to DependencyInfo( - version = "64b947f17e", + "dev.toastbits:composekit" to DependencyInfo( + version = "0.1.0-rc3", name = "ComposeKit", author = "toasterofbread", url = "https://github.com/toasterofbread/composekit", @@ -86,7 +101,7 @@ class SpMpDeps(extra: Map) { license_url = "https://github.com/Kotlin/kotlinx.serialization/blob/51cb8e8e556983fc83a565d5f04bb089363453e0/LICENSE.txt" ), "org.jetbrains.compose" to DependencyInfo( - version = "1.6.2", + version = "1.8.0-alpha01", name = "Compose Multiplatform", author = "JetBrains", url = "https://github.com/JetBrains/compose-multiplatform", @@ -142,7 +157,7 @@ class SpMpDeps(extra: Map) { license_url = "https://github.com/MohamedRejeb/Ksoup/blob/5f07e799c95e518d80caf70fc586ddcc649e1315/LICENSE" ), "com.github.toasterofbread.ComposeReorderable" to DependencyInfo( - version = "349bdb3a2a", + version = "77c7652169", name = "ComposeReorderable", author = "aclassen", url = "https://github.com/aclassen/ComposeReorderable", @@ -151,6 +166,7 @@ class SpMpDeps(extra: Map) { fork_url = "https://github.com/toasterofbread/ComposeReorderable/", // redirect = "org.burnoutcrew.composereorderable:reorderable" ), + "com.github.SvenWoltmann:color-thief-java" to DependencyInfo( version = "v1.1.2", name = "Color Thief Java", diff --git a/desktopApp/build.gradle.kts b/desktopApp/build.gradle.kts index 1f501372a..d0c293734 100644 --- a/desktopApp/build.gradle.kts +++ b/desktopApp/build.gradle.kts @@ -58,7 +58,9 @@ kotlin { implementation(compose.components.resources) implementation(project(":shared")) - implementation(deps.get("dev.toastbits.composekit:library")) + for (dependency in deps.getAllComposeKit()) { + implementation(dependency) + } implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.6.4") diff --git a/desktopApp/src/jvmMain/kotlin/main.kt b/desktopApp/src/jvmMain/kotlin/main.kt index dc66438e7..3bc54ff23 100644 --- a/desktopApp/src/jvmMain/kotlin/main.kt +++ b/desktopApp/src/jvmMain/kotlin/main.kt @@ -42,7 +42,7 @@ fun main(args: Array) { SpMp.init(context) - val force_software_renderer: Boolean = runBlocking { context.settings.platform.FORCE_SOFTWARE_RENDERER.get() } + val force_software_renderer: Boolean = runBlocking { context.settings.Platform.FORCE_SOFTWARE_RENDERER.get() } if (force_software_renderer) { System.setProperty("skiko.renderApi", "SOFTWARE") } @@ -73,7 +73,7 @@ fun main(args: Array) { } lateinit var window: ComposeWindow - val enable_window_transparency: Boolean = runBlocking { context.settings.theme.ENABLE_WINDOW_TRANSPARENCY.get() } + val enable_window_transparency: Boolean = runBlocking { context.settings.Theme.ENABLE_WINDOW_TRANSPARENCY.get() } val shortcut_state: ShortcutState = ShortcutState() var player: PlayerState? = null @@ -125,7 +125,7 @@ fun main(args: Array) { window.background = java.awt.Color(0, 0, 0, 0) } - val startup_command: String = context.settings.platform.STARTUP_COMMAND.get() + val startup_command: String = context.settings.Platform.STARTUP_COMMAND.get() if (startup_command.isBlank()) { return@LaunchedEffect } diff --git a/flake.nix b/flake.nix index c969f21ef..bce0ba6e2 100644 --- a/flake.nix +++ b/flake.nix @@ -23,6 +23,7 @@ vulkan-loader xorg.libXtst apksigcopier + gtk3 # Webview at-spi2-atk @@ -108,6 +109,8 @@ lib_paths=($(echo $NIX_LDFLAGS | grep -oP '(?<=-rpath\s| -L)[^ ]+')) lib_paths_str=$(IFS=:; echo "''${lib_paths[*]}") export LD_LIBRARY_PATH="$lib_paths_str:$LD_LIBRARY_PATH" + + export XDG_DATA_DIRS="$XDG_DATA_DIRS:${pkgs.gtk3}/share/gsettings-schemas/gtk+3-3.24.42" ''; }; }; diff --git a/gradle.properties b/gradle.properties index c826510e4..6c17eea33 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,9 +22,9 @@ android.suppressUnsupportedCompileSdk=34,35 org.jetbrains.compose.experimental.wasm.enabled=true # Plugin versions -kotlin.version=2.0.21 +kotlin.version=2.1.0 agp.version=8.4.1 -compose.version=1.7.0-rc01 +compose.version=1.8.0-alpha01 sqldelight.version=2.0.2 # Nix diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 9bfe18f97..1a5cfdb6b 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -91,9 +91,11 @@ kotlin { implementation(compose.components.resources) implementation(deps.get("dev.toastbits:spms")) - implementation(deps.get("dev.toastbits.composekit:library")) implementation(deps.get("dev.toastbits:ytm-kt")) implementation(deps.get("dev.toastbits.kana-kt:kanakt")) + for (dependency in deps.getAllComposeKit()) { + implementation(dependency) + } implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0-RC") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3") diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/ErrorReportActivity.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/ErrorReportActivity.kt index e48d77e9b..37ef2ae8f 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/ErrorReportActivity.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/ErrorReportActivity.kt @@ -47,14 +47,14 @@ import androidx.compose.ui.unit.sp import com.anggrayudi.storage.extension.count import com.toasterofbread.spmp.model.JsonHttpClient import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.platform.AppThemeManager import com.toasterofbread.spmp.resources.getStringTODO import com.toasterofbread.spmp.resources.stringResourceTODO import com.toasterofbread.spmp.ui.component.uploadErrorToPasteEe -import dev.toastbits.composekit.platform.ApplicationContext -import dev.toastbits.composekit.platform.composable.theme.ApplicationTheme -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.application.ApplicationTheme +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.context.ApplicationContext +import dev.toastbits.composekit.theme.core.ThemeManager +import dev.toastbits.composekit.util.thenIf import io.ktor.client.HttpClient import io.ktor.client.request.request import io.ktor.client.request.setBody @@ -83,7 +83,6 @@ private const val LOGCAT_LINES_TO_DISPLAY: Int = 100 class ErrorReportActivity : ComponentActivity() { private val coroutine_scope = CoroutineScope(Job()) private var logcat_output: String? by mutableStateOf(null) - private var context: AppContext? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -91,12 +90,15 @@ class ErrorReportActivity : ComponentActivity() { val message: String = intent.getStringExtra("message") ?: "No message" val stack_trace: String = intent.getStringExtra("stack_trace") ?: "No stack trace" - try { - context = runBlocking { - AppContext.create(this@ErrorReportActivity, coroutine_scope, ApplicationContext(this@ErrorReportActivity)) + val context: AppContext? = + try { + runBlocking { + AppContext.create(this@ErrorReportActivity, coroutine_scope, ApplicationContext(this@ErrorReportActivity)) + } + } + catch (_: Throwable) { + null } - } - catch (_: Throwable) {} val logcat_lines = LOGCAT_LINES_TO_DISPLAY + stack_trace.count("\n") @@ -110,14 +112,14 @@ class ErrorReportActivity : ComponentActivity() { "---STACK TRACE---\n$stack_trace\n---LOGCAT (last $logcat_lines lines)---\n$logcat" } - val theme: AppThemeManager? = context?.theme - if (theme?.Update() == true) { - theme.ApplicationTheme(context!!) { - ErrorDisplay(message, stack_trace, logcat, error_text) + val theme: ThemeManager? = context?.theme + if (theme != null) { + theme.ApplicationTheme(context, context.settings) { + ErrorDisplay(context, message, stack_trace, logcat, error_text) } } else { - ErrorDisplay(message, stack_trace, logcat, error_text) + ErrorDisplay(null, message, stack_trace, logcat, error_text) } return@setContent } @@ -135,7 +137,7 @@ class ErrorReportActivity : ComponentActivity() { } @Composable - fun ErrorDisplay(message: String, stack_trace: String, logs: String, error_text: String) { + fun ErrorDisplay(context: AppContext?, message: String, stack_trace: String, logs: String, error_text: String) { val share_intent = remember { Intent.createChooser(Intent().apply { action = Intent.ACTION_SEND diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/AppContext.android.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/AppContext.android.kt index 3bfefeccc..da1ed0567 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/AppContext.android.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/AppContext.android.kt @@ -1,7 +1,6 @@ package com.toasterofbread.spmp.platform import SpMp -import android.app.Activity import android.content.ComponentName import android.content.Context import android.content.Intent @@ -17,18 +16,18 @@ import com.toasterofbread.spmp.platform.download.PlayerDownloadManager import com.toasterofbread.spmp.resources.Language import com.toasterofbread.spmp.resources.getAvailableLanguages import com.toasterofbread.spmp.youtubeapi.YtmApiType -import dev.toastbits.composekit.platform.ApplicationContext -import dev.toastbits.composekit.platform.PlatformContextImpl -import dev.toastbits.composekit.platform.PlatformPreferences -import dev.toastbits.composekit.platform.PlatformPreferencesImpl -import dev.toastbits.composekit.utils.common.getThemeColour -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.context.ApplicationContext +import dev.toastbits.composekit.context.PlatformContext +import dev.toastbits.composekit.settings.PlatformSettings +import dev.toastbits.composekit.settings.PlatformSettingsImpl +import dev.toastbits.composekit.theme.core.ThemeManager +import dev.toastbits.composekit.util.getThemeColour +import dev.toastbits.composekit.util.platform.launchSingle import dev.toastbits.ytmkt.model.YtmApi import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.withContext -import kotlinx.serialization.json.Json actual class AppContext private constructor( context: Context, @@ -37,16 +36,18 @@ actual class AppContext private constructor( api_url: String, data_language: Language, available_languages: List, - private val prefs: PlatformPreferences, - application_context: ApplicationContext? = null -): PlatformContextImpl(context, coroutine_scope, application_context) { + private val prefs: PlatformSettings, + application_context: ApplicationContext? = null, + themeManager: ThemeManager? = null +): PlatformContext(context, coroutine_scope, application_context) { companion object { suspend fun create( context: Context, coroutine_scope: CoroutineScope, - application_context: ApplicationContext? = null + application_context: ApplicationContext? = null, + themeManager: ThemeManager? = null ): AppContext { - val prefs: PlatformPreferences = PlatformPreferencesImpl.getInstance(context, ProjectJson.instance) + val prefs: PlatformSettings = PlatformSettingsImpl.getInstance(context, ProjectJson.instance) val settings: YTApiSettings = YTApiSettings(prefs) return AppContext( @@ -57,7 +58,8 @@ actual class AppContext private constructor( Language.getSystem(), getAvailableLanguages(), prefs, - application_context + application_context, + themeManager ) } @@ -65,14 +67,14 @@ actual class AppContext private constructor( Intent().setComponent(ComponentName(context, "com.toasterofbread.spmp.MainActivity")) } - actual fun getPrefs(): PlatformPreferences = prefs + actual fun getPrefs(): PlatformSettings = prefs private val colorblendr_coroutine_scope = CoroutineScope(Dispatchers.Default) private var current_colorblendr_song: Song? = null fun onNotificationThumbnailLoaded(image: Bitmap?) { colorblendr_coroutine_scope.launchSingle { - if (!settings.experimental.ANDROID_MONET_COLOUR_ENABLE.get()) { + if (!settings.Experimental.ANDROID_MONET_COLOUR_ENABLE.get()) { return@launchSingle } @@ -111,5 +113,5 @@ actual class AppContext private constructor( actual val settings: Settings = Settings(this, available_languages) actual val download_manager: PlayerDownloadManager = PlayerDownloadManager(this) actual val ytapi: YtmApi = api_type.instantiate(this, api_url, data_language) - actual val theme: AppThemeManager = AppThemeManager(this@AppContext) + actual val theme: ThemeManager = themeManager ?: AppThemeManager(this@AppContext) } diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/DiscordStatus.android.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/DiscordStatus.android.kt index 672c35175..0efc45d67 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/DiscordStatus.android.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/DiscordStatus.android.kt @@ -112,11 +112,11 @@ actual class DiscordStatus actual constructor( val disabled_statuses: List = listOfNotNull( - "invisible".takeIf { context.settings.discord.STATUS_DISABLE_WHEN_INVISIBLE.get() }, - "dnd".takeIf { context.settings.discord.STATUS_DISABLE_WHEN_DND.get() }, - "idle".takeIf { context.settings.discord.STATUS_DISABLE_WHEN_IDLE.get() }, - "offline".takeIf { context.settings.discord.STATUS_DISABLE_WHEN_OFFLINE.get() }, - "online".takeIf { context.settings.discord.STATUS_DISABLE_WHEN_ONLINE.get() } + "invisible".takeIf { context.settings.Discord.STATUS_DISABLE_WHEN_INVISIBLE.get() }, + "dnd".takeIf { context.settings.Discord.STATUS_DISABLE_WHEN_DND.get() }, + "idle".takeIf { context.settings.Discord.STATUS_DISABLE_WHEN_IDLE.get() }, + "offline".takeIf { context.settings.Discord.STATUS_DISABLE_WHEN_OFFLINE.get() }, + "online".takeIf { context.settings.Discord.STATUS_DISABLE_WHEN_ONLINE.get() } ) if (disabled_statuses.isEmpty()) { diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/ImageBitmap.android.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/ImageBitmap.android.kt index ccae43dd6..6f8eab5d9 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/ImageBitmap.android.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/ImageBitmap.android.kt @@ -8,7 +8,7 @@ import androidx.compose.ui.graphics.asAndroidBitmap import androidx.compose.ui.graphics.asImageBitmap import androidx.palette.graphics.Palette import java.io.ByteArrayOutputStream -import dev.toastbits.composekit.utils.common.sortedByHue +import dev.toastbits.composekit.util.sortedByHue actual fun createImageBitmapUtil(): ImageBitmapUtil? = AndroidImageBitmapUtil() diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.android.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.android.kt index 22232a34c..1fb6f791c 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.android.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.android.kt @@ -1,7 +1,7 @@ package com.toasterofbread.spmp.platform.download import android.os.Build -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.platform.AppContext @@ -135,7 +135,7 @@ actual class PlayerDownloadManager actual constructor(val context: AppContext) { callback: DownloadRequestCallback? ) { if (!silent && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - context.application_context?.requestNotficationPermission { granted -> + context.applicationContext?.requestNotificationPermission { granted -> if (granted) { performDownload(song, silent, custom_uri, download_lyrics, direct, callback) } @@ -158,7 +158,7 @@ actual class PlayerDownloadManager actual constructor(val context: AppContext) { val instance: Int = result_callback_id++ addResultCallback(PlayerDownloadService.IntentAction.START_DOWNLOAD, song.id, instance) { data -> val status: DownloadStatus = data["status"] as DownloadStatus - context.coroutine_scope.launch { + context.coroutineScope.launch { if (custom_uri == null) { MediaItemLibrary.onSongFileAdded(status) } diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadService.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadService.kt index c2af172fc..6f39519e6 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadService.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadService.kt @@ -27,7 +27,7 @@ import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.PlatformBinder import com.toasterofbread.spmp.platform.PlatformServiceImpl import com.toasterofbread.spmp.platform.getUiLanguage -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -69,7 +69,7 @@ class PlayerDownloadService: PlatformServiceImpl() { } override fun onPausedChanged() { - context.coroutine_scope.launch { + context.coroutineScope.launch { pause_resume_action?.title = if (paused) getString(Res.string.action_download_resume) else getString(Res.string.action_download_pause) @@ -103,7 +103,7 @@ class PlayerDownloadService: PlatformServiceImpl() { } override fun onDownloadProgress() { - context.coroutine_scope.launch { + context.coroutineScope.launch { updateNotification() } } @@ -222,7 +222,7 @@ class PlayerDownloadService: PlatformServiceImpl() { override fun onMessage(data: Any?) { require(data is PlayerDownloadManager.PlayerDownloadMessage) - context.coroutine_scope.launch { + context.coroutineScope.launch { onActionIntentReceived(data) } } @@ -332,7 +332,7 @@ class PlayerDownloadService: PlatformServiceImpl() { val action: Any? = intent?.extras?.get("action") if (action is IntentAction) { println("Download service received action $action") - context.coroutine_scope.launch { + context.coroutineScope.launch { onActionIntentReceived( PlayerDownloadManager.PlayerDownloadMessage( action, diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/getMediaDataSpecPlaybackUri.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/getMediaDataSpecPlaybackUri.kt index 3232dc884..e2eb3c95b 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/getMediaDataSpecPlaybackUri.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/getMediaDataSpecPlaybackUri.kt @@ -11,7 +11,7 @@ import com.toasterofbread.spmp.model.mediaitem.song.getSongTargetAudioFormat import com.toasterofbread.spmp.platform.download.DownloadStatus import com.toasterofbread.spmp.platform.download.PlayerDownloadManager import com.toasterofbread.spmp.platform.playerservice.AUTO_DOWNLOAD_SOFT_TIMEOUT -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import dev.toastbits.ytmkt.formats.VideoFormatsEndpoint import dev.toastbits.ytmkt.model.external.YoutubeVideoFormat import kotlinx.coroutines.delay @@ -41,12 +41,12 @@ internal suspend fun getMediaDataSpecPlaybackUri( return@runCatching Uri.parse(local_file.uri) } - val auto_download_enabled: Boolean = context.settings.streaming.AUTO_DOWNLOAD_ENABLED.get() + val auto_download_enabled: Boolean = context.settings.Streaming.AUTO_DOWNLOAD_ENABLED.get() if ( auto_download_enabled - && song.getPlayCount(context.database, 7) >= context.settings.streaming.AUTO_DOWNLOAD_THRESHOLD.get() - && (context.settings.streaming.AUTO_DOWNLOAD_ON_METERED.get() || !context.isConnectionMetered()) + && song.getPlayCount(context.database, 7) >= context.settings.Streaming.AUTO_DOWNLOAD_THRESHOLD.get() + && (context.settings.Streaming.AUTO_DOWNLOAD_ON_METERED.get() || !context.isConnectionMetered()) && !MediaItemLibrary.song_sync_in_progress ) { var done: Boolean = false diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/AudioDeviceCallback.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/AudioDeviceCallback.kt index 234f8d981..9a0684004 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/AudioDeviceCallback.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/AudioDeviceCallback.kt @@ -4,7 +4,6 @@ import android.media.AudioDeviceCallback import android.media.AudioDeviceInfo import android.os.Build import androidx.media3.common.Player -import com.toasterofbread.spmp.model.settings.category.PlayerSettings import kotlinx.coroutines.launch internal class PlayerAudioDeviceCallback( @@ -33,8 +32,8 @@ internal class PlayerAudioDeviceCallback( } service.coroutine_scope.launch { - val resume_on_bt: Boolean = service.context.settings.player.RESUME_ON_BT_CONNECT.get() - val resume_on_wired: Boolean = service.context.settings.player.RESUME_ON_WIRED_CONNECT.get() + val resume_on_bt: Boolean = service.context.settings.Player.RESUME_ON_BT_CONNECT.get() + val resume_on_wired: Boolean = service.context.settings.Player.RESUME_ON_WIRED_CONNECT.get() for (device in addedDevices) { if ((resume_on_bt && isBluetoothAudio(device)) || (resume_on_wired && isWiredAudio(device))) { @@ -51,8 +50,8 @@ internal class PlayerAudioDeviceCallback( } service.coroutine_scope.launch { - val pause_on_bt: Boolean = service.context.settings.player.PAUSE_ON_BT_DISCONNECT.get() - val pause_on_wired: Boolean = service.context.settings.player.PAUSE_ON_WIRED_DISCONNECT.get() + val pause_on_bt: Boolean = service.context.settings.Player.PAUSE_ON_BT_DISCONNECT.get() + val pause_on_wired: Boolean = service.context.settings.Player.PAUSE_ON_WIRED_DISCONNECT.get() for (device in removedDevices) { if ((pause_on_bt && isBluetoothAudio(device)) || (pause_on_wired && isWiredAudio(device))) { diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ExoPlayerUtils.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ExoPlayerUtils.kt index a36cdb262..af2ff1051 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ExoPlayerUtils.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ExoPlayerUtils.kt @@ -39,7 +39,7 @@ fun ExoMediaItem.toSong(): Song = SongRef(mediaMetadata.artworkUri.toString()) internal suspend fun LoudnessEnhancer.update(song: Song?, context: AppContext) { - if (song == null || !context.settings.streaming.ENABLE_AUDIO_NORMALISATION.get()) { + if (song == null || !context.settings.Streaming.ENABLE_AUDIO_NORMALISATION.get()) { enabled = false return } diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ForegroundPlayerService.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ForegroundPlayerService.kt index 1db92c696..9c937c160 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ForegroundPlayerService.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ForegroundPlayerService.kt @@ -27,8 +27,8 @@ import com.toasterofbread.spmp.platform.visualiser.FFTAudioProcessor import com.toasterofbread.spmp.platform.visualiser.MusicVisualiser import com.toasterofbread.spmp.service.playercontroller.RadioHandler import com.toasterofbread.spmp.widget.WidgetUpdateListener -import dev.toastbits.composekit.platform.PlatformPreferencesListener -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.settings.PlatformSettingsListener +import dev.toastbits.composekit.util.platform.launchSingle import dev.toastbits.spms.player.shouldRepeatOnSeekToPrevious import dev.toastbits.spms.socketapi.shared.SpMsPlayerRepeatMode import dev.toastbits.spms.socketapi.shared.SpMsPlayerState @@ -71,32 +71,32 @@ open class ForegroundPlayerService( private lateinit var widget_update_listener: WidgetUpdateListener private val audio_device_callback: PlayerAudioDeviceCallback = PlayerAudioDeviceCallback(this) - private val prefs_listener: PlatformPreferencesListener = - PlatformPreferencesListener { key -> + private val prefs_listener: PlatformSettingsListener = + PlatformSettingsListener { key -> when (key) { - context.settings.streaming.ENABLE_AUDIO_NORMALISATION.key -> { + context.settings.Streaming.ENABLE_AUDIO_NORMALISATION.key -> { coroutine_scope.launch { loudness_enhancer?.update(current_song, context) } } - context.settings.streaming.ENABLE_SILENCE_SKIPPING.key -> { + context.settings.Streaming.ENABLE_SILENCE_SKIPPING.key -> { coroutine_scope.launch { - audio_sink.skipSilenceEnabled = context.settings.streaming.ENABLE_SILENCE_SKIPPING.get() + audio_sink.skipSilenceEnabled = context.settings.Streaming.ENABLE_SILENCE_SKIPPING.get() } } - context.settings.behaviour.REPEAT_SONG_ON_PREVIOUS_THRESHOLD_S.key -> { + context.settings.Behaviour.REPEAT_SONG_ON_PREVIOUS_THRESHOLD_S.key -> { coroutine_scope.launch { updateRepeatSongOnPreviousThreshold() } } - context.settings.experimental.ANDROID_MONET_COLOUR_ENABLE.key -> { + context.settings.Experimental.ANDROID_MONET_COLOUR_ENABLE.key -> { startColorblendrHeartbeatLoop() } } } private suspend fun updateRepeatSongOnPreviousThreshold() { - val threshold_s: Float = context.settings.behaviour.REPEAT_SONG_ON_PREVIOUS_THRESHOLD_S.get() + val threshold_s: Float = context.settings.Behaviour.REPEAT_SONG_ON_PREVIOUS_THRESHOLD_S.get() if (threshold_s < 0f) { repeat_song_on_previous_threshold = null } @@ -226,7 +226,7 @@ open class ForegroundPlayerService( super.onTaskRemoved(intent) coroutine_scope.launch { - if (context.settings.behaviour.STOP_PLAYER_ON_APP_CLOSE.get()) { + if (context.settings.Behaviour.STOP_PLAYER_ON_APP_CLOSE.get()) { stop() } } @@ -242,7 +242,7 @@ open class ForegroundPlayerService( } private fun startColorblendrHeartbeatLoop() = colorblendr_coroutine_scope.launchSingle { - if (!context.settings.experimental.ANDROID_MONET_COLOUR_ENABLE.get()) { + if (!context.settings.Experimental.ANDROID_MONET_COLOUR_ENABLE.get()) { return@launchSingle } diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/HeadlessExternalPlayerService.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/HeadlessExternalPlayerService.kt index 336f2f57f..8c907446e 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/HeadlessExternalPlayerService.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/HeadlessExternalPlayerService.kt @@ -21,7 +21,7 @@ internal class HeadlessExternalPlayerService: ExternalPlayerService(plays_audio override fun PersistentContent(requestServiceChange: (PlayerServiceCompanion) -> Unit) { val player: PlayerState = LocalPlayerState.current val launch_arguments: ProgramArguments = LocalProgramArguments.current - val ui_only: Boolean by player.settings.platform.EXTERNAL_SERVER_MODE_UI_ONLY.observe() + val ui_only: Boolean by player.settings.Platform.EXTERNAL_SERVER_MODE_UI_ONLY.observe() LaunchedEffect(ui_only) { if (!ui_only && PlatformExternalPlayerService.isAvailable(player.context, launch_arguments)) { requestServiceChange(PlatformExternalPlayerService.Companion) diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/MediaDataSpecProcessor.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/MediaDataSpecProcessor.kt index a4402df64..4aeaa71e2 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/MediaDataSpecProcessor.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/MediaDataSpecProcessor.kt @@ -9,7 +9,7 @@ import com.toasterofbread.spmp.model.settings.category.VideoFormatsEndpointType import com.toasterofbread.spmp.model.settings.category.instantiate import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.getMediaDataSpecPlaybackUri -import dev.toastbits.composekit.platform.PlatformPreferencesListener +import dev.toastbits.composekit.settings.PlatformSettingsListener import kotlinx.coroutines.runBlocking import java.io.IOException @@ -17,11 +17,11 @@ import java.io.IOException internal class MediaDataSpecProcessor(private val context: AppContext) { private var current_endpoint: VideoFormatsEndpointType? = null - private val prefs_listener: PlatformPreferencesListener = - PlatformPreferencesListener { key -> + private val prefs_listener: PlatformSettingsListener = + PlatformSettingsListener { key -> when (key) { - context.settings.streaming.ENABLE_VIDEO_FORMAT_FALLBACK.key, - context.settings.streaming.VIDEO_FORMATS_METHOD.key -> current_endpoint = null + context.settings.Streaming.ENABLE_VIDEO_FORMAT_FALLBACK.key, + context.settings.Streaming.VIDEO_FORMATS_METHOD.key -> current_endpoint = null } } @@ -36,7 +36,7 @@ internal class MediaDataSpecProcessor(private val context: AppContext) { suspend fun processMediaDataSpec(data_spec: DataSpec): DataSpec { val endpoint: VideoFormatsEndpointType = current_endpoint - ?: context.settings.streaming.VIDEO_FORMATS_METHOD.get().also { current_endpoint = it } + ?: context.settings.Streaming.VIDEO_FORMATS_METHOD.get().also { current_endpoint = it } val uri: Uri = getMediaDataSpecPlaybackUri( @@ -56,7 +56,7 @@ internal class MediaDataSpecProcessor(private val context: AppContext) { current_endpoint?.also { runBlocking { - if (context.settings.streaming.ENABLE_VIDEO_FORMAT_FALLBACK.get()) { + if (context.settings.Streaming.ENABLE_VIDEO_FORMAT_FALLBACK.get()) { current_endpoint = it.getNext() } } diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlatformExternalPlayerService.android.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlatformExternalPlayerService.android.kt index cf8f0641c..9470d5452 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlatformExternalPlayerService.android.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlatformExternalPlayerService.android.kt @@ -51,7 +51,7 @@ actual class PlatformExternalPlayerService: ForegroundPlayerService(play_when_re override fun PersistentContent(requestServiceChange: (PlayerServiceCompanion) -> Unit) { val player: PlayerState = LocalPlayerState.current val launch_arguments: ProgramArguments = LocalProgramArguments.current - val ui_only: Boolean by player.settings.platform.EXTERNAL_SERVER_MODE_UI_ONLY.observe() + val ui_only: Boolean by player.settings.Platform.EXTERNAL_SERVER_MODE_UI_ONLY.observe() LaunchedEffect(ui_only) { if (ui_only && PlatformExternalPlayerService.isAvailable(player.context, launch_arguments)) { requestServiceChange(PlatformExternalPlayerService.Companion) @@ -245,7 +245,7 @@ actual class PlatformExternalPlayerService: ForegroundPlayerService(play_when_re onConnected: (PlayerService) -> Unit, onDisconnected: () -> Unit ): Any { - if (context.settings.platform.EXTERNAL_SERVER_MODE_UI_ONLY.get()) { + if (context.settings.Platform.EXTERNAL_SERVER_MODE_UI_ONLY.get()) { require(instance is ExternalPlayerService?) val service: ExternalPlayerService = if (instance != null) instance.also { it.setContext(context) } diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/initialiseSessionAndPlayer.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/initialiseSessionAndPlayer.kt index f35931441..5a2d69d26 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/initialiseSessionAndPlayer.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/initialiseSessionAndPlayer.kt @@ -5,7 +5,6 @@ import android.os.Handler import androidx.annotation.OptIn import androidx.media3.common.AudioAttributes import androidx.media3.common.C -import androidx.media3.common.Player import androidx.media3.common.audio.SonicAudioProcessor import androidx.media3.common.util.UnstableApi import androidx.media3.exoplayer.ExoPlayer @@ -43,7 +42,7 @@ internal fun ForegroundPlayerService.initialiseSessionAndPlayer( ) .build() - audio_sink.skipSilenceEnabled = context.settings.streaming.ENABLE_SILENCE_SKIPPING.get() + audio_sink.skipSilenceEnabled = context.settings.Streaming.ENABLE_SILENCE_SKIPPING.get() val renderers_factory: RenderersFactory = RenderersFactory { handler: Handler?, _, audioListener: AudioRendererEventListener?, _, _ -> diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/notification/NotificationStateManager.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/notification/NotificationStateManager.kt index 6ee9504e9..9f0e5ffd7 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/notification/NotificationStateManager.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/notification/NotificationStateManager.kt @@ -6,7 +6,7 @@ import android.os.SystemClock import androidx.media3.common.Player import com.toasterofbread.spmp.platform.playerservice.PlayerServiceNotificationCustomAction import com.toasterofbread.spmp.ui.getAndroidIcon -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.util.platform.launchSingle import dev.toastbits.ytmkt.model.external.SongLikedStatus import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/notification/PlayerServiceNotificationManager.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/notification/PlayerServiceNotificationManager.kt index b5a18d1f5..da41eee96 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/notification/PlayerServiceNotificationManager.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/notification/PlayerServiceNotificationManager.kt @@ -26,8 +26,8 @@ import com.toasterofbread.spmp.platform.playerservice.ForegroundPlayerService import com.toasterofbread.spmp.platform.playerservice.formatMediaNotificationImage import com.toasterofbread.spmp.platform.playerservice.toSong import com.toasterofbread.spmp.shared.R -import dev.toastbits.composekit.platform.isAppInForeground -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.context.isAppInForeground +import dev.toastbits.composekit.util.platform.launchSingle import dev.toastbits.spms.socketapi.shared.SpMsPlayerState import dev.toastbits.ytmkt.model.external.ThumbnailProvider import kotlinx.coroutines.CoroutineScope diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/NotifImageOverlayMenu.android.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/NotifImageOverlayMenu.android.kt index 1928d37c4..b57dcdad1 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/NotifImageOverlayMenu.android.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/NotifImageOverlayMenu.android.kt @@ -41,8 +41,8 @@ import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.util.platform.launchSingle +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.platform.playerservice.getMediaNotificationImageMaxOffset import com.toasterofbread.spmp.platform.playerservice.getMediaNotificationImageSize diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/SpMpWidget.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/SpMpWidget.kt index 069307a8e..235c0072b 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/SpMpWidget.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/SpMpWidget.kt @@ -4,11 +4,7 @@ import LocalPlayerState import ProgramArguments import SpMp import android.annotation.SuppressLint -import android.appwidget.AppWidgetManager -import android.content.ComponentName import android.content.Context -import android.content.Intent -import android.content.Intent.FLAG_ACTIVITY_NEW_TASK import android.graphics.Bitmap import androidx.compose.foundation.layout.PaddingValues import androidx.compose.material3.LocalContentColor @@ -26,6 +22,7 @@ import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.text.font.Font import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.LayoutDirection @@ -40,7 +37,6 @@ import androidx.glance.ImageProvider import androidx.glance.action.clickable import androidx.glance.appwidget.AppWidgetId import androidx.glance.appwidget.GlanceAppWidget -import androidx.glance.appwidget.GlanceAppWidgetManager import androidx.glance.appwidget.SizeMode import androidx.glance.appwidget.provideContent import androidx.glance.background @@ -56,27 +52,14 @@ import androidx.glance.layout.size import androidx.glance.layout.wrapContentSize import androidx.glance.unit.ColorProvider import com.toasterofbread.spmp.model.mediaitem.song.Song -import com.toasterofbread.spmp.model.mediaitem.song.updateLiked import com.toasterofbread.spmp.model.settings.category.AccentColourSource -import com.toasterofbread.spmp.model.settings.category.FontMode -import com.toasterofbread.spmp.model.settings.category.observeCurrentTheme import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.platform.observeUiLanguage import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.shared.R import com.toasterofbread.spmp.ui.component.Thumbnail import com.toasterofbread.spmp.ui.layout.nowplaying.ThemeMode -import com.toasterofbread.spmp.util.getToggleTarget import com.toasterofbread.spmp.widget.action.TypeWidgetClickAction import com.toasterofbread.spmp.widget.action.WidgetClickAction -import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClickAction.NONE -import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClickAction.OPEN_SPMP -import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClickAction.OPEN_WIDGET_CONFIG -import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClickAction.PLAY_PAUSE -import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClickAction.SEEK_NEXT -import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClickAction.SEEK_PREVIOUS -import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClickAction.TOGGLE_LIKE -import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClickAction.TOGGLE_VISIBILITY import com.toasterofbread.spmp.widget.action.execute import com.toasterofbread.spmp.widget.component.GlanceText import com.toasterofbread.spmp.widget.component.styledcolumn.GLANCE_STYLED_COLUMN_DEFAULT_SPACING @@ -92,20 +75,24 @@ import com.toasterofbread.spmp.widget.configuration.enum.colour import com.toasterofbread.spmp.widget.configuration.type.TypeConfigurationDefaultsMask import com.toasterofbread.spmp.widget.configuration.type.TypeWidgetConfig import com.toasterofbread.spmp.widget.modifier.systemCornerRadius -import dev.toastbits.composekit.platform.composable.theme.LocalApplicationTheme -import dev.toastbits.composekit.settings.ui.NamedTheme -import dev.toastbits.composekit.settings.ui.ThemeValues -import dev.toastbits.composekit.settings.ui.ThemeValuesData -import dev.toastbits.composekit.utils.common.getThemeColour -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.ytmkt.model.external.SongLikedStatus +import dev.toastbits.composekit.theme.core.ThemeManager +import dev.toastbits.composekit.theme.core.ThemeValues +import dev.toastbits.composekit.theme.core.model.ComposeKitFont +import dev.toastbits.composekit.theme.core.model.ComposeKitFont.Default.font +import dev.toastbits.composekit.theme.core.model.NamedTheme +import dev.toastbits.composekit.theme.core.model.SerialisableTheme +import dev.toastbits.composekit.theme.core.model.ThemeReference +import dev.toastbits.composekit.theme.core.model.ThemeValuesData +import dev.toastbits.composekit.theme.core.provider.ContextThemeProvider +import dev.toastbits.composekit.theme.core.provider.ThemeProvider +import dev.toastbits.composekit.theme.core.ui.LocalComposeKitTheme +import dev.toastbits.composekit.util.getThemeColour +import dev.toastbits.composekit.util.thenIf import dev.toastbits.ytmkt.model.external.ThumbnailProvider import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.cancel import kotlinx.coroutines.launch -import org.jetbrains.compose.resources.FontResource @Suppress("UNCHECKED_CAST") abstract class SpMpWidget>( @@ -128,7 +115,7 @@ abstract class SpMpWidget>( protected val widget_background_colour: Color @Composable - get() = LocalApplicationTheme.current.card.copy(alpha = base_configuration.background_opacity) + get() = LocalComposeKitTheme.current.card.copy(alpha = base_configuration.background_opacity) private val coroutine_scope: CoroutineScope = CoroutineScope(Job()) private var widget_id: Int? by mutableStateOf(null) @@ -143,11 +130,25 @@ abstract class SpMpWidget>( ) ) + private val themeManager: StaticThemeManager = StaticThemeManager(ThemeValuesData.ofSingleColour(Color.Blue)) + + private class StaticThemeManager(initialTheme: ThemeValues): ThemeManager { + var theme: ThemeValues by mutableStateOf(initialTheme) + + override val accent: Color get() = theme.accent + override val background: Color get() = theme.background + override val card: Color get() = theme.card + override val error: Color get() = theme.error + override val onBackground: Color get() = theme.onBackground + + override fun onContextualColourChanged(thumbnailColour: Color?) {} + } + final override suspend fun provideGlance(context: Context, id: GlanceId) { - this.context = AppContext.create(context, coroutine_scope) + this.context = AppContext.create(context, coroutine_scope, themeManager = themeManager) - val np_theme_mode: ThemeMode = this.context.settings.theme.NOWPLAYING_THEME_MODE.get() - val swipe_sensitivity: Float = this.context.settings.player.EXPAND_SWIPE_SENSITIVITY.get() + val np_theme_mode: ThemeMode = this.context.settings.Theme.NOWPLAYING_THEME_MODE.get() + val swipe_sensitivity: Float = this.context.settings.Player.EXPAND_SWIPE_SENSITIVITY.get() provideContent { // Force recomposition @@ -167,10 +168,35 @@ abstract class SpMpWidget>( println("Widget $widget_id update received ($widget_type)") + val custom_themes: List by this@SpMpWidget.context.settings.Theme.CUSTOM_THEMES.observe() + + val theme_reference: ThemeReference = + configuration.base_configuration.theme + ?: this@SpMpWidget.context.settings.Theme.CURRENT_THEME.observe().value + + val themeProvider: ThemeProvider = + object : ContextThemeProvider(this.context) { + override fun getCustomTheme(index: Int): SerialisableTheme? = custom_themes.getOrNull(index) + override fun getCustomThemes(): List = custom_themes + } + + val theme: ThemeValuesData = + ThemeValuesData.of(theme_reference.getTheme(themeProvider)) + .run { + copy( + onBackground = + when (base_configuration.content_colour) { + THEME -> onBackground + LIGHT -> Color.White + DARK -> Color.Black + } + ) + } + CompositionLocalProvider( // App LocalPlayerState provides state, - dev.toastbits.composekit.platform.LocalContext provides this.context, + dev.toastbits.composekit.components.LocalContext provides this.context, // System LocalContext provides context, @@ -178,19 +204,10 @@ abstract class SpMpWidget>( LocalDensity provides Density(context.resources.displayMetrics.density), LocalLayoutDirection provides if (context.resources.getBoolean(R.bool.is_rtl)) LayoutDirection.Rtl else LayoutDirection.Ltr ) { - val theme: NamedTheme by observeCurrentTheme(this.context, base_configuration.theme_index) - - val on_background_colour: Color = - when (base_configuration.content_colour) { - THEME -> theme.theme.on_background - LIGHT -> Color.White - DARK -> Color.Black - } - CompositionLocalProvider( *listOfNotNull( - LocalApplicationTheme provides theme.theme.copy(on_background = on_background_colour), - if (!custom_background) LocalContentColor provides on_background_colour else null + LocalComposeKitTheme provides theme, + if (!custom_background) LocalContentColor provides theme.onBackground else null ).toTypedArray() ) { Box( @@ -210,7 +227,7 @@ abstract class SpMpWidget>( GlanceBorderBox( base_configuration.border_radius_dp.dp, - theme.theme.accent, + theme.accent, GlanceModifier .fillMaxSize() .systemCornerRadius() @@ -288,8 +305,8 @@ abstract class SpMpWidget>( @Composable private fun ObserveConfiguration(widget_id: Int) { val config: SpMpWidgetConfiguration by SpMpWidgetConfiguration.observeForWidget(this.context, widget_type, widget_id) as MutableState> - val base_default: BaseWidgetConfig by context.settings.widget.DEFAULT_BASE_WIDGET_CONFIGURATION.observe() - val type_defaults: Map> by context.settings.widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.observe() + val base_default: BaseWidgetConfig by context.settings.Widget.DEFAULT_BASE_WIDGET_CONFIGURATION.observe() + val type_defaults: Map> by context.settings.Widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.observe() val type_default: TypeWidgetConfig = (type_defaults[widget_type] ?: widget_type.default_config) as TypeWidgetConfig configuration = remember(config, base_default, type_default) { @@ -325,9 +342,8 @@ abstract class SpMpWidget>( alpha: Float = 1f, max_width: Dp? = null ) { - val ui_language: String by context.observeUiLanguage() - val app_font_mode: FontMode by context.settings.system.FONT.observe() - val font: FontResource? = (base_configuration.font ?: app_font_mode).getFontResource(ui_language) + val app_font_mode: ComposeKitFont by context.settings.Interface.FONT.observe() + val font: Font? = (base_configuration.font ?: app_font_mode).rememberFont() GlanceText( text = text, @@ -339,6 +355,16 @@ abstract class SpMpWidget>( ) } + @Composable + private fun ComposeKitFont.rememberFont(): Font? = + when (this) { + ComposeKitFont.System -> null + is ComposeKitFont.BuiltIn -> rememberFont() + is ComposeKitFont.ResolvableFont -> rememberFont() + is ComposeKitFont.Composite -> fonts.first().rememberFont() + is ComposeKitFont.Default -> font.rememberFont() + } + @Composable fun StyledColumn( section_theme_modes: List, @@ -408,8 +434,8 @@ abstract class SpMpWidget>( song.Thumbnail( ThumbnailProvider.Quality.HIGH, contentOverride = { - val theme: ThemeValues = LocalApplicationTheme.current - val app_accent_source: AccentColourSource by context.settings.theme.ACCENT_COLOUR_SOURCE.observe() + val theme: ThemeValues = LocalComposeKitTheme.current + val app_accent_source: AccentColourSource by context.settings.Theme.ACCENT_COLOUR_SOURCE.observe() val current_accent: Color = when (base_configuration.accent_colour_source ?: app_accent_source) { AccentColourSource.THEME -> theme.accent @@ -421,7 +447,7 @@ abstract class SpMpWidget>( } CompositionLocalProvider( - LocalApplicationTheme provides ThemeValuesData.of(theme).copy(accent = current_accent) + LocalComposeKitTheme provides ThemeValuesData.of(theme).copy(accent = current_accent) ) { content(song, it?.asAndroidBitmap()) } diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceActionButton.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceActionButton.kt index 81179054f..17538a763 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceActionButton.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceActionButton.kt @@ -27,10 +27,10 @@ import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClick import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClickAction.SEEK_PREVIOUS import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClickAction.TOGGLE_LIKE import com.toasterofbread.spmp.widget.action.WidgetClickAction.CommonWidgetClickAction.TOGGLE_VISIBILITY -import dev.toastbits.composekit.platform.composable.theme.LocalApplicationTheme -import dev.toastbits.composekit.settings.ui.vibrant_accent -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.common.getValue +import dev.toastbits.composekit.theme.core.ui.LocalComposeKitTheme +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.composable.getValue import dev.toastbits.ytmkt.model.external.SongLikedStatus @Composable @@ -38,7 +38,7 @@ internal fun CommonActionButton( action: WidgetClickAction, modifier: GlanceModifier = GlanceModifier, icon_modifier: GlanceModifier = GlanceModifier, - background_colour: Color = LocalApplicationTheme.current.vibrant_accent, + background_colour: Color = LocalComposeKitTheme.current.vibrantAccent, getTypeActionIcon: (T) -> Int? ) { Box( diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceActionButtonGrid.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceActionButtonGrid.kt index a3d52b0cd..12fd057a8 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceActionButtonGrid.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceActionButtonGrid.kt @@ -16,8 +16,8 @@ import com.toasterofbread.spmp.widget.action.TypeWidgetClickAction import com.toasterofbread.spmp.widget.action.WidgetClickAction import com.toasterofbread.spmp.widget.component.styledcolumn.GLANCE_STYLED_COLUMN_DEFAULT_SPACING import com.toasterofbread.spmp.widget.modifier.size -import dev.toastbits.composekit.platform.composable.theme.LocalApplicationTheme -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.theme.core.ui.LocalComposeKitTheme +import dev.toastbits.composekit.theme.core.vibrantAccent enum class GlanceActionButtonGridMode { FILL, @@ -50,7 +50,7 @@ fun GlanceActionButtonGrid( button_modifier: GlanceModifier = GlanceModifier, spacing: Dp = GLANCE_STYLED_COLUMN_DEFAULT_SPACING, alignment: Alignment = Alignment.Center, - button_background_colour: Color = LocalApplicationTheme.current.vibrant_accent + button_background_colour: Color = LocalComposeKitTheme.current.vibrantAccent ) { val button_size: DpSize = mode.getButtonSize(size, spacing) val button_icon_size: Dp = minOf(button_size.width, button_size.height) * 0.37f diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceLargePlayPauseButton.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceLargePlayPauseButton.kt index a6bfe64a2..270ada4ce 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceLargePlayPauseButton.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceLargePlayPauseButton.kt @@ -12,19 +12,19 @@ import androidx.glance.layout.Alignment import androidx.glance.layout.Box import com.toasterofbread.spmp.shared.R import com.toasterofbread.spmp.widget.action.PlayPauseAction -import dev.toastbits.composekit.platform.composable.theme.LocalApplicationTheme -import dev.toastbits.composekit.settings.ui.ThemeValues -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.theme.core.ui.LocalComposeKitTheme +import dev.toastbits.composekit.theme.core.ThemeValues +import dev.toastbits.composekit.theme.core.vibrantAccent @Composable internal fun GlanceLargePlayPauseButton( play: Boolean, modifier: GlanceModifier = GlanceModifier ) { - val theme: ThemeValues = LocalApplicationTheme.current + val theme: ThemeValues = LocalComposeKitTheme.current Box( modifier - .background(theme.vibrant_accent) + .background(theme.vibrantAccent) .cornerRadius(10.dp) .clickable( PlayPauseAction(play) diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceLazyColumn.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceLazyColumn.kt index 23cf19118..252fc3921 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceLazyColumn.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceLazyColumn.kt @@ -7,7 +7,7 @@ import androidx.glance.appwidget.lazy.LazyListScope import androidx.glance.layout.Spacer import androidx.glance.layout.height import com.toasterofbread.spmp.widget.modifier.padding -import dev.toastbits.composekit.utils.modifier.horizontal +import dev.toastbits.composekit.components.utils.modifier.horizontal @Composable internal fun GlanceLazyColumn(content_padding: PaddingValues, modifier: GlanceModifier, content: LazyListScope.() -> Unit) { diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceText.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceText.kt index 03aa1f2a0..2c17d3c5a 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceText.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/GlanceText.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.text.font.Font import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.sp @@ -31,13 +32,13 @@ import org.jetbrains.compose.resources.FontResource internal fun GlanceText( text: String, modifier: GlanceModifier = GlanceModifier, - font: FontResource? = null, + font: Font? = null, font_size: TextUnit = 15.sp, colour: Color = LocalContentColor.current, max_width: Dp? = null ) { val context: Context = LocalContext.current - val typeface: Typeface? = font?.let { Font(it) }?.toAndroidTypeface() + val typeface: Typeface? = font?.toAndroidTypeface() val max_width_px: Int? = with (LocalDensity.current) { max_width?.roundToPx() diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/spmp/GlanceSongPreview.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/spmp/GlanceSongPreview.kt index 832cd9658..52c7ce687 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/spmp/GlanceSongPreview.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/spmp/GlanceSongPreview.kt @@ -16,7 +16,7 @@ import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.widget.SpMpWidget -import dev.toastbits.composekit.utils.common.getValue +import dev.toastbits.composekit.util.composable.getValue import dev.toastbits.ytmkt.model.external.ThumbnailProvider @Composable diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/styledcolumn/GlanceStyledColumn.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/styledcolumn/GlanceStyledColumn.kt index 2de95173c..edecb9ed4 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/styledcolumn/GlanceStyledColumn.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/component/styledcolumn/GlanceStyledColumn.kt @@ -29,8 +29,8 @@ import com.toasterofbread.spmp.widget.configuration.enum.WidgetSectionTheme import com.toasterofbread.spmp.widget.configuration.enum.WidgetStyledBorderMode import com.toasterofbread.spmp.widget.configuration.enum.colour import com.toasterofbread.spmp.widget.modifier.padding -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.wave.wavePath +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.composable.wave.wavePath val GLANCE_STYLED_COLUMN_DEFAULT_SPACING: Dp = 12.dp @@ -117,7 +117,7 @@ private fun ColumnWaveBorder( ) val bottom_wave_path: Path = Path() - wavePath( + com.toasterofbread.spmp.ui.util.wavePath( path = bottom_wave_path, size = image_size, waves = 9, @@ -153,7 +153,7 @@ private fun Canvas.drawWave( fill_direction: Int = 0 ) { val path: Path = Path() - wavePath( + com.toasterofbread.spmp.ui.util.wavePath( path = path, size = wave_size, waves = waves, diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/BasicControlsWidget.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/BasicControlsWidget.kt index 6487e428f..6f19ceeb9 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/BasicControlsWidget.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/BasicControlsWidget.kt @@ -43,7 +43,7 @@ package com.toasterofbread.spmp.widget.impl // // val on_background_colour: Color = // when (configuration.base_configuration.content_colour) { -// THEME -> theme.theme.on_background +// THEME -> theme.theme.onBackground // LIGHT -> Color.White // DARK -> Color.Black // } @@ -67,7 +67,7 @@ package com.toasterofbread.spmp.widget.impl // onClick = {}, // colors = ButtonDefaults.buttonColors( // backgroundColor = ColorProvider(theme.theme.accent), -// contentColor = ColorProvider(theme.theme.on_accent) +// contentColor = ColorProvider(theme.theme.onAccent) // ) // ) // } diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/LyricsWidget.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/LyricsWidget.kt index 0c06aa65f..06bf3faec 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/LyricsWidget.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/LyricsWidget.kt @@ -77,7 +77,7 @@ internal abstract class LyricsWidget: SpMpWidget - LocalPlayerState.current.settings.lyrics.DEFAULT_FURIGANA.observe().value + LocalPlayerState.current.settings.Lyrics.DEFAULT_FURIGANA.observe().value LyricsWidgetConfig.FuriganaMode.SHOW -> true diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/SongQueueWidget.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/SongQueueWidget.kt index 59aaf5d7a..8299b6eda 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/SongQueueWidget.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/SongQueueWidget.kt @@ -19,7 +19,7 @@ import com.toasterofbread.spmp.widget.component.GlanceLazyColumn import com.toasterofbread.spmp.widget.configuration.type.SongQueueWidgetConfig import com.toasterofbread.spmp.widget.action.QueueSeekAction import com.toasterofbread.spmp.widget.component.spmp.GlanceSongPreview -import dev.toastbits.composekit.utils.common.thenIf +import dev.toastbits.composekit.util.thenIf import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.widget_empty_status_nothing_playing diff --git a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/SplitImageControlsWidget.kt b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/SplitImageControlsWidget.kt index 159d3e578..e05bb7d00 100644 --- a/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/SplitImageControlsWidget.kt +++ b/shared/src/androidMain/kotlin/com/toasterofbread/spmp/widget/impl/SplitImageControlsWidget.kt @@ -41,10 +41,10 @@ import com.toasterofbread.spmp.widget.component.styledcolumn.GLANCE_STYLED_COLUM import com.toasterofbread.spmp.widget.configuration.enum.WidgetSectionTheme import com.toasterofbread.spmp.widget.configuration.type.SplitImageControlsWidgetConfig import com.toasterofbread.spmp.widget.modifier.systemCornerRadius -import dev.toastbits.composekit.platform.composable.theme.LocalApplicationTheme -import dev.toastbits.composekit.settings.ui.vibrant_accent -import dev.toastbits.composekit.utils.common.blendWith -import dev.toastbits.composekit.utils.common.getValue +import dev.toastbits.composekit.theme.core.ui.LocalComposeKitTheme +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.blendWith +import dev.toastbits.composekit.util.composable.getValue import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.widget_empty_status_nothing_playing @@ -104,8 +104,8 @@ internal class SplitImageControlsWidget: SpMpWidget - with(LocalApplicationTheme.current) { - accent.blendWith(on_background, 0.35f) + with(LocalComposeKitTheme.current) { + accent.blendWith(onBackground, 0.35f) } WidgetSectionTheme.Mode.ACCENT, WidgetSectionTheme.Mode.TRANSPARENT -> LocalContentColor.current @@ -207,7 +207,7 @@ internal class SplitImageControlsWidget: SpMpWidget LocalApplicationTheme.current.vibrant_accent + WidgetSectionTheme.Mode.TRANSPARENT -> LocalComposeKitTheme.current.vibrantAccent WidgetSectionTheme.Mode.ACCENT -> widget_background_colour.copy(alpha = 1f) }, diff --git a/shared/src/commonMain/composeResources/font/LICENSE-hc-maru-gothic b/shared/src/commonMain/composeResources/font/LICENSE-hc-maru-gothic deleted file mode 100644 index 3f0c8cac2..000000000 --- a/shared/src/commonMain/composeResources/font/LICENSE-hc-maru-gothic +++ /dev/null @@ -1,48 +0,0 @@ -=========================================================================== - -【フォント名】 HC丸ゴシック, HCP丸ゴシック -【日本語書体名】 HC丸ゴシック, HCP丸ゴシック -【英語書体名】 HC Maru Gothic, HCP Maru Gothic -【制作者】 蓬莱和多流 -【著作権者】 元とした各フォントの制作者 -【配布責任者】 蓬莱和多流 -【形式】 TrueType等幅・ビットマップ無し - TrueTypeプロポーショナル・ビットマップ無し -【収録文字数】 約8000 -【縦書きの可否】 不可 -【使用許諾条件】 後述 -【改変】 可 -【再配布】 可 -【初版公開日】 2009年06月24日 -【公開日】 2009年07月13日 -【連絡先】 horaiwataru@gmail.com -【Version】 0.802 - -=========================================================================== - -【概要】 - 当フォントはぬかみそフォント(nukamiso_komenuka [Version beta05])に - 花園丸ゴシック(仮称)のグリフと梅ゴシックO5のグリフを追加したフォントです。 - 花園丸ゴシック(仮称)については全グリフの座標をオリジナルのものから仮想ボディ - の3/32(4096に対し384)ほどY軸方向にプラスしています。 - プロポーショナルフォントについてはぬかみそフォントの基本ラテンの箇所 - (unicode:0021-007E)を製作者により手作業で編集しています。 - なおフォント名の"HC"は"蓬莱和多流カスタム"の意味です。 - -【使用許諾条件】 - 使用している個々のフォントのライセンスに従います。 - 詳細はフォントに同梱の以下のフォルダ配下のドキュメントまたはURLを参照願います。 - - ぬかみそフォント : (フォルダ)docs-nukamiso - 花園丸ゴシック(仮称): http://glyphwiki.org/wiki/GlyphWiki:%E3%83%87%E3%83%BC%E3%82%BF%E3%83%BB%E8%A8%98%E4%BA%8B%E3%81%AE%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9 - 梅ゴシックO5 : (フォルダ)docs-ume - -【元フォントの配布元】 - ぬかみそフォント : http://www.h7.dion.ne.jp/‾beta-rev/about/about.html - 花園丸ゴシック(仮称): http://www.mars.dti.ne.jp/glyph/fonts.html - 梅ゴシックO5 : http://sourceforge.jp/projects/ume-font/wiki/FrontPage - -【更新情報】 -0.800 新規作成 -0.801 ドキュメントの訂正(初版公開日等) -0.802 縦書きグリフのオーバーラップ輪郭を削除 diff --git a/shared/src/commonMain/composeResources/font/hc-maru-gothic.ttf b/shared/src/commonMain/composeResources/font/hc-maru-gothic.ttf deleted file mode 100644 index ebb6cd006..000000000 Binary files a/shared/src/commonMain/composeResources/font/hc-maru-gothic.ttf and /dev/null differ diff --git a/shared/src/commonMain/composeResources/values-es-rUS/strings.xml b/shared/src/commonMain/composeResources/values-es-rUS/strings.xml index 4f4863e02..92da51164 100644 --- a/shared/src/commonMain/composeResources/values-es-rUS/strings.xml +++ b/shared/src/commonMain/composeResources/values-es-rUS/strings.xml @@ -280,8 +280,8 @@ Calidad de audio de la transmisión Trata los sencillos de los artistas como una canción. Cadenas no localizadas - Del tema - De la miniatura + Del tema + De la miniatura Alto Bajo Medio diff --git a/shared/src/commonMain/composeResources/values-fr-rFR/strings.xml b/shared/src/commonMain/composeResources/values-fr-rFR/strings.xml index 813a9db7c..f5f7e6647 100644 --- a/shared/src/commonMain/composeResources/values-fr-rFR/strings.xml +++ b/shared/src/commonMain/composeResources/values-fr-rFR/strings.xml @@ -457,8 +457,8 @@ Aperçu Couleur d'accent - À partir du thème - À partir de la miniature + À partir du thème + À partir de la miniature Mode de thème de lecture en cours Fond de couleur avec accent diff --git a/shared/src/commonMain/composeResources/values-ja-rJP/strings.xml b/shared/src/commonMain/composeResources/values-ja-rJP/strings.xml index ed3b289e8..c183db0be 100644 --- a/shared/src/commonMain/composeResources/values-ja-rJP/strings.xml +++ b/shared/src/commonMain/composeResources/values-ja-rJP/strings.xml @@ -479,8 +479,8 @@ プレビュー アクセント色 - テーマから - サムネイルから + テーマから + サムネイルから 再生画面テーマモード バックグラウンドをアクセント色で彩る @@ -941,7 +941,7 @@ 明るいアクセント カード 背景の上 - アクセントの上 + アクセントの上 エラー なし @@ -1072,7 +1072,7 @@ テーマ アクセント色のソース - アプリの設定 + アプリの設定 フォント フォントサイズ アプリの設定 diff --git a/shared/src/commonMain/composeResources/values-pl-rPL/strings.xml b/shared/src/commonMain/composeResources/values-pl-rPL/strings.xml index 7b9922380..307ba1a15 100644 --- a/shared/src/commonMain/composeResources/values-pl-rPL/strings.xml +++ b/shared/src/commonMain/composeResources/values-pl-rPL/strings.xml @@ -301,8 +301,8 @@ Edytuj motyw Kolor akcentu - Z motywu - Z miniatury obrazu + Z motywu + Z miniatury obrazu Obecnie odtwarzany tryb tematyczny Kolor tła z akcentem diff --git a/shared/src/commonMain/composeResources/values-ru-rRU/strings.xml b/shared/src/commonMain/composeResources/values-ru-rRU/strings.xml index fad0af88f..935ae5940 100644 --- a/shared/src/commonMain/composeResources/values-ru-rRU/strings.xml +++ b/shared/src/commonMain/composeResources/values-ru-rRU/strings.xml @@ -459,8 +459,8 @@ Превью Цвет акцента - Из темы - Из превью трека + Из темы + Из превью трека Мод темы текущего воспроизведения Красить фон в цвет акцента diff --git a/shared/src/commonMain/composeResources/values-tr-rTR/strings.xml b/shared/src/commonMain/composeResources/values-tr-rTR/strings.xml index 228d20fed..8786130ce 100644 --- a/shared/src/commonMain/composeResources/values-tr-rTR/strings.xml +++ b/shared/src/commonMain/composeResources/values-tr-rTR/strings.xml @@ -480,8 +480,8 @@ Önizleme Vurgu rengi - Temadan - Küçük resimden + Temadan + Küçük resimden Şu an çalan tema modu Arka planı vurgu rengi ile renklendir diff --git a/shared/src/commonMain/composeResources/values-zh-rCN/strings.xml b/shared/src/commonMain/composeResources/values-zh-rCN/strings.xml index 6bb81f996..bab476b7d 100644 --- a/shared/src/commonMain/composeResources/values-zh-rCN/strings.xml +++ b/shared/src/commonMain/composeResources/values-zh-rCN/strings.xml @@ -444,8 +444,8 @@ 预览 强调色 - 来自主题 - 来自缩略图 + 来自主题 + 来自缩略图 正在播放的主题模式 用强调色彩色背景 diff --git a/shared/src/commonMain/composeResources/values-zh-rTW/strings.xml b/shared/src/commonMain/composeResources/values-zh-rTW/strings.xml index 7e147ea58..435953269 100644 --- a/shared/src/commonMain/composeResources/values-zh-rTW/strings.xml +++ b/shared/src/commonMain/composeResources/values-zh-rTW/strings.xml @@ -472,8 +472,8 @@ 預覽 強調色 - 來自主題 - 來自縮圖 + 來自主題 + 來自縮圖 正在播放的主題模式 使用強調色彩色背景 diff --git a/shared/src/commonMain/composeResources/values/strings.xml b/shared/src/commonMain/composeResources/values/strings.xml index a0ebabf2d..e4fcf8712 100644 --- a/shared/src/commonMain/composeResources/values/strings.xml +++ b/shared/src/commonMain/composeResources/values/strings.xml @@ -216,6 +216,7 @@ Upload to account + Sort type Playlist order Name Duration @@ -266,6 +267,7 @@ No lyrics found No more results + Lyrics source Search for lyrics on $source Loading lyrics Source does not support searching @@ -527,8 +529,8 @@ Preview Accent colour - From theme - From thumbnail + From theme + From thumbnail Now playing theme mode Colour background with accent @@ -996,7 +998,7 @@ Vibrant accent Card On background - On accent + On accent Error None @@ -1127,7 +1129,7 @@ Theme Accent colour source - App setting + App setting Font Font size App setting diff --git a/shared/src/commonMain/kotlin/SpMp.kt b/shared/src/commonMain/kotlin/SpMp.kt index 128547ff6..5ee678e79 100644 --- a/shared/src/commonMain/kotlin/SpMp.kt +++ b/shared/src/commonMain/kotlin/SpMp.kt @@ -1,6 +1,3 @@ -@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") - -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize @@ -20,21 +17,12 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.Modifier -import androidx.compose.ui.input.key.KeyEvent import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.intl.Locale -import androidx.compose.ui.text.intl.platformLocaleDelegate -import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.ProjectBuildConfig import com.toasterofbread.spmp.model.appaction.shortcut.LocalShortcutState import com.toasterofbread.spmp.model.appaction.shortcut.ShortcutState -import com.toasterofbread.spmp.model.settings.category.FontMode import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.platform.ProjectJson -import com.toasterofbread.spmp.platform.observeUiLanguage import com.toasterofbread.spmp.platform.playerservice.ClientServerPlayerService import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.service.playercontroller.openUri @@ -46,30 +34,20 @@ import com.toasterofbread.spmp.ui.layout.loadingsplash.LoadingSplash import com.toasterofbread.spmp.ui.layout.loadingsplash.SplashMode import com.toasterofbread.spmp.ui.layout.nowplaying.PlayerExpansionState import com.toasterofbread.spmp.ui.layout.nowplaying.ThemeMode -import dev.toastbits.composekit.navigation.Screen +import dev.toastbits.composekit.application.ApplicationTheme +import dev.toastbits.composekit.commonsettings.impl.LocalComposeKitSettings +import dev.toastbits.composekit.components.LocalContext import dev.toastbits.composekit.navigation.compositionlocal.LocalNavigator import dev.toastbits.composekit.navigation.navigator.Navigator -import dev.toastbits.composekit.platform.LocalContext -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.PlatformPreferences -import dev.toastbits.composekit.platform.PreferencesGroup -import dev.toastbits.composekit.platform.composable.theme.ApplicationTheme -import dev.toastbits.composekit.settings.ui.SettingsScreen -import dev.toastbits.composekit.settings.ui.ThemeValues -import dev.toastbits.composekit.utils.common.thenIf +import dev.toastbits.composekit.navigation.screen.Screen +import dev.toastbits.composekit.navigation.screen.ScreenButton +import dev.toastbits.composekit.settings.PlatformSettings +import dev.toastbits.composekit.theme.core.ThemeValues +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.util.thenIf import dev.toastbits.spms.socketapi.shared.SPMS_API_VERSION import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import org.jetbrains.compose.resources.ComposeEnvironment -import org.jetbrains.compose.resources.DensityQualifier -import org.jetbrains.compose.resources.Font -import org.jetbrains.compose.resources.FontResource -import org.jetbrains.compose.resources.InternalResourceApi -import org.jetbrains.compose.resources.LanguageQualifier -import org.jetbrains.compose.resources.LocalComposeEnvironment -import org.jetbrains.compose.resources.RegionQualifier -import org.jetbrains.compose.resources.ResourceEnvironment -import org.jetbrains.compose.resources.ThemeQualifier import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.action_close @@ -94,7 +72,7 @@ object SpMp { private set val player_state: PlayerState get() = _player_state!! - val prefs: PlatformPreferences get() = context.getPrefs() + val prefs: PlatformSettings get() = context.getPrefs() private val low_memory_listeners: MutableList<() -> Unit> = mutableListOf() private var window_fullscreen_toggler: (() -> Unit)? = null @@ -107,8 +85,8 @@ object SpMp { launch_arguments: ProgramArguments, composable_coroutine_scope: CoroutineScope ): PlayerState { - val np_theme_mode: ThemeMode = context.settings.theme.NOWPLAYING_THEME_MODE.get() - val swipe_sensitivity: Float = context.settings.player.EXPAND_SWIPE_SENSITIVITY.get() + val np_theme_mode: ThemeMode = context.settings.Theme.NOWPLAYING_THEME_MODE.get() + val swipe_sensitivity: Float = context.settings.Player.EXPAND_SWIPE_SENSITIVITY.get() val player: PlayerState = PlayerState(context, launch_arguments, composable_coroutine_scope, np_theme_mode, swipe_sensitivity) _player_state = player return player @@ -131,6 +109,15 @@ object SpMp { } private val navigator = object : Navigator { + override val currentExtraButtons: List + @Composable + get() = emptyList() + override val currentInfo: String? + @Composable + get() = null + override val currentTitle: String? + @Composable + get() = null override val currentScreen: Screen = Screen.EMPTY @Composable @@ -142,28 +129,56 @@ object SpMp { throw IllegalStateException() } - override fun canNavigateBackward(): Boolean = false - override fun canNavigateForward(): Boolean = false + override fun addHistoryResetListener(listener: Navigator.HistoryResetListener) { + TODO("Not yet implemented") + } + + override fun getNavigateBackwardCount(): Int = 0 + override fun getNavigateForwardCount(): Int = 0 + override fun getMostRecentOfOrNull(predicate: (Screen) -> Boolean): Screen? = null - override fun handleKeyEvent(keyEvent: KeyEvent): Boolean = false override fun navigateBackward(by: Int) { _player_state?.navigateBack() } override fun navigateForward(by: Int) {} override fun peekRelative(offset: Int): Screen? = null - override fun pushScreen(screen: Screen, skipIfSameClass: Boolean) { + override fun pushScreen(screen: Screen) { val player: PlayerState = _player_state ?: return - player.openAppPage(screen.toAppPage(player.app_page_state, this), replace_current = false) + player.openAppPage(screen.toAppPage(player.app_page_state), replace_current = false) + } + + override fun removeHistoryResetListener(listener: Navigator.HistoryResetListener) { + TODO("Not yet implemented") + } + + override fun removeScreens(amount: Int) { + TODO("Not yet implemented") } - override fun replaceScreen(screen: Screen) { + override fun replaceScreen(screen: Screen, inPlace: Boolean) { val player: PlayerState = _player_state ?: return - player.openAppPage(screen.toAppPage(player.app_page_state, this), replace_current = true) + player.openAppPage(screen.toAppPage(player.app_page_state), replace_current = true) + } + + override fun replaceScreenUpTo( + screen: Screen, + inPlace: Boolean, + isLastScreenToReplace: (Screen) -> Boolean + ) { + TODO("Not yet implemented") + } + + override fun clearForwardNavigation() { + TODO("Not yet implemented") + } + + override fun visualise(): String { + TODO("Not yet implemented") } } - private fun Screen.toAppPage(state: AppPageState, navigator: Navigator): AppPage = + private fun Screen.toAppPage(state: AppPageState): AppPage = object : AppPage() { override val state: AppPageState = state @@ -174,15 +189,12 @@ object SpMp { content_padding: PaddingValues, close: () -> Unit ) { - this@toAppPage.Content(navigator, modifier, content_padding) + this@toAppPage.Content(modifier, content_padding) } - override fun onClosed(next_page: AppPage?) { - super.onClosed(next_page) - - if (this@toAppPage is SettingsScreen) { - this@toAppPage.onClosed() - } + override fun onClosed(next_page: AppPage?, going_back: Boolean) { + super.onClosed(next_page, going_back) + this@toAppPage.onClosed(going_back) } } @@ -195,9 +207,6 @@ object SpMp { window_fullscreen_toggler: (() -> Unit)? = null ) { shortcut_state.ObserveState() - if (!context.theme.Update()) { - return - } val coroutine_scope: CoroutineScope = rememberCoroutineScope() @@ -208,9 +217,7 @@ object SpMp { } } - val ui_language: String by context.observeUiLanguage() - - Theme(context, ui_language) { + Theme(context) { LaunchedEffect(open_uri) { if (open_uri != null) { player_state.openUri(open_uri).onFailure { @@ -220,21 +227,18 @@ object SpMp { } Surface(modifier = modifier.fillMaxSize()) { - val ui_scale: Float by context.settings.system.UI_SCALE.observe() - CompositionLocalProvider( LocalPlayerState provides player_state, LocalShortcutState provides shortcut_state, - LocalDensity provides Density(LocalDensity.current.density * ui_scale, 1f), LocalProgramArguments provides arguments, LocalContext provides context, LocalNavigator provides navigator, - LocalComposeEnvironment provides LocalisedComposeEnvironment { ui_language } + LocalComposeKitSettings provides context.settings ) { var mismatched_server_api_version: Int? by remember { mutableStateOf(null) } val splash_mode: SplashMode? = when (Platform.current) { Platform.ANDROID -> { - val external_server_mode: Boolean by player_state.settings.platform.ENABLE_EXTERNAL_SERVER_MODE.observe() + val external_server_mode: Boolean by player_state.settings.Platform.ENABLE_EXTERNAL_SERVER_MODE.observe() if (!player_state.service_connected && external_server_mode) SplashMode.SPLASH else null } @@ -338,43 +342,12 @@ expect fun isWindowTransparencySupported(): Boolean @Composable fun SpMp.Theme( context: AppContext, - ui_language: String, theme: ThemeValues = context.theme, content: @Composable () -> Unit ) { theme.ApplicationTheme( context, - getFontFamily(context, ui_language) ?: FontFamily.Default, - content + context.settings, + content = content ) } - -@Composable -private fun getFontFamily(context: AppContext, ui_language: String): FontFamily? { - val font_mode: FontMode by context.settings.system.FONT.observe() - val font_resource: FontResource? = remember(ui_language, font_mode) { font_mode.getFontResource(ui_language) } - - return font_resource?.let { FontFamily(Font(it)) } -} - -private class LocalisedComposeEnvironment( - private val getUiLanguage: @Composable () -> String -): ComposeEnvironment { - @Composable - @OptIn(InternalResourceApi::class) - override fun rememberEnvironment(): ResourceEnvironment { - val uiLanguage: String = getUiLanguage() - val composeLocale: Locale = remember(uiLanguage) { Locale(platformLocaleDelegate.parseLanguageTag(uiLanguage)) } - val composeTheme: Boolean = isSystemInDarkTheme() - val composeDensity: Density = LocalDensity.current - - return remember(composeLocale, composeTheme, composeDensity) { - ResourceEnvironment( - LanguageQualifier(composeLocale.language), - RegionQualifier(composeLocale.region), - ThemeQualifier.selectByValue(composeTheme), - DensityQualifier.selectByDensity(composeDensity.density) - ) - } - } -} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/UiString.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/UiString.kt index d19593b3f..79bfd726f 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/UiString.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/UiString.kt @@ -13,6 +13,7 @@ import com.toasterofbread.spmp.platform.observeUiLanguage import com.toasterofbread.spmp.resources.Language import com.toasterofbread.spmp.resources.getResourceEnvironment import com.toasterofbread.spmp.service.playercontroller.PlayerState +import dev.toastbits.composekit.util.model.Locale import dev.toastbits.ytmkt.uistrings.RawUiString import dev.toastbits.ytmkt.uistrings.UiString import dev.toastbits.ytmkt.uistrings.YoutubeUiString @@ -38,10 +39,10 @@ data class AppUiString( fun UiString.observe(): String { val player: PlayerState = LocalPlayerState.current var string: String by remember { mutableStateOf("") } - val ui_language: String by player.context.observeUiLanguage() + val ui_language: Locale by player.context.observeUiLanguage() LaunchedEffect(this, ui_language) { - string = getString(ui_language) + string = getString(ui_language.toTag()) } return string @@ -90,7 +91,7 @@ fun UiString.Companion.deserialise(data: String): UiString { } suspend fun UiString.getString(context: AppContext): String = - getString(context.getUiLanguage()) + getString(context.getUiLanguage().toTag()) // companion object { // fun mediaItemPage(key: String, item_type: MediaItemType, context: AppContext, source_language: String = context.getDataLanguage()): UiString = diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/NavigationAppAction.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/NavigationAppAction.kt index 5388241fc..4f6aa9916 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/NavigationAppAction.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/NavigationAppAction.kt @@ -1,23 +1,26 @@ package com.toasterofbread.spmp.model.appaction -import kotlinx.serialization.Serializable -import com.toasterofbread.spmp.ui.layout.apppage.AppPage -import com.toasterofbread.spmp.service.playercontroller.PlayerState -import com.toasterofbread.spmp.model.appaction.AppAction -import com.toasterofbread.spmp.model.appaction.action.navigation.* -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu -import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Row -import androidx.compose.material3.Text import androidx.compose.material3.Button import androidx.compose.material3.Icon -import androidx.compose.ui.Modifier +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp -import androidx.compose.runtime.* -import androidx.compose.animation.AnimatedVisibility +import com.toasterofbread.spmp.model.appaction.action.navigation.AppPageNavigationAction +import com.toasterofbread.spmp.model.appaction.action.navigation.NavigationAction +import com.toasterofbread.spmp.service.playercontroller.PlayerState +import com.toasterofbread.spmp.ui.layout.apppage.AppPage +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu +import kotlinx.serialization.Serializable import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.appaction_config_navigation_action @@ -42,10 +45,11 @@ data class NavigationAppAction( var show_action_selector: Boolean by remember { mutableStateOf(false) } LargeDropdownMenu( - expanded = show_action_selector, + title = stringResource(Res.string.appaction_config_navigation_action), + isOpen = show_action_selector, onDismissRequest = { show_action_selector = false }, - item_count = AppPage.Type.entries.size + NavigationAction.Type.entries.size - 1, - selected = + items = (0 until AppPage.Type.entries.size + NavigationAction.Type.entries.size - 1).toList(), + selectedItem = if (action is AppPageNavigationAction) action.page.ordinal + 1 else action.getType().ordinal - 1, itemContent = { @@ -64,13 +68,13 @@ data class NavigationAppAction( } } }, - onSelected = { + onSelected = { _, item -> val action: NavigationAction - if (it < NavigationAction.Type.entries.size - 1) { - action = NavigationAction.Type.entries[it + 1].createAction() + if (item < NavigationAction.Type.entries.size - 1) { + action = NavigationAction.Type.entries[item + 1].createAction() } else { - action = AppPageNavigationAction(AppPage.Type.entries[it + 1 - NavigationAction.Type.entries.size]) + action = AppPageNavigationAction(AppPage.Type.entries[item + 1 - NavigationAction.Type.entries.size]) } onModification(copy(action = action)) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/OtherAppAction.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/OtherAppAction.kt index dda01ce2b..6e01ce65d 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/OtherAppAction.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/OtherAppAction.kt @@ -1,33 +1,41 @@ package com.toasterofbread.spmp.model.appaction import SpMp -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.FlowRow -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.Alignment -import androidx.compose.ui.unit.dp -import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.foundation.layout.Row +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.Edit +import androidx.compose.material.icons.filled.Fullscreen +import androidx.compose.material.icons.filled.Refresh +import androidx.compose.material.icons.filled.UnfoldLess +import androidx.compose.material.icons.filled.UnfoldMore +import androidx.compose.material3.Button import androidx.compose.material3.Icon import androidx.compose.material3.Text -import androidx.compose.material3.Button -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* -import com.toasterofbread.spmp.model.appaction.AppAction +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.composable.onWindowBackPressed +import dev.toastbits.composekit.components.platform.composable.onWindowBackPressed +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu +import dev.toastbits.composekit.util.platform.Platform import kotlinx.serialization.Serializable import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.appaction_config_other_action +import spmp.shared.generated.resources.appaction_other_action_decrease_ui_scale +import spmp.shared.generated.resources.appaction_other_action_increase_ui_scale import spmp.shared.generated.resources.appaction_other_action_navigate_back -import spmp.shared.generated.resources.appaction_other_action_toggle_fullscreen import spmp.shared.generated.resources.appaction_other_action_reload_page -import spmp.shared.generated.resources.appaction_other_action_increase_ui_scale -import spmp.shared.generated.resources.appaction_other_action_decrease_ui_scale +import spmp.shared.generated.resources.appaction_other_action_toggle_fullscreen @Serializable data class OtherAppAction( @@ -58,22 +66,22 @@ data class OtherAppAction( var show_action_selector: Boolean by remember { mutableStateOf(false) } LargeDropdownMenu( - expanded = show_action_selector, + title =stringResource(Res.string.appaction_config_other_action), + isOpen = show_action_selector, onDismissRequest = { show_action_selector = false }, - item_count = Action.AVAILABLE.size, - selected = action.ordinal, - itemContent = { + items = Action.AVAILABLE, + selectedItem = action, + itemContent = { action -> Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(10.dp) ) { - val action: Action = Action.AVAILABLE[it] Icon(action.getIcon(), null) Text(action.getName()) } }, - onSelected = { - onModification(copy(action = Action.AVAILABLE[it])) + onSelected = { _, action -> + onModification(copy(action = action)) show_action_selector = false } ) @@ -148,8 +156,8 @@ data class OtherAppAction( INCREASE_UI_SCALE, DECREASE_UI_SCALE -> { val delta: Float = if (this == INCREASE_UI_SCALE) 0.1f else -0.1f - val current: Float = player.context.settings.system.UI_SCALE.get() - player.context.settings.system.UI_SCALE.set((current + delta).coerceAtLeast(0.1f)) + val current: Float = player.context.settings.Interface.UI_SCALE.get() + player.context.settings.Interface.UI_SCALE.set((current + delta).coerceAtLeast(0.1f)) } } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/PlaybackAppAction.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/PlaybackAppAction.kt index a5aba20e6..36ac0cbc5 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/PlaybackAppAction.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/PlaybackAppAction.kt @@ -1,19 +1,21 @@ package com.toasterofbread.spmp.model.appaction -import kotlinx.serialization.Serializable -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.compose.ui.Alignment -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.FlowRow -import androidx.compose.material3.Text import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import com.toasterofbread.spmp.model.appaction.action.playback.PlaybackAction import com.toasterofbread.spmp.service.playercontroller.PlayerState -import com.toasterofbread.spmp.model.appaction.action.playback.* -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu +import kotlinx.serialization.Serializable import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.appaction_config_playback_action_type @@ -38,15 +40,16 @@ data class PlaybackAppAction( var show_action_selector: Boolean by remember { mutableStateOf(false) } LargeDropdownMenu( - expanded = show_action_selector, + title = stringResource(Res.string.appaction_config_playback_action_type), + isOpen = show_action_selector, onDismissRequest = { show_action_selector = false }, - item_count = PlaybackAction.Type.entries.size, - selected = action.getType().ordinal, - itemContent = { - PlaybackAction.Type.entries[it].Preview() + items = PlaybackAction.Type.entries, + selectedItem = action.getType(), + itemContent = { action -> + action.Preview() }, - onSelected = { - onModification(copy(action = PlaybackAction.Type.entries[it].createAction())) + onSelected = { _, action -> + onModification(copy(action = action.createAction())) show_action_selector = false } ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/SongAppAction.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/SongAppAction.kt index 1551be897..f8367899a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/SongAppAction.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/SongAppAction.kt @@ -41,8 +41,8 @@ import com.toasterofbread.spmp.platform.download.DownloadStatus import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.LikeDislikeButton import com.toasterofbread.spmp.util.getToggleTarget -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu import dev.toastbits.ytmkt.endpoint.SetSongLikedEndpoint import dev.toastbits.ytmkt.endpoint.SongLikedEndpoint import dev.toastbits.ytmkt.model.external.SongLikedStatus @@ -113,22 +113,22 @@ data class SongAppAction( val available_actions: List = remember { Action.getAvailable(player.context) } LargeDropdownMenu( - expanded = show_action_selector, + title = stringResource(Res.string.appaction_config_song_action), + isOpen = show_action_selector, onDismissRequest = { show_action_selector = false }, - item_count = available_actions.size, - selected = action.ordinal, - itemContent = { + items = available_actions, + selectedItem = action, + itemContent = { action -> Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(10.dp) ) { - val action: Action = available_actions[it] Icon(action.getIcon(), null) Text(action.getName()) } }, - onSelected = { - onModification(copy(action = available_actions[it])) + onSelected = { _, action -> + onModification(copy(action = action)) show_action_selector = false } ) @@ -241,7 +241,7 @@ data class SongAppAction( private suspend fun Song.getCurrentUrl(queue_index: Int, player: PlayerState): String { var url: String = getUrl(player.context) - if (queue_index == player.status.index && player.settings.behaviour.INCLUDE_PLAYBACK_POSITION_IN_SHARE_URL.get()) { + if (queue_index == player.status.index && player.settings.Behaviour.INCLUDE_PLAYBACK_POSITION_IN_SHARE_URL.get()) { val position_ms: Long = player.status.getPositionMs() if (position_ms >= 0) { url += "&t=${position_ms / 1000}" diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/action/navigation/AppPageNavigationAction.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/action/navigation/AppPageNavigationAction.kt index 04b8438b9..5ac54fee7 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/action/navigation/AppPageNavigationAction.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/action/navigation/AppPageNavigationAction.kt @@ -7,13 +7,14 @@ import androidx.compose.runtime.* import androidx.compose.ui.* import androidx.compose.ui.unit.dp import androidx.compose.ui.graphics.vector.ImageVector -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu -import com.toasterofbread.spmp.model.settings.category.SettingsGroup +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu +import com.toasterofbread.spmp.model.settings.SettingsGroup import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.apppage.AppPage import com.toasterofbread.spmp.ui.layout.apppage.settingspage.SettingsAppPage import kotlinx.serialization.Serializable import LocalPlayerState +import dev.toastbits.composekit.settings.ui.screen.PlatformSettingsGroupScreen import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.appaction_config_navigation_settings_group_none @@ -41,8 +42,8 @@ data class AppPageNavigationAction( player.openAppPage(page) if (page is SettingsAppPage && settings_group != null) { - val group_page: SettingsGroup.CategoryPage = player.settings.groupFromKey(settings_group)?.getPage() ?: return - group_page.openPage(player.context) + val group: SettingsGroup = player.settings.groupFromKey(settings_group) ?: return + player.app_page_state.Settings.openGroup(group) } } @@ -62,27 +63,29 @@ data class AppPageNavigationAction( override fun ConfigurationItems(item_modifier: Modifier, onModification: (NavigationAction) -> Unit) { val player: PlayerState = LocalPlayerState.current var show_settings_group_selector: Boolean by remember { mutableStateOf(false) } - val settings_pages: List = remember { player.settings.group_pages } + val settings_pages: List = remember { player.settings.group_pages } LargeDropdownMenu( - expanded = show_settings_group_selector, + title = stringResource(Res.string.appaction_config_navigation_settings_group), + isOpen = show_settings_group_selector, onDismissRequest = { show_settings_group_selector = false }, - item_count = settings_pages.size + 1, - selected = settings_group?.let { group_key -> - settings_pages.indexOfFirst { it.group.group_key == group_key } + 1 - } ?: 0, + items = (0 until settings_pages.size + 1).toList(), + selectedItem = + settings_group?.let { group_key -> + settings_pages.indexOfFirst { it.group.groupKey == group_key } + 1 + } ?: 0, itemContent = { if (it == 0) { Text(stringResource(Res.string.appaction_config_navigation_settings_group_none)) } else { - Text(settings_pages[it - 1].getTitle()) + Text(settings_pages[it - 1].title) } }, - onSelected = { + onSelected = { _, index -> val group_key: String? = - if (it == 0) null - else settings_pages[it - 1].group.group_key + if (index == 0) null + else settings_pages[index - 1].group.groupKey onModification(copy(settings_group = group_key)) show_settings_group_selector = false @@ -107,7 +110,7 @@ data class AppPageNavigationAction( Text(stringResource(Res.string.appaction_config_navigation_settings_group_none)) } else { - Text(settings_pages.first { it.group.group_key == settings_group }.getTitle()) + Text(settings_pages.first { it.group.groupKey == settings_group }.title) } } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutIndicator.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutIndicator.kt index 5c74e0421..f980b7f1a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutIndicator.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutIndicator.kt @@ -21,7 +21,7 @@ fun ShortcutIndicator() { // exit = fadeOut() // ) { // val indicator_colour: Color = - // if (button == current_button) player.theme.on_accent + // if (button == current_button) player.theme.onAccent // else player.theme.accent // Box( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutState.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutState.kt index 730e4a113..617b0eb9e 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutState.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutState.kt @@ -10,11 +10,10 @@ import androidx.compose.runtime.mutableStateListOf import androidx.compose.ui.input.key.Key import androidx.compose.ui.input.key.KeyEvent import androidx.compose.ui.input.key.key -import androidx.compose.ui.input.key.nativeKeyCode import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.shortcut.trigger.KeyboardShortcutTrigger import com.toasterofbread.spmp.ui.component.shortcut.trigger.MouseButtonShortcutTrigger -import dev.toastbits.composekit.utils.common.addUnique +import dev.toastbits.composekit.util.addUnique import kotlinx.coroutines.launch import kotlin.math.roundToLong @@ -40,9 +39,9 @@ class ShortcutState { @Composable fun ObserveState() { val player: PlayerState = LocalPlayerState.current - navigate_song_with_numbers = player.settings.shortcut.NAVIGATE_SONG_WITH_NUMBERS.observe().value + navigate_song_with_numbers = player.settings.Shortcut.NAVIGATE_SONG_WITH_NUMBERS.observe().value - val shortcuts: List? by player.settings.shortcut.CONFIGURED_SHORTCUTS.observe() + val shortcuts: List? by player.settings.Shortcut.CONFIGURED_SHORTCUTS.observe() LaunchedEffect(shortcuts) { val keyboard_shortcuts: MutableList = mutableListOf() val mouse_button_shortcuts: MutableList = mutableListOf() diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutTriggerSelector.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutTriggerSelector.kt index 93c431639..cc73b7e40 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutTriggerSelector.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutTriggerSelector.kt @@ -10,11 +10,12 @@ import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.material3.Button import com.toasterofbread.spmp.ui.component.shortcut.trigger.ShortcutTrigger -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu import com.toasterofbread.spmp.ui.component.shortcut.trigger.getName @Composable fun ShortcutTriggerSelector( + title: String, trigger: ShortcutTrigger? = null, modifier: Modifier = Modifier, onModification: (ShortcutTrigger?) -> Unit @@ -22,15 +23,16 @@ fun ShortcutTriggerSelector( var selecting_type: Boolean by remember { mutableStateOf(false) } LargeDropdownMenu( - selecting_type, - { selecting_type = false }, - ShortcutTrigger.Type.entries.size + 1, - trigger?.getType()?.ordinal?.plus(1) ?: 0, + title = title, + isOpen = selecting_type, + onDismissRequest = { selecting_type = false }, + items = (0 until ShortcutTrigger.Type.entries.size + 1).toList(), + selectedItem = trigger?.getType()?.ordinal?.plus(1) ?: 0, itemContent = { val type: ShortcutTrigger.Type? = if (it == 0) null else ShortcutTrigger.Type.entries[it - 1] type.Preview() }, - onSelected = { type -> + onSelected = { _, type -> if (type == 0) { onModification(null) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutsEditor.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutsEditor.kt index 17c00f1f7..c3cc013aa 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutsEditor.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/ShortcutsEditor.kt @@ -1,14 +1,10 @@ package com.toasterofbread.spmp.model.appaction.shortcut -import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.FlowRow -import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add @@ -20,15 +16,12 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.StickyHeightColumn -import dev.toastbits.composekit.platform.composable.ScrollBarLazyRow +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyRow import com.toasterofbread.spmp.model.appaction.AppAction -import com.toasterofbread.spmp.model.appaction.shortcut.getDefaultShortcuts import com.toasterofbread.spmp.ui.component.shortcut.ShortcutPreview import com.toasterofbread.spmp.service.playercontroller.PlayerState -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json import LocalPlayerState +import dev.toastbits.composekit.components.utils.composable.StickyHeightColumn import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_key_navigate_song_with_numbers @@ -36,14 +29,14 @@ import spmp.shared.generated.resources.s_key_navigate_song_with_numbers @Composable fun ShortcutsEditor(modifier: Modifier = Modifier) { val player: PlayerState = LocalPlayerState.current - var shortcuts: List? by player.settings.shortcut.CONFIGURED_SHORTCUTS.observe() + var shortcuts: List? by player.settings.Shortcut.CONFIGURED_SHORTCUTS.observe() val default_shortcuts: List = remember { getDefaultShortcuts() } StickyHeightColumn( modifier, verticalArrangement = Arrangement.spacedBy(10.dp) ) { - var navigate_song_with_numbers: Boolean by player.settings.shortcut.NAVIGATE_SONG_WITH_NUMBERS.observe() + var navigate_song_with_numbers: Boolean by player.settings.Shortcut.NAVIGATE_SONG_WITH_NUMBERS.observe() FlowRow( Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/trigger/MouseButtonShortcutTrigger.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/trigger/MouseButtonShortcutTrigger.kt index 7d0c447c9..1a597089b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/trigger/MouseButtonShortcutTrigger.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/appaction/shortcut/trigger/MouseButtonShortcutTrigger.kt @@ -9,7 +9,7 @@ import androidx.compose.material3.Text import androidx.compose.material3.Button import androidx.compose.runtime.* import kotlinx.serialization.Serializable -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu import com.toasterofbread.spmp.model.appaction.shortcut.ShortcutState import com.toasterofbread.spmp.model.appaction.shortcut.LocalShortcutState import org.jetbrains.compose.resources.stringResource diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/lyrics/LyricsFileConverter.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/lyrics/LyricsFileConverter.kt index 6b04bd083..c558596cc 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/lyrics/LyricsFileConverter.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/lyrics/LyricsFileConverter.kt @@ -1,7 +1,7 @@ package com.toasterofbread.spmp.model.lyrics -import dev.toastbits.composekit.platform.PlatformFile -import dev.toastbits.composekit.utils.common.indexOfOrNull +import dev.toastbits.composekit.context.PlatformFile +import dev.toastbits.composekit.util.indexOfOrNull import com.toasterofbread.spmp.ProjectBuildConfig import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.mediaitem.song.SongRef diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItem.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItem.kt index ed3a02771..6feece584 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItem.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItem.kt @@ -9,7 +9,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.vector.ImageVector -import dev.toastbits.composekit.platform.Platform +import dev.toastbits.composekit.util.platform.Platform import com.toasterofbread.spmp.db.Database import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.artist.ArtistData diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItemPreviewInteraction.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItemPreviewInteraction.kt index 96c413926..22c4c979c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItemPreviewInteraction.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItemPreviewInteraction.kt @@ -1,7 +1,6 @@ package com.toasterofbread.spmp.model.mediaitem import LocalPlayerState -import androidx.compose.foundation.Indication import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.collectIsPressedAsState @@ -12,17 +11,16 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalViewConfiguration -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.composable.platformClickableWithOffset -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.composable.OnChangedEffect import com.toasterofbread.spmp.service.playercontroller.LocalPlayerClickOverrides import com.toasterofbread.spmp.service.playercontroller.PlayerClickOverrides +import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.longpressmenu.LongPressMenuData import com.toasterofbread.spmp.ui.component.longpressmenu.longPressItem -import com.toasterofbread.spmp.service.playercontroller.PlayerState +import dev.toastbits.composekit.components.platform.composable.platformClickableWithOffset +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.util.composable.OnChangedEffect +import dev.toastbits.composekit.util.platform.Platform import kotlinx.coroutines.delay enum class MediaItemPreviewInteractionPressStage { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItemSortType.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItemSortType.kt index cc47b579a..a7501a0f4 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItemSortType.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaItemSortType.kt @@ -2,7 +2,7 @@ package com.toasterofbread.spmp.model.mediaitem import androidx.compose.runtime.Composable import androidx.compose.material3.Text -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu import com.toasterofbread.spmp.db.Database import com.toasterofbread.spmp.model.mediaitem.db.getPlayCount import com.toasterofbread.spmp.model.mediaitem.song.Song @@ -10,6 +10,7 @@ import com.toasterofbread.spmp.resources.rememberStringResourceByKey import dev.toastbits.ytmkt.model.external.mediaitem.YtmMediaItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res +import spmp.shared.generated.resources.sort_type import spmp.shared.generated.resources.sort_type_alphabet import spmp.shared.generated.resources.sort_type_artist import spmp.shared.generated.resources.sort_type_duration @@ -83,16 +84,17 @@ enum class MediaItemSortType { val index_offset = if (native_string_key == null) 1 else 0 LargeDropdownMenu( - expanded, - onDismissed, - entries.size - index_offset, - selected_option.ordinal - index_offset, - { - Text(entries[it + index_offset].getReadable(native_string_key)) + title = stringResource(Res.string.sort_type), + isOpen = expanded, + onDismissRequest = onDismissed, + items = (0 until entries.size - index_offset).toList(), + selectedItem = selected_option.ordinal - index_offset, + onSelected = { _, index -> + onSelected(entries[index + index_offset]) + onDismissed() } - ) { - onSelected(entries[it + index_offset]) - onDismissed() + ) { index -> + Text(entries[index + index_offset].getReadable(native_string_key)) } } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaitemHolder.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaitemHolder.kt index aff02ee8e..1022c7174 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaitemHolder.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/MediaitemHolder.kt @@ -30,7 +30,7 @@ private suspend fun List.filterItems( hidden_items: List, is_song_feed: Boolean = false ): List { - val hide_radios: Boolean = is_song_feed && !context.settings.feed.SHOW_RADIOS.get() + val hide_radios: Boolean = is_song_feed && !context.settings.Feed.SHOW_RADIOS.get() return mapNotNull { val item: MediaItem? = it.item diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/artist/SubscriberCount.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/artist/SubscriberCount.kt index 950e77ba8..9f979eb40 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/artist/SubscriberCount.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/artist/SubscriberCount.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.getValue import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.getUiLanguage import com.toasterofbread.spmp.platform.observeUiLanguage +import dev.toastbits.composekit.util.model.Locale import dev.toastbits.ytmkt.uistrings.amountToString import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res @@ -15,6 +16,6 @@ fun Artist.getSubscriberCount(context: AppContext): Int? = @Composable fun Int.toReadableSubscriberCount(context: AppContext): String { - val ui_language: String by context.observeUiLanguage() - return stringResource(Res.string.artist_x_subscribers).replace("\$x", amountToString(this, ui_language)) + val ui_language: Locale by context.observeUiLanguage() + return stringResource(Res.string.artist_x_subscribers).replace("\$x", amountToString(this, ui_language.toTag())) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/artist/formatArtistTitles.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/artist/formatArtistTitles.kt index d9be60399..a392553c6 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/artist/formatArtistTitles.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/artist/formatArtistTitles.kt @@ -1,7 +1,7 @@ package com.toasterofbread.spmp.model.mediaitem.artist import com.toasterofbread.spmp.platform.AppContext -import dev.toastbits.composekit.utils.common.isJa +import dev.toastbits.composekit.util.isJa fun formatArtistTitles(titles: List, context: AppContext): String? { val filtered_titles: List = titles.filterNotNull() diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/HiddenItems.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/HiddenItems.kt index 405946b48..7ad680707 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/HiddenItems.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/HiddenItems.kt @@ -34,9 +34,9 @@ suspend fun isMediaItemHidden( isMediaItemHiddenImpl( item, context, - context.settings.filter.ENABLE.get(), - context.settings.filter.APPLY_TO_ARTISTS.get(), - context.settings.filter.TITLE_KEYWORDS.get(), + context.settings.Filter.ENABLE.get(), + context.settings.Filter.APPLY_TO_ARTISTS.get(), + context.settings.Filter.TITLE_KEYWORDS.get(), hidden_items ) @@ -46,9 +46,9 @@ fun observeIsMediaItemHidden( hidden_items: List? = null ): State { val player: PlayerState = LocalPlayerState.current - val filter_enabled: Boolean by player.settings.filter.ENABLE.observe() - val filter_apply_to_artists: Boolean by player.settings.filter.APPLY_TO_ARTISTS.observe() - val filter_title_keywords: Set by player.settings.filter.TITLE_KEYWORDS.observe() + val filter_enabled: Boolean by player.settings.Filter.ENABLE.observe() + val filter_apply_to_artists: Boolean by player.settings.Filter.APPLY_TO_ARTISTS.observe() + val filter_title_keywords: Set by player.settings.Filter.TITLE_KEYWORDS.observe() return remember { derivedStateOf { isMediaItemHiddenImpl( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/PlayCount.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/PlayCount.kt index b8587ea3f..242e1792b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/PlayCount.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/PlayCount.kt @@ -1,5 +1,6 @@ package com.toasterofbread.spmp.model.mediaitem.db +import PlatformIO import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect @@ -15,17 +16,16 @@ import com.toasterofbread.spmp.model.mediaitem.playlist.LocalPlaylist import com.toasterofbread.spmp.model.mediaitem.playlist.LocalPlaylistData import com.toasterofbread.spmp.model.mediaitem.playlist.PlaylistFileConverter.saveToFile import com.toasterofbread.spmp.platform.AppContext +import dev.toastbits.composekit.context.PlatformFile import dev.toastbits.ytmkt.model.external.mediaitem.YtmMediaItem -import dev.toastbits.composekit.platform.PlatformFile -import kotlinx.coroutines.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import kotlinx.datetime.Clock -import kotlinx.datetime.TimeZone -import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.Instant import kotlinx.datetime.LocalDate +import kotlinx.datetime.TimeZone import kotlinx.datetime.toLocalDateTime -import kotlinx.datetime.Instant import kotlin.time.Duration -import PlatformIO suspend fun MediaItem.incrementPlayCount(context: AppContext, by: Int = 1): Result = withContext(Dispatchers.PlatformIO) { require(by >= 1) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/ThemeColour.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/ThemeColour.kt index cb426c12f..686e180de 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/ThemeColour.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/db/ThemeColour.kt @@ -6,7 +6,7 @@ import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.graphics.Color -import dev.toastbits.composekit.utils.common.getThemeColour +import dev.toastbits.composekit.util.getThemeColour import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.loader.MediaItemThumbnailLoader import dev.toastbits.ytmkt.model.external.ThumbnailProvider as YtmThumbnailProvider diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/layout/ContinuableMediaItemLayout.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/layout/ContinuableMediaItemLayout.kt index 4ec6f9129..23ccb755a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/layout/ContinuableMediaItemLayout.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/layout/ContinuableMediaItemLayout.kt @@ -12,7 +12,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.Platform +import dev.toastbits.composekit.util.platform.Platform import com.toasterofbread.spmp.model.mediaitem.MediaItemRef import com.toasterofbread.spmp.model.mediaitem.toMediaItemRef import com.toasterofbread.spmp.model.mediaitem.MediaItem diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/layout/YoutubePageType.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/layout/YoutubePageType.kt index eccda2804..cee711843 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/layout/YoutubePageType.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/layout/YoutubePageType.kt @@ -95,6 +95,6 @@ suspend fun YoutubePage.open(player: PlayerState, title: UiString?) { browse_params = getBrowseParamsData() ) is PlainYoutubePage -> - player.openViewMorePage(browse_id, runBlocking { title?.getString(player.context.getUiLanguage()) }) + player.openViewMorePage(browse_id, runBlocking { title?.getString(player.context.getUiLanguage().toTag()) }) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/LocalPlaylists.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/LocalPlaylists.kt index 110aa3412..74cb73af8 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/LocalPlaylists.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/LocalPlaylists.kt @@ -17,7 +17,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import kotlinx.coroutines.* import PlatformIO -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/MediaItemLibrary.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/MediaItemLibrary.kt index c96f68912..23a0e3365 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/MediaItemLibrary.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/MediaItemLibrary.kt @@ -10,9 +10,10 @@ import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.download.DownloadStatus import com.toasterofbread.spmp.platform.playerservice.ClientServerPlayerService -import dev.toastbits.composekit.platform.PlatformFile -import dev.toastbits.composekit.platform.ReentrantLock -import dev.toastbits.composekit.utils.common.addUnique +import dev.toastbits.composekit.context.PlatformFile +import dev.toastbits.composekit.util.addUnique +import java.util.concurrent.locks.ReentrantLock +import kotlin.concurrent.withLock @Suppress("DeferredResultUnused") object MediaItemLibrary { @@ -20,7 +21,7 @@ object MediaItemLibrary { context: AppContext, custom_location_uri: String? = null ): PlatformFile? { - val location_url: String = custom_location_uri ?: context.settings.system.LIBRARY_PATH.get() + val location_url: String = custom_location_uri ?: context.settings.Misc.LIBRARY_PATH.get() if (location_url.isNotBlank()) { val custom_dir: PlatformFile? = context.getUserDirectoryFile(location_url) if (custom_dir != null) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/Loader.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/Loader.kt index 4184b4a87..205799c03 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/Loader.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/Loader.kt @@ -6,7 +6,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import dev.toastbits.composekit.platform.ReentrantLock import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Deferred @@ -14,7 +13,8 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope -import dev.toastbits.composekit.platform.synchronized +import java.util.concurrent.locks.ReentrantLock +import kotlin.concurrent.withLock internal abstract class ListenerLoader: BasicLoader() { protected abstract val listeners: MutableList> diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/MediaItemLoader.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/MediaItemLoader.kt index e5a71e1c5..4269cd6fb 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/MediaItemLoader.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/MediaItemLoader.kt @@ -11,8 +11,6 @@ import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.MediaItemData import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.artist.ArtistData -import com.toasterofbread.spmp.model.mediaitem.layout.ContinuableMediaItemLayout -import dev.toastbits.ytmkt.model.external.mediaitem.MediaItemLayout import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary import com.toasterofbread.spmp.model.mediaitem.playlist.LocalPlaylist import com.toasterofbread.spmp.model.mediaitem.playlist.LocalPlaylistData @@ -21,15 +19,11 @@ import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylist import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylistData import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.mediaitem.song.SongData -import com.toasterofbread.spmp.model.mediaitem.enums.PlaylistType import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.youtubeapi.SpMpYoutubeiApi -import dev.toastbits.ytmkt.model.external.mediaitem.YtmPlaylist -import dev.toastbits.ytmkt.model.external.mediaitem.YtmSong -import dev.toastbits.ytmkt.radio.RadioContinuation -import dev.toastbits.composekit.platform.PlatformFile -import dev.toastbits.composekit.platform.ReentrantLock +import dev.toastbits.composekit.context.PlatformFile import dev.toastbits.ytmkt.radio.BuiltInRadioContinuation +import java.util.concurrent.locks.ReentrantLock internal object MediaItemLoader: ListenerLoader() { private val song_lock: ReentrantLock = ReentrantLock() diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/MediaItemThumbnailLoader.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/MediaItemThumbnailLoader.kt index 9b9c2ddfd..34862cc32 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/MediaItemThumbnailLoader.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/MediaItemThumbnailLoader.kt @@ -8,8 +8,8 @@ import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.remember import androidx.compose.ui.graphics.ImageBitmap -import dev.toastbits.composekit.utils.common.addUnique -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.util.addUnique +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.model.mediaitem.MediaItem import dev.toastbits.ytmkt.model.external.ThumbnailProvider import com.toasterofbread.spmp.platform.AppContext @@ -19,10 +19,10 @@ import com.toasterofbread.spmp.service.playercontroller.PlayerState import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import PlatformIO -import dev.toastbits.composekit.platform.synchronized import okio.buffer import okio.use import io.ktor.client.HttpClient +import kotlin.concurrent.withLock internal data class MediaItemThumbnailLoaderKey( val provider: ThumbnailProvider, @@ -128,7 +128,7 @@ internal object MediaItemThumbnailLoader: ListenerLoader = item.downloadThumbnailData(thumbnail_url, client) result.onSuccess { image -> - if (cache_file != null && !disable_cache_write && context.settings.misc.THUMB_CACHE_ENABLED.get()) { + if (cache_file != null && !disable_cache_write && context.settings.Misc.THUMB_CACHE_ENABLED.get()) { cache_file.parent_file.mkdirs() cache_file.outputStream().buffer().use { it.write(image.toByteArray()) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/SongLyricsLoader.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/SongLyricsLoader.kt index 1adbaf3bf..9a24a4976 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/SongLyricsLoader.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/loader/SongLyricsLoader.kt @@ -2,7 +2,7 @@ package com.toasterofbread.spmp.model.mediaitem.loader import androidx.compose.runtime.* import app.cash.sqldelight.Query -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.model.lyrics.* import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary import com.toasterofbread.spmp.model.mediaitem.song.Song diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/InteractivePlaylistEditor.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/InteractivePlaylistEditor.kt index 3dfc7044d..1af1cf91c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/InteractivePlaylistEditor.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/InteractivePlaylistEditor.kt @@ -19,7 +19,6 @@ import dev.toastbits.ytmkt.endpoint.AccountPlaylistEditorEndpoint import dev.toastbits.ytmkt.model.external.PlaylistEditor import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.withContext -import dev.toastbits.composekit.platform.assert class InteractivePlaylistEditor( val playlist: Playlist, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylist.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylist.kt index 712ba9d20..36fed38a4 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylist.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylist.kt @@ -8,8 +8,8 @@ import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import dev.toastbits.composekit.platform.PlatformFile -import dev.toastbits.composekit.utils.modifier.background +import dev.toastbits.composekit.context.PlatformFile +import dev.toastbits.composekit.components.utils.modifier.background import com.toasterofbread.spmp.model.mediaitem.MediaItemSortType import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary @@ -19,7 +19,7 @@ import com.toasterofbread.spmp.platform.AppContext import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import PlatformIO -import dev.toastbits.composekit.settings.ui.on_accent +import dev.toastbits.composekit.theme.core.onAccent sealed interface LocalPlaylist: Playlist { suspend fun getLocalPlaylistFile(context: AppContext): PlatformFile? = @@ -79,6 +79,6 @@ suspend fun Playlist.downloadAsLocalPlaylist(context: AppContext, replace: Boole fun LocalPlaylist.LocalPlaylistDefaultThumbnail(modifier: Modifier = Modifier) { val player = LocalPlayerState.current Box(modifier.background { player.theme.accent }, contentAlignment = Alignment.Center) { - Icon(Icons.Default.PlaylistPlay, null, tint = player.theme.on_accent) + Icon(Icons.Default.PlaylistPlay, null, tint = player.theme.onAccent) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistData.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistData.kt index 370afde52..5963b61b8 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistData.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistData.kt @@ -26,7 +26,7 @@ import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.mediaitem.enums.PlaylistType import com.toasterofbread.spmp.platform.AppContext import dev.toastbits.ytmkt.model.external.mediaitem.YtmPlaylist -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile class LocalPlaylistData(id: String): PlaylistData(id), LocalPlaylist { var play_count: Int = 0 diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistEditor.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistEditor.kt index a623be5a7..2620fc1bd 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistEditor.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistEditor.kt @@ -1,6 +1,6 @@ package com.toasterofbread.spmp.model.mediaitem.playlist -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary import com.toasterofbread.spmp.model.mediaitem.playlist.PlaylistFileConverter.saveToFile import com.toasterofbread.spmp.model.mediaitem.song.SongData diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistRef.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistRef.kt index f0e2adc0f..3f78ad035 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistRef.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/LocalPlaylistRef.kt @@ -6,7 +6,7 @@ import com.toasterofbread.spmp.model.mediaitem.PropertyRememberer import com.toasterofbread.spmp.model.mediaitem.UnsupportedPropertyRememberer import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary import com.toasterofbread.spmp.platform.AppContext -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile class LocalPlaylistRef(override val id: String): LocalPlaylist, MediaItemRef() { override fun toString(): String = "LocalPlaylistRef($id)" diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/PlaylistFileConverter.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/PlaylistFileConverter.kt index cc1b0cd9c..f45a22ea0 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/PlaylistFileConverter.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/PlaylistFileConverter.kt @@ -1,7 +1,7 @@ package com.toasterofbread.spmp.model.mediaitem.playlist import SpMp -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.model.mediaitem.MediaItemSortType import dev.toastbits.ytmkt.model.external.ThumbnailProvider import com.toasterofbread.spmp.model.mediaitem.db.getPlayCount diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/PlaylistHolder.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/PlaylistHolder.kt index d6ef5b5ae..9c9f64c78 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/PlaylistHolder.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/playlist/PlaylistHolder.kt @@ -4,7 +4,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import com.toasterofbread.spmp.model.mediaitem.MediaItemHolder -import dev.toastbits.composekit.platform.assert class PlaylistHolder(initial_playlist: Playlist): MediaItemHolder { override val item: Playlist? get() = current_playlist diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/Song.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/Song.kt index df4517ac3..71f615c14 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/Song.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/Song.kt @@ -179,9 +179,9 @@ interface Song: MediaItem.WithArtists { val controller: PlayerService? = player.controller val internal_offset: Long? by LyricsSyncOffset.observe(database) - val settings_delay: Float by player.settings.lyrics.SYNC_DELAY.observe() - val settings_delay_topbar: Float by player.settings.lyrics.SYNC_DELAY_TOPBAR.observe() - val settings_delay_bt: Float by player.settings.lyrics.SYNC_DELAY_BLUETOOTH.observe() + val settings_delay: Float by player.settings.Lyrics.SYNC_DELAY.observe() + val settings_delay_topbar: Float by player.settings.Lyrics.SYNC_DELAY_TOPBAR.observe() + val settings_delay_bt: Float by player.settings.Lyrics.SYNC_DELAY_BLUETOOTH.observe() return remember(controller, is_topbar) { derivedStateOf { var delay: Float = settings_delay @@ -232,7 +232,7 @@ private data class SongThumbnailProvider(val id: String): ThumbnailProvider { @Composable fun Song?.observeThumbnailRounding(): Int { val player: PlayerState = LocalPlayerState.current - val default: Float by player.settings.theme.NOWPLAYING_DEFAULT_IMAGE_CORNER_ROUNDING.observe() + val default: Float by player.settings.Theme.NOWPLAYING_DEFAULT_IMAGE_CORNER_ROUNDING.observe() val corner_rounding: Float? = this?.ThumbnailRounding?.observe(player.database)?.value return ((corner_rounding ?: default) * 50f).roundToInt() } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongAudioQuality.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongAudioQuality.kt index c493b6aea..4a470c8ec 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongAudioQuality.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongAudioQuality.kt @@ -1,6 +1,5 @@ package com.toasterofbread.spmp.model.mediaitem.song -import com.toasterofbread.spmp.model.settings.Settings import com.toasterofbread.spmp.platform.AppContext import dev.toastbits.ytmkt.formats.VideoFormatsEndpoint import dev.toastbits.ytmkt.model.external.YoutubeVideoFormat @@ -10,10 +9,10 @@ enum class SongAudioQuality { } suspend fun AppContext.getSongTargetStreamQuality(): SongAudioQuality = - settings.streaming.STREAM_AUDIO_QUALITY.get() + settings.Streaming.STREAM_AUDIO_QUALITY.get() suspend fun AppContext.getSongTargetDownloadQuality(): SongAudioQuality = - settings.streaming.DOWNLOAD_AUDIO_QUALITY.get() + settings.Streaming.DOWNLOAD_AUDIO_QUALITY.get() suspend fun getSongAudioFormatByQuality( song_id: String, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongData.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongData.kt index 11946153a..cb3eef495 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongData.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongData.kt @@ -1,6 +1,5 @@ package com.toasterofbread.spmp.model.mediaitem.song -import dev.toastbits.composekit.platform.lazyAssert import com.toasterofbread.spmp.db.Database import com.toasterofbread.spmp.model.mediaitem.MediaItem import dev.toastbits.ytmkt.model.external.ThumbnailProvider @@ -11,6 +10,7 @@ import com.toasterofbread.spmp.model.mediaitem.db.Property import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylist import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylistData import com.toasterofbread.spmp.model.mediaitem.playlist.toRemotePlaylistData +import dev.toastbits.composekit.util.platform.lazyAssert import dev.toastbits.ytmkt.model.external.mediaitem.YtmSong class SongData( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongLikedStatus.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongLikedStatus.kt index 7ae8244b1..555c35774 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongLikedStatus.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/mediaitem/song/SongLikedStatus.kt @@ -3,7 +3,6 @@ package com.toasterofbread.spmp.model.mediaitem.song import com.toasterofbread.spmp.platform.AppContext import dev.toastbits.ytmkt.endpoint.SetSongLikedEndpoint import dev.toastbits.ytmkt.model.external.SongLikedStatus -import dev.toastbits.composekit.platform.synchronized fun interface SongLikedStatusListener { fun onSongLikedStatusChanged(song: Song, liked_status: SongLikedStatus) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/radio/RadioInstance.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/radio/RadioInstance.kt index c2ee6f2d5..e7c01ae40 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/radio/RadioInstance.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/radio/RadioInstance.kt @@ -3,7 +3,7 @@ package com.toasterofbread.spmp.model.radio import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.util.platform.launchSingle import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.MediaItemData diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/Settings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/Settings.kt index d4398c04c..811dc1a20 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/Settings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/Settings.kt @@ -1,61 +1,92 @@ package com.toasterofbread.spmp.model.settings -import com.toasterofbread.spmp.model.settings.category.* +import com.toasterofbread.spmp.model.settings.category.BehaviourSettings +import com.toasterofbread.spmp.model.settings.category.DependencySettings +import com.toasterofbread.spmp.model.settings.category.DiscordAuthSettings +import com.toasterofbread.spmp.model.settings.category.DiscordSettings +import com.toasterofbread.spmp.model.settings.category.ExperimentalSettings +import com.toasterofbread.spmp.model.settings.category.FeedSettings +import com.toasterofbread.spmp.model.settings.category.FilterSettings +import com.toasterofbread.spmp.model.settings.category.InterfaceSettings +import com.toasterofbread.spmp.model.settings.category.LayoutSettings +import com.toasterofbread.spmp.model.settings.category.LyricsSettings +import com.toasterofbread.spmp.model.settings.category.MiscSettings +import com.toasterofbread.spmp.model.settings.category.PlatformSettings +import com.toasterofbread.spmp.model.settings.category.PlayerSettings +import com.toasterofbread.spmp.model.settings.category.SearchSettings +import com.toasterofbread.spmp.model.settings.category.ShortcutSettings +import com.toasterofbread.spmp.model.settings.category.StreamingSettings +import com.toasterofbread.spmp.model.settings.category.ThemeSettings +import com.toasterofbread.spmp.model.settings.category.WidgetSettings +import com.toasterofbread.spmp.model.settings.category.YTApiSettings +import com.toasterofbread.spmp.model.settings.category.YoutubeAuthSettings import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.resources.Language +import dev.toastbits.composekit.commonsettings.impl.ComposeKitSettings +import dev.toastbits.composekit.settings.ComposeKitSettingsGroup +import dev.toastbits.composekit.settings.ui.screen.PlatformSettingsGroupScreen -class Settings(context: AppContext, available_languages: List) { - val youtube_auth: YoutubeAuthSettings = YoutubeAuthSettings(context) - val system: SystemSettings = SystemSettings(context, available_languages) - val behaviour: BehaviourSettings = BehaviourSettings(context) - val layout: LayoutSettings = LayoutSettings(context) - val player: PlayerSettings = PlayerSettings(context) - val feed: FeedSettings = FeedSettings(context) - val theme: ThemeSettings = ThemeSettings(context) - val lyrics: LyricsSettings = LyricsSettings(context) - val discord: DiscordSettings = DiscordSettings(context) - val discord_auth: DiscordAuthSettings = DiscordAuthSettings(context) - val filter: FilterSettings = FilterSettings(context) - val streaming: StreamingSettings = StreamingSettings(context) - val shortcut: ShortcutSettings = ShortcutSettings(context) - val platform: PlatformSettings = PlatformSettings(context) - val misc: MiscSettings = MiscSettings(context) - val widget: WidgetSettings = WidgetSettings(context) - val deps: DependencySettings = DependencySettings(context) - val search: SearchSettings = SearchSettings(context) - val experimental: ExperimentalSettings = ExperimentalSettings(context) - val ytapi: YTApiSettings = YTApiSettings(context.getPrefs()) +class Settings( + private val context: AppContext, + available_languages: List +): ComposeKitSettings { + val YoutubeAuth: YoutubeAuthSettings = YoutubeAuthSettings(context) + val Behaviour: BehaviourSettings = BehaviourSettings(context) + val Layout: LayoutSettings = LayoutSettings(context) + val Player: PlayerSettings = PlayerSettings(context) + val Feed: FeedSettings = FeedSettings(context) + override val Theme: ThemeSettings = ThemeSettings(context) + val Lyrics: LyricsSettings = LyricsSettings(context) + val Discord: DiscordSettings = DiscordSettings(context) + val DiscordAuth: DiscordAuthSettings = DiscordAuthSettings(context) + val Filter: FilterSettings = FilterSettings(context) + val Streaming: StreamingSettings = StreamingSettings(context) + val Shortcut: ShortcutSettings = ShortcutSettings(context) + val Platform: PlatformSettings = PlatformSettings(context) + val Misc: MiscSettings = MiscSettings(context) + val Widget: WidgetSettings = WidgetSettings(context) + val Deps: DependencySettings = DependencySettings(context) + val Search: SearchSettings = SearchSettings(context) + val Experimental: ExperimentalSettings = ExperimentalSettings(context) + val YtApi: YTApiSettings = YTApiSettings(context.getPrefs()) + override val Interface: InterfaceSettings = InterfaceSettings(context) + + override val preferences: dev.toastbits.composekit.settings.PlatformSettings + get() = context.getPrefs() + + override val allGroups: List + get() = all_groups.values.toList() val all_groups: Map = listOf( - youtube_auth, - - system, - behaviour, - layout, - player, - feed, - theme, - lyrics, - discord, - discord_auth, - filter, - streaming, - shortcut, - platform, - widget, - misc, - deps, - experimental, - - ytapi - ).associateBy { it.group_key } + YoutubeAuth, + + Interface, + Behaviour, + Layout, + Player, + Feed, + Theme, + Lyrics, + Discord, + DiscordAuth, + Filter, + Streaming, + Shortcut, + Platform, + Widget, + Misc, + Deps, + Experimental, + + YtApi + ).associateBy { it.groupKey } val groups_with_page: List get() = - all_groups.values.filter { it.getPage() != null && it !is DependencySettings } + all_groups.values.filter { !it.hidden && it !is DependencySettings } - val group_pages: List get() = - all_groups.values.mapNotNull { if (it is DependencySettings) null else it.getPage() } + val group_pages: List get() = + all_groups.values.mapNotNull { if (it is DependencySettings) null else it.takeIf { !it.hidden }?.let { PlatformSettingsGroupScreen(it) } } fun groupFromKey(key: String): SettingsGroup? = all_groups[key] diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/SettingsGroup.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/SettingsGroup.kt new file mode 100644 index 000000000..3cfd2db0a --- /dev/null +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/SettingsGroup.kt @@ -0,0 +1,12 @@ +package com.toasterofbread.spmp.model.settings + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import dev.toastbits.composekit.settings.ComposeKitSettingsGroup + +interface SettingsGroup: ComposeKitSettingsGroup { + val hidden: Boolean get() = false + + @Composable + fun titleBarEndContent(modifier: Modifier) {} +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/SettingsGroupImpl.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/SettingsGroupImpl.kt new file mode 100644 index 000000000..7bb1c1a21 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/SettingsGroupImpl.kt @@ -0,0 +1,9 @@ +package com.toasterofbread.spmp.model.settings + +import dev.toastbits.composekit.settings.ComposeKitSettingsGroupImpl +import dev.toastbits.composekit.settings.PlatformSettings + +abstract class SettingsGroupImpl( + groupKey: String, + settings: PlatformSettings +): ComposeKitSettingsGroupImpl(groupKey, settings), SettingsGroup \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/SettingsImportExport.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/SettingsImportExport.kt deleted file mode 100644 index cabd87992..000000000 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/SettingsImportExport.kt +++ /dev/null @@ -1,121 +0,0 @@ -package com.toasterofbread.spmp.model.settings - -import dev.toastbits.composekit.platform.PlatformFile -import dev.toastbits.composekit.platform.PlatformPreferences -import com.toasterofbread.spmp.model.settings.category.SettingsGroup -import com.toasterofbread.spmp.platform.AppContext -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.* -import kotlinx.serialization.json.encodeToJsonElement -import PlatformIO -import okio.buffer -import okio.use - -object SettingsImportExport { - @Serializable - data class SettingsExportData( - val included_categories: List?, - val values: JsonObject? - ) { - fun getGroups(context: AppContext): List? = - included_categories?.mapNotNull { context.settings.groupFromKey(it) } - } - - suspend fun exportSettingsData( - prefs: PlatformPreferences, - groups: List - ): SettingsExportData { - val values: MutableMap = mutableMapOf() - - for (category in groups) { - for (property in category.getAllProperties()) { - val value: Any? = property.get() - if (value != property.getDefaultValue()) { - values[property.key] = property.serialise(value) - } - } - } - - return SettingsExportData( - included_categories = groups.map { it.group_key }, - values = JsonObject(values) - ) - } - - suspend fun loadSettingsFile(file: PlatformFile): SettingsExportData = - withContext(Dispatchers.PlatformIO) { - return@withContext file.inputStream().buffer().use { stream -> - Json.decodeFromString(stream.readUtf8()) - } - } - - data class ImportResult( - val directly_imported_count: Int, - val default_imported_count: Int - ) - - fun importSettingsData( - context: AppContext, - data: SettingsExportData, - groups: List? - ): ImportResult { - var directly_imported: Int = 0 - var default_imported: Int = 0 - - if (data.values != null) { - context.getPrefs().edit { - val all_groups: Collection = context.settings.all_groups.values - val included_categories: List? = data.included_categories?.mapNotNull { key -> - context.settings.groupFromKey(key) - } - - for (category in included_categories ?: all_groups) { - if (groups != null && !groups.contains(category)) { - continue - } - - for (property in category.getAllProperties()) { - val value: JsonElement? = data.values[property.key] - if (value != null) { - property.set(value, this) - directly_imported++ - } - else { - remove(property.key) - default_imported++ - } - } - } - } - } - - return ImportResult( - directly_imported, - default_imported - ) - } -} - -private fun prefsValueToJsonElement(value: Any?): JsonElement = - when (value) { - // null -> JsonPrimitive(null) - // is String -> JsonPrimitive(value) - is Set<*> -> JsonArray((value as Set).map { JsonPrimitive(it) }) - // is Int -> JsonPrimitive(value) - // is Long -> JsonPrimitive(value) - // is Float -> JsonPrimitive(value) - // is Boolean -> JsonPrimitive(value) - else -> Json.encodeToJsonElement(value) - // else -> throw NotImplementedError(value::class.toString()) - } - -private fun jsonElementToPrefsValue(element: JsonElement?): Any? = - when (element) { - null, is JsonNull -> null - is JsonArray -> element.jsonArray.map { it.jsonPrimitive.content }.toSet() - is JsonPrimitive -> element.booleanOrNull ?: element.intOrNull ?: element.longOrNull ?: element.floatOrNull ?: element.content - else -> throw NotImplementedError(element::class.toString()) - } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/BehaviourSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/BehaviourSettings.kt index 2b53d1041..1a3d19d87 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/BehaviourSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/BehaviourSettings.kt @@ -4,11 +4,12 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.TouchApp import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getBehaviourCategoryItems -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_behaviour @@ -35,73 +36,73 @@ import spmp.shared.generated.resources.s_sub_start_radio_on_song_press import spmp.shared.generated.resources.s_sub_stop_player_on_app_close import spmp.shared.generated.resources.s_sub_treat_singles_as_song -class BehaviourSettings(val context: AppContext): SettingsGroup("BEHAVIOUR", context.getPrefs()) { - val OPEN_NP_ON_SONG_PLAYED: PreferencesProperty by property( +class BehaviourSettings(val context: AppContext): SettingsGroupImpl("BEHAVIOUR", context.getPrefs()) { + val OPEN_NP_ON_SONG_PLAYED: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_open_np_on_song_played) }, getDescription = { stringResource(Res.string.s_sub_open_np_on_song_played) }, getDefaultValue = { true } ) - val START_RADIO_ON_SONG_PRESS: PreferencesProperty by property( + val START_RADIO_ON_SONG_PRESS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_start_radio_on_song_press) }, getDescription = { stringResource(Res.string.s_sub_start_radio_on_song_press) }, getDefaultValue = { true } ) - val MULTISELECT_CANCEL_ON_ACTION: PreferencesProperty by property( + val MULTISELECT_CANCEL_ON_ACTION: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_multiselect_cancel_on_action) }, getDescription = { stringResource(Res.string.s_sub_multiselect_cancel_on_action) }, getDefaultValue = { true } ) - val MULTISELECT_CANCEL_ON_NONE_SELECTED: PreferencesProperty by property( + val MULTISELECT_CANCEL_ON_NONE_SELECTED: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_multiselect_cancel_on_none_selected) }, getDescription = { null }, getDefaultValue = { true } ) - val TREAT_SINGLES_AS_SONG: PreferencesProperty by property( + val TREAT_SINGLES_AS_SONG: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_treat_singles_as_song) }, getDescription = { stringResource(Res.string.s_sub_treat_singles_as_song) }, getDefaultValue = { false } ) - val TREAT_ANY_SINGLE_ITEM_PLAYLIST_AS_SINGLE: PreferencesProperty by property( + val TREAT_ANY_SINGLE_ITEM_PLAYLIST_AS_SINGLE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_treat_any_single_item_playlist_as_single) }, getDescription = { null }, getDefaultValue = { false } ) - val SHOW_LIKES_PLAYLIST: PreferencesProperty by property( + val SHOW_LIKES_PLAYLIST: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_show_likes_playlist) }, getDescription = { null }, getDefaultValue = { true } ) - val SEARCH_SHOW_SUGGESTIONS: PreferencesProperty by property( + val SEARCH_SHOW_SUGGESTIONS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_search_show_suggestions) }, getDescription = { null }, getDefaultValue = { true } ) - val STOP_PLAYER_ON_APP_CLOSE: PreferencesProperty by property( + val STOP_PLAYER_ON_APP_CLOSE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_stop_player_on_app_close) }, getDescription = { stringResource(Res.string.s_sub_stop_player_on_app_close) }, getDefaultValue = { false } ) - val INCLUDE_PLAYBACK_POSITION_IN_SHARE_URL: PreferencesProperty by property( + val INCLUDE_PLAYBACK_POSITION_IN_SHARE_URL: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_include_playback_position_in_share_url) }, getDescription = { null }, getDefaultValue = { true } ) - val REPEAT_SONG_ON_PREVIOUS_THRESHOLD_S: PreferencesProperty by property( + val REPEAT_SONG_ON_PREVIOUS_THRESHOLD_S: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_repeat_song_on_previous_threshold_s) }, getDescription = { stringResource(Res.string.s_sub_repeat_song_on_previous_threshold_s) }, getDefaultValue = { -1f } ) - val LPM_CLOSE_ON_ACTION: PreferencesProperty by property( + val LPM_CLOSE_ON_ACTION: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lpm_close_on_action) }, getDescription = { null }, getDefaultValue = { true } ) - val LPM_INCREMENT_PLAY_AFTER: PreferencesProperty by property( + val LPM_INCREMENT_PLAY_AFTER: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lpm_increment_play_after) }, getDescription = { null }, getDefaultValue = { true } ) - val DESKTOP_LPM_KEEP_ON_BACKGROUND_SCROLL: PreferencesProperty by property( + val DESKTOP_LPM_KEEP_ON_BACKGROUND_SCROLL: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_desktop_lpm_keep_on_background_scroll) }, getDescription = { stringResource(Res.string.s_sub_desktop_lpm_keep_on_background_scroll) }, getDefaultValue = { false }, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DependencySettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DependencySettings.kt index a32ba8d72..b14fdcedb 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DependencySettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DependencySettings.kt @@ -33,12 +33,13 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.DependencyInfo import com.toasterofbread.spmp.SpMpDeps +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.settings.ui.component.item.ComposableSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.vibrant_accent -import dev.toastbits.composekit.utils.common.thenIf +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ComposableSettingsItem +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.thenIf import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.`dependency_list_dep_$author` @@ -49,7 +50,7 @@ import spmp.shared.generated.resources.dependency_list_title import spmp.shared.generated.resources.s_cat_dependencies import spmp.shared.generated.resources.s_cat_desc_dependencies -class DependencySettings(val context: AppContext): SettingsGroup("DEPENDENCY", context.getPrefs()) { +class DependencySettings(val context: AppContext): SettingsGroupImpl("DEPENDENCY", context.getPrefs()) { @Composable override fun getTitle(): String = stringResource(Res.string.s_cat_dependencies) @@ -61,7 +62,7 @@ class DependencySettings(val context: AppContext): SettingsGroup("DEPENDENCY", c override fun getConfigurationItems(): List = listOf( - ComposableSettingsItem { + ComposableSettingsItem(resetComposeUiState = {}) { DependencyList(Modifier.fillMaxSize()) } ) @@ -101,7 +102,7 @@ private fun DependencyInfo(dependency: DependencyInfo, modifier: Modifier = Modi Column( modifier .background( - player.theme.vibrant_accent.copy(alpha = 0.2f), + player.theme.vibrantAccent.copy(alpha = 0.2f), RoundedCornerShape(10.dp) ) .padding(horizontal = 15.dp, vertical = 10.dp) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DiscordAuthSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DiscordAuthSettings.kt index ec107d854..273a9e49b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DiscordAuthSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DiscordAuthSettings.kt @@ -1,62 +1,28 @@ package com.toasterofbread.spmp.model.settings.category -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Icon import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.settings.ui.SettingsInterface import com.toasterofbread.spmp.ProjectBuildConfig +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.ui.layout.apppage.settingspage.getDiscordAuthItem -import com.toasterofbread.spmp.ui.layout.apppage.settingspage.PrefsPageScreen -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource -import org.jetbrains.compose.resources.vectorResource import spmp.shared.generated.resources.Res -import spmp.shared.generated.resources.ic_discord import spmp.shared.generated.resources.s_cat_discord_auth -class DiscordAuthSettings(val context: AppContext): SettingsGroup("DISCORDAUTH", context.getPrefs()) { - val DISCORD_ACCOUNT_TOKEN: PreferencesProperty by property( +class DiscordAuthSettings(val context: AppContext): SettingsGroupImpl("DISCORDAUTH", context.getPrefs()) { + val DISCORD_ACCOUNT_TOKEN: PlatformSettingsProperty by property( getName = { "" }, getDescription = { null }, getDefaultValue = { ProjectBuildConfig.DISCORD_ACCOUNT_TOKEN ?: "" } ) - val DISCORD_WARNING_ACCEPTED: PreferencesProperty by property( + val DISCORD_WARNING_ACCEPTED: PlatformSettingsProperty by property( getName = { "" }, getDescription = { null }, getDefaultValue = { false } ) - override fun getPage(): CategoryPage = - object : CategoryPage( - this, - { stringResource(Res.string.s_cat_discord_auth) } - ) { - override fun openPage(context: AppContext) { - val manual: Boolean = false - SpMp.player_state.app_page_state.Settings.settings_interface.openPageById(PrefsPageScreen.DISCORD_LOGIN.ordinal, manual) - } - - override fun getTitleItem(context: AppContext): SettingsItem = - getDiscordAuthItem( - context, - info_only = true, - ignore_prerequisite = true, - StartIcon = { - Box(Modifier.height(40.dp).padding(end = 20.dp), contentAlignment = Alignment.Center) { - Icon(DiscordSettings.getDiscordIcon(), null) - } - } - ) - } - @Composable override fun getTitle(): String = stringResource(Res.string.s_cat_discord_auth) @@ -68,5 +34,5 @@ class DiscordAuthSettings(val context: AppContext): SettingsGroup("DISCORDAUTH", override fun getConfigurationItems(): List = emptyList() - override fun showPage(exporting: Boolean): Boolean = exporting + override val hidden: Boolean = true } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DiscordSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DiscordSettings.kt index 14187c887..ee9f0a1d2 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DiscordSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/DiscordSettings.kt @@ -4,10 +4,12 @@ package com.toasterofbread.spmp.model.settings.category import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector import com.toasterofbread.spmp.ProjectBuildConfig +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getDiscordCategoryItems -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import kotlinx.coroutines.runBlocking import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.vectorResource @@ -44,95 +46,89 @@ import spmp.shared.generated.resources.s_sub_discord_status_text_a import spmp.shared.generated.resources.s_sub_discord_status_text_b import spmp.shared.generated.resources.s_sub_discord_status_text_c -class DiscordSettings(val context: AppContext): SettingsGroup("DISCORD", context.getPrefs()) { - val STATUS_ENABLE: PreferencesProperty by property( +class DiscordSettings(val context: AppContext): SettingsGroupImpl("DISCORD", context.getPrefs()) { + val STATUS_ENABLE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_discord_status_enable) }, getDescription = { null }, getDefaultValue = { true } ) - val STATUS_DISABLE_WHEN_INVISIBLE: PreferencesProperty by property( + val STATUS_DISABLE_WHEN_INVISIBLE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_discord_status_disable_when_invisible) }, getDescription = { null }, getDefaultValue = { false } ) - val STATUS_DISABLE_WHEN_DND: PreferencesProperty by property( + val STATUS_DISABLE_WHEN_DND: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_discord_status_disable_when_dnd) }, getDescription = { null }, getDefaultValue = { false } ) - val STATUS_DISABLE_WHEN_IDLE: PreferencesProperty by property( + val STATUS_DISABLE_WHEN_IDLE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_discord_status_disable_when_idle) }, getDescription = { null }, getDefaultValue = { false } ) - val STATUS_DISABLE_WHEN_OFFLINE: PreferencesProperty by property( + val STATUS_DISABLE_WHEN_OFFLINE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_discord_status_disable_when_offline) }, getDescription = { null }, getDefaultValue = { false } ) - val STATUS_DISABLE_WHEN_ONLINE: PreferencesProperty by property( + val STATUS_DISABLE_WHEN_ONLINE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_discord_status_disable_when_online) }, getDescription = { null }, getDefaultValue = { false } ) - val LARGE_IMAGE_SOURCE: PreferencesProperty by enumProperty( + val LARGE_IMAGE_SOURCE: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_discord_status_large_image_source) }, getDescription = { null }, getDefaultValue = { ImageSource.SONG } ) - val SMALL_IMAGE_SOURCE: PreferencesProperty by enumProperty( + val SMALL_IMAGE_SOURCE: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_discord_status_small_image_source) }, getDescription = { null }, getDefaultValue = { ImageSource.ARTIST } ) - val STATUS_NAME: PreferencesProperty by resourceDefaultValueProperty( + val STATUS_NAME: PlatformSettingsProperty by resourceDefaultValueProperty( getName = { stringResource(Res.string.s_key_discord_status_name) }, getDescription = { stringResource(Res.string.s_sub_discord_status_name) }, - getDefaultValueSuspending = { ProjectBuildConfig.DISCORD_STATUS_TEXT_NAME_OVERRIDE ?: getString(Res.string.discord_status_default_name) }, - getDefaultValueComposable = { ProjectBuildConfig.DISCORD_STATUS_TEXT_NAME_OVERRIDE ?: stringResource(Res.string.discord_status_default_name) } + getDefaultValue = { ProjectBuildConfig.DISCORD_STATUS_TEXT_NAME_OVERRIDE ?: runBlocking { getString(Res.string.discord_status_default_name) } } ) - val STATUS_TEXT_A: PreferencesProperty by resourceDefaultValueProperty( + val STATUS_TEXT_A: PlatformSettingsProperty by resourceDefaultValueProperty( getName = { stringResource(Res.string.s_key_discord_status_text_a) }, getDescription = { stringResource(Res.string.s_sub_discord_status_text_a) }, - getDefaultValueSuspending = { ProjectBuildConfig.DISCORD_STATUS_TEXT_TEXT_A_OVERRIDE ?: getString(Res.string.discord_status_default_text_a) }, - getDefaultValueComposable = { ProjectBuildConfig.DISCORD_STATUS_TEXT_TEXT_A_OVERRIDE ?: stringResource(Res.string.discord_status_default_text_a) } + getDefaultValue = { ProjectBuildConfig.DISCORD_STATUS_TEXT_TEXT_A_OVERRIDE ?: runBlocking { getString(Res.string.discord_status_default_text_a) } } ) - val STATUS_TEXT_B: PreferencesProperty by resourceDefaultValueProperty( + val STATUS_TEXT_B: PlatformSettingsProperty by resourceDefaultValueProperty( getName = { stringResource(Res.string.s_key_discord_status_text_b) }, getDescription = { stringResource(Res.string.s_sub_discord_status_text_b) }, - getDefaultValueSuspending = { ProjectBuildConfig.DISCORD_STATUS_TEXT_TEXT_B_OVERRIDE ?: getString(Res.string.discord_status_default_text_b) }, - getDefaultValueComposable = { ProjectBuildConfig.DISCORD_STATUS_TEXT_TEXT_B_OVERRIDE ?: stringResource(Res.string.discord_status_default_text_b) } + getDefaultValue = { ProjectBuildConfig.DISCORD_STATUS_TEXT_TEXT_B_OVERRIDE ?: runBlocking { getString(Res.string.discord_status_default_text_b) } } ) - val STATUS_TEXT_C: PreferencesProperty by resourceDefaultValueProperty( + val STATUS_TEXT_C: PlatformSettingsProperty by resourceDefaultValueProperty( getName = { stringResource(Res.string.s_key_discord_status_text_c) }, getDescription = { stringResource(Res.string.s_sub_discord_status_text_c) }, - getDefaultValueSuspending = { ProjectBuildConfig.DISCORD_STATUS_TEXT_TEXT_C_OVERRIDE ?: getString(Res.string.discord_status_default_text_c) }, - getDefaultValueComposable = { ProjectBuildConfig.DISCORD_STATUS_TEXT_TEXT_C_OVERRIDE ?: stringResource(Res.string.discord_status_default_text_c) } + getDefaultValue = { ProjectBuildConfig.DISCORD_STATUS_TEXT_TEXT_C_OVERRIDE ?: runBlocking { getString(Res.string.discord_status_default_text_c) } } ) - val SHOW_SONG_BUTTON: PreferencesProperty by property( + val SHOW_SONG_BUTTON: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_discord_status_show_button_song) }, getDescription = { stringResource(Res.string.s_sub_discord_status_show_button_song) }, getDefaultValue = { true } ) - val SONG_BUTTON_TEXT: PreferencesProperty by resourceDefaultValueProperty( + val SONG_BUTTON_TEXT: PlatformSettingsProperty by resourceDefaultValueProperty( getName = { stringResource(Res.string.s_key_discord_status_button_song_text) }, getDescription = { null }, - getDefaultValueSuspending = { ProjectBuildConfig.DISCORD_STATUS_TEXT_BUTTON_SONG_OVERRIDE ?: getString(Res.string.discord_status_default_button_song) }, - getDefaultValueComposable = { ProjectBuildConfig.DISCORD_STATUS_TEXT_BUTTON_SONG_OVERRIDE ?: stringResource(Res.string.discord_status_default_button_song) } + getDefaultValue = { ProjectBuildConfig.DISCORD_STATUS_TEXT_BUTTON_SONG_OVERRIDE ?: runBlocking { getString(Res.string.discord_status_default_button_song) } } ) - val SHOW_PROJECT_BUTTON: PreferencesProperty by property( + val SHOW_PROJECT_BUTTON: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_discord_status_show_button_project) }, getDescription = { stringResource(Res.string.s_sub_discord_status_show_button_project) }, getDefaultValue = { true } ) - val PROJECT_BUTTON_TEXT: PreferencesProperty by resourceDefaultValueProperty( + val PROJECT_BUTTON_TEXT: PlatformSettingsProperty by resourceDefaultValueProperty( getName = { stringResource(Res.string.s_key_discord_status_button_project_text) }, getDescription = { null }, - getDefaultValueSuspending = { ProjectBuildConfig.DISCORD_STATUS_TEXT_BUTTON_PROJECT_OVERRIDE ?: getString(Res.string.discord_status_default_button_project) }, - getDefaultValueComposable = { ProjectBuildConfig.DISCORD_STATUS_TEXT_BUTTON_PROJECT_OVERRIDE ?: stringResource(Res.string.discord_status_default_button_project) } + getDefaultValue = { ProjectBuildConfig.DISCORD_STATUS_TEXT_BUTTON_PROJECT_OVERRIDE ?: runBlocking { getString(Res.string.discord_status_default_button_project) } } ) @Composable diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ExperimentalSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ExperimentalSettings.kt index df3fcb3c9..e7142a9af 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ExperimentalSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ExperimentalSettings.kt @@ -4,10 +4,11 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Science import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getExperimentalCategoryItems -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_desc_experimental @@ -17,8 +18,8 @@ import spmp.shared.generated.resources.s_sub_android_monet_colour_enable class ExperimentalSettings( val context: AppContext -): SettingsGroup("EXPERIMENTAL", context.getPrefs()) { - val ANDROID_MONET_COLOUR_ENABLE: PreferencesProperty by property( +): SettingsGroupImpl("EXPERIMENTAL", context.getPrefs()) { + val ANDROID_MONET_COLOUR_ENABLE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_android_monet_colour_enable) }, getDescription = { stringResource(Res.string.s_sub_android_monet_colour_enable) }, getDefaultValue = { false } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/FeedSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/FeedSettings.kt index b5ea64dba..93f5e302e 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/FeedSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/FeedSettings.kt @@ -4,11 +4,12 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.FormatListBulleted import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getFeedCategoryItems -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_desc_feed @@ -26,53 +27,53 @@ import spmp.shared.generated.resources.s_key_feed_square_preview_text_lines import spmp.shared.generated.resources.s_key_hidden_feed_rows import spmp.shared.generated.resources.s_sub_feed_initial_rows -class FeedSettings(val context: AppContext): SettingsGroup("FEED", context.getPrefs()) { - val SHOW_ARTISTS_ROW: PreferencesProperty by property( +class FeedSettings(val context: AppContext): SettingsGroupImpl("FEED", context.getPrefs()) { + val SHOW_ARTISTS_ROW: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_feed_show_artists_row) }, getDescription = { null }, getDefaultValue = { true } ) - val SHOW_SONG_DOWNLOAD_INDICATORS: PreferencesProperty by property( + val SHOW_SONG_DOWNLOAD_INDICATORS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_feed_show_song_download_indicators) }, getDescription = { null }, getDefaultValue = { false } ) - val INITIAL_ROWS: PreferencesProperty by property( + val INITIAL_ROWS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_feed_initial_rows) }, getDescription = { stringResource(Res.string.s_sub_feed_initial_rows) }, getDefaultValue = { 4 } ) - val SQUARE_PREVIEW_TEXT_LINES: PreferencesProperty by property( + val SQUARE_PREVIEW_TEXT_LINES: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_feed_square_preview_text_lines) }, getDescription = { null }, getDefaultValue = { if (Platform.DESKTOP.isCurrent()) 2 else 2 } ) - val GRID_ROW_COUNT: PreferencesProperty by property( + val GRID_ROW_COUNT: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_feed_grid_row_count) }, getDescription = { null }, getDefaultValue = { if (Platform.DESKTOP.isCurrent()) 1 else 2 } ) - val GRID_ROW_COUNT_EXPANDED: PreferencesProperty by property( + val GRID_ROW_COUNT_EXPANDED: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_feed_grid_row_count_expanded) }, getDescription = { null }, getDefaultValue = { if (Platform.DESKTOP.isCurrent()) 1 else 2 } ) - val LANDSCAPE_GRID_ROW_COUNT: PreferencesProperty by property( + val LANDSCAPE_GRID_ROW_COUNT: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_feed_alt_grid_row_count) }, getDescription = { null }, getDefaultValue = { if (Platform.DESKTOP.isCurrent()) 1 else 1 } ) - val LANDSCAPE_GRID_ROW_COUNT_EXPANDED: PreferencesProperty by property( + val LANDSCAPE_GRID_ROW_COUNT_EXPANDED: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_feed_alt_grid_row_count_expanded) }, getDescription = { null }, getDefaultValue = { if (Platform.DESKTOP.isCurrent()) 1 else 1 } ) - val SHOW_RADIOS: PreferencesProperty by property( + val SHOW_RADIOS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_feed_show_radios) }, getDescription = { null }, getDefaultValue = { false } ) - val HIDDEN_ROWS: PreferencesProperty> by property( + val HIDDEN_ROWS: PlatformSettingsProperty> by property( getName = { stringResource(Res.string.s_key_hidden_feed_rows) }, getDescription = { stringResource(Res.string.s_hidden_feed_rows_dialog_title) }, getDefaultValue = { emptySet() } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/FilterSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/FilterSettings.kt index 9e5995afc..1a8892627 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/FilterSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/FilterSettings.kt @@ -4,10 +4,11 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.FilterAlt import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getFilterCategoryItems -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_desc_filter @@ -19,28 +20,28 @@ import spmp.shared.generated.resources.s_key_filter_enable import spmp.shared.generated.resources.s_key_filter_title_keywords import spmp.shared.generated.resources.s_sub_filter_title_keywords -class FilterSettings(val context: AppContext): SettingsGroup("FILTER", context.getPrefs()) { - val ENABLE: PreferencesProperty by property( +class FilterSettings(val context: AppContext): SettingsGroupImpl("FILTER", context.getPrefs()) { + val ENABLE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_filter_enable) }, getDescription = { null }, getDefaultValue = { true } ) - val APPLY_TO_PLAYLIST_ITEMS: PreferencesProperty by property( + val APPLY_TO_PLAYLIST_ITEMS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_filter_apply_to_playlist_items) }, getDescription = { null }, getDefaultValue = { false } ) - val APPLY_TO_ARTISTS: PreferencesProperty by property( + val APPLY_TO_ARTISTS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_filter_apply_to_artists) }, getDescription = { null }, getDefaultValue = { false } ) - val APPLY_TO_ARTIST_ITEMS: PreferencesProperty by property( + val APPLY_TO_ARTIST_ITEMS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_filter_apply_to_artist_items) }, getDescription = { null }, getDefaultValue = { false } ) - val TITLE_KEYWORDS: PreferencesProperty> by property( + val TITLE_KEYWORDS: PlatformSettingsProperty> by property( getName = { stringResource(Res.string.s_key_filter_title_keywords) }, getDescription = { stringResource(Res.string.s_sub_filter_title_keywords) }, getDefaultValue = { emptySet() } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/InterfaceSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/InterfaceSettings.kt new file mode 100644 index 000000000..625a1ff4e --- /dev/null +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/InterfaceSettings.kt @@ -0,0 +1,47 @@ +package com.toasterofbread.spmp.model.settings.category + +import com.toasterofbread.spmp.model.settings.SettingsGroup +import com.toasterofbread.spmp.platform.AppContext +import dev.toastbits.composekit.commonsettings.impl.group.impl.ComposeKitSettingsGroupInterfaceImpl +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.LocaleSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.util.model.Locale +import dev.toastbits.composekit.util.model.LocaleList +import org.jetbrains.compose.resources.stringResource +import spmp.shared.generated.resources.Res +import spmp.shared.generated.resources.language_name +import spmp.shared.generated.resources.s_key_data_lang +import spmp.shared.generated.resources.s_sub_data_lang + +class InterfaceSettings( + context: AppContext +): ComposeKitSettingsGroupInterfaceImpl( + "INTERFACE", + context.getPrefs(), + Res.string.language_name +), SettingsGroup { + val DATA_LOCALE: PlatformSettingsProperty by nullableSerialisableProperty( + getName = { stringResource(Res.string.s_key_data_lang) }, + getDescription = { stringResource(Res.string.s_sub_data_lang) }, + getDefaultValue = { null } + ) + + override fun getConfigurationItems(): List { + val items: MutableList = super.getConfigurationItems().toMutableList() + + val uiLocaleIndex: Int = + items.indexOfFirst { (it as? LocaleSettingsItem)?.state == UI_LOCALE } + check(uiLocaleIndex != -1) { items.toList() } + + val dataLocaleItem: SettingsItem = + LocaleSettingsItem( + DATA_LOCALE, + localeList = LocaleList.Localised(localeNameResource), + allowCustomLocale = true + ) + + items.add(uiLocaleIndex + 1, dataLocaleItem) + return items + } +} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/LayoutSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/LayoutSettings.kt index f29082fd3..07234b9d1 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/LayoutSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/LayoutSettings.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getLayoutCategoryItems @@ -43,11 +44,11 @@ import com.toasterofbread.spmp.ui.layout.contentbar.ContentBarReference import com.toasterofbread.spmp.ui.layout.contentbar.CustomContentBar import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.ColourSource import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlotEditorPreviewOptions -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.vibrant_accent -import dev.toastbits.composekit.utils.common.thenWith +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.thenWith import kotlinx.serialization.json.JsonElement import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res @@ -55,7 +56,7 @@ import spmp.shared.generated.resources.layout_editor_preview_options import spmp.shared.generated.resources.s_cat_desc_layout import spmp.shared.generated.resources.s_cat_layout -class LayoutSettings(val context: AppContext): SettingsGroup("LAYOUT", context.getPrefs()) { +class LayoutSettings(val context: AppContext): SettingsGroupImpl("LAYOUT", context.getPrefs()) { // // Map of LayoutSlot to ContentBarReference? // PORTRAIT_SLOTS, // LANDSCAPE_SLOTS, @@ -71,27 +72,27 @@ class LayoutSettings(val context: AppContext): SettingsGroup("LAYOUT", context.g // // List of serialised CustomBars // CUSTOM_BARS; - val PORTRAIT_SLOTS: PreferencesProperty> by serialisableProperty( + val PORTRAIT_SLOTS: PlatformSettingsProperty> by serialisableProperty( getName = { "" }, getDescription = { null }, getDefaultValue = { emptyMap() } ) - val LANDSCAPE_SLOTS: PreferencesProperty> by serialisableProperty( + val LANDSCAPE_SLOTS: PlatformSettingsProperty> by serialisableProperty( getName = { "" }, getDescription = { null }, getDefaultValue = { emptyMap() } ) - val SLOT_COLOURS: PreferencesProperty> by serialisableProperty( + val SLOT_COLOURS: PlatformSettingsProperty> by serialisableProperty( getName = { "" }, getDescription = { null }, getDefaultValue = { emptyMap() } ) - val SLOT_CONFIGS: PreferencesProperty> by serialisableProperty( + val SLOT_CONFIGS: PlatformSettingsProperty> by serialisableProperty( getName = { "" }, getDescription = { null }, getDefaultValue = { emptyMap() } ) - val CUSTOM_BARS: PreferencesProperty> by serialisableProperty( + val CUSTOM_BARS: PlatformSettingsProperty> by serialisableProperty( getName = { "" }, getDescription = { null }, getDefaultValue = { emptyList() } @@ -161,7 +162,7 @@ class LayoutSettings(val context: AppContext): SettingsGroup("LAYOUT", context.g } .platformClickable(onClick = {}) .background(player.theme.background, shape) - .border(1.dp, player.theme.vibrant_accent, shape) + .border(1.dp, player.theme.vibrantAccent, shape) .padding(20.dp) ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/LyricsSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/LyricsSettings.kt index 9861da31e..4bbbd90f5 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/LyricsSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/LyricsSettings.kt @@ -4,10 +4,11 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.MusicNote import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getLyricsCategoryItems -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_desc_lyrics @@ -32,63 +33,63 @@ import spmp.shared.generated.resources.s_sub_lyrics_sync_delay import spmp.shared.generated.resources.s_sub_lyrics_sync_delay_bluetooth import spmp.shared.generated.resources.s_sub_lyrics_sync_delay_topbar -class LyricsSettings(val context: AppContext): SettingsGroup("LYRICS", context.getPrefs()) { - val FOLLOW_ENABLED: PreferencesProperty by property( +class LyricsSettings(val context: AppContext): SettingsGroupImpl("LYRICS", context.getPrefs()) { + val FOLLOW_ENABLED: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_follow_enabled) }, getDescription = { stringResource(Res.string.s_sub_lyrics_follow_enabled) }, getDefaultValue = { true } ) - val FOLLOW_OFFSET: PreferencesProperty by property( + val FOLLOW_OFFSET: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_follow_offset) }, getDescription = { stringResource(Res.string.s_sub_lyrics_follow_offset) }, getDefaultValue = { 0.25f } ) - val ROMANISE_FURIGANA: PreferencesProperty by property( + val ROMANISE_FURIGANA: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_romanise_furigana) }, getDescription = { null }, getDefaultValue = { false } ) - val DEFAULT_FURIGANA: PreferencesProperty by property( + val DEFAULT_FURIGANA: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_default_furigana) }, getDescription = { null }, getDefaultValue = { true } ) - val TEXT_ALIGNMENT: PreferencesProperty by property( + val TEXT_ALIGNMENT: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_text_alignment) }, getDescription = { null }, getDefaultValue = { 0 } // Left, center, right ) - val EXTRA_PADDING: PreferencesProperty by property( + val EXTRA_PADDING: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_extra_padding) }, getDescription = { stringResource(Res.string.s_sub_lyrics_extra_padding) }, getDefaultValue = { true } ) - val ENABLE_WORD_SYNC: PreferencesProperty by property( + val ENABLE_WORD_SYNC: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_enable_word_sync) }, getDescription = { stringResource(Res.string.s_sub_lyrics_enable_word_sync) }, getDefaultValue = { false } ) - val FONT_SIZE: PreferencesProperty by property( + val FONT_SIZE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_font_size) }, getDescription = { null }, getDefaultValue = { 0.5f } ) - val DEFAULT_SOURCE: PreferencesProperty by property( + val DEFAULT_SOURCE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_default_source) }, getDescription = { null }, getDefaultValue = { 0 } ) - val SYNC_DELAY: PreferencesProperty by property( + val SYNC_DELAY: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_sync_delay) }, getDescription = { stringResource(Res.string.s_sub_lyrics_sync_delay) }, getDefaultValue = { 0f } ) - val SYNC_DELAY_TOPBAR: PreferencesProperty by property( + val SYNC_DELAY_TOPBAR: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_sync_delay_topbar) }, getDescription = { stringResource(Res.string.s_sub_lyrics_sync_delay_topbar) }, getDefaultValue = { -0.5f } ) - val SYNC_DELAY_BLUETOOTH: PreferencesProperty by property( + val SYNC_DELAY_BLUETOOTH: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_lyrics_sync_delay_bluetooth) }, getDescription = { stringResource(Res.string.s_sub_lyrics_sync_delay_bluetooth) }, getDefaultValue = { 0.3f } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/MiscSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/MiscSettings.kt index 19a5dbce5..9c084220d 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/MiscSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/MiscSettings.kt @@ -5,39 +5,60 @@ import androidx.compose.material.icons.outlined.MoreHoriz import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector import com.toasterofbread.spmp.ProjectBuildConfig +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getMiscCategoryItems -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_desc_misc import spmp.shared.generated.resources.s_cat_misc +import spmp.shared.generated.resources.s_key_add_songs_to_history import spmp.shared.generated.resources.s_key_enable_thumbnail_cache +import spmp.shared.generated.resources.s_key_library_path import spmp.shared.generated.resources.s_key_navbar_height_multiplier +import spmp.shared.generated.resources.s_key_persistent_queue import spmp.shared.generated.resources.s_key_status_webhook_payload import spmp.shared.generated.resources.s_key_status_webhook_url +import spmp.shared.generated.resources.s_sub_library_path import spmp.shared.generated.resources.s_sub_navbar_height_multiplier +import spmp.shared.generated.resources.s_sub_persistent_queue import spmp.shared.generated.resources.s_sub_status_webhook_payload import spmp.shared.generated.resources.s_sub_status_webhook_url -class MiscSettings(val context: AppContext): SettingsGroup("MISC", context.getPrefs()) { - val NAVBAR_HEIGHT_MULTIPLIER: PreferencesProperty by property( +class MiscSettings(val context: AppContext): SettingsGroupImpl("MISC", context.getPrefs()) { + val LIBRARY_PATH: PlatformSettingsProperty by property( + getName = { stringResource(Res.string.s_key_library_path) }, + getDescription = { stringResource(Res.string.s_sub_library_path) }, + getDefaultValue = { "" } + ) + val PERSISTENT_QUEUE: PlatformSettingsProperty by property( + getName = { stringResource(Res.string.s_key_persistent_queue) }, + getDescription = { stringResource(Res.string.s_sub_persistent_queue) }, + getDefaultValue = { true } + ) + val ADD_SONGS_TO_HISTORY: PlatformSettingsProperty by property( + getName = { stringResource(Res.string.s_key_add_songs_to_history) }, + getDescription = { stringResource(Res.string.s_key_add_songs_to_history) }, + getDefaultValue = { false } + ) + val NAVBAR_HEIGHT_MULTIPLIER: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_navbar_height_multiplier) }, getDescription = { stringResource(Res.string.s_sub_navbar_height_multiplier) }, getDefaultValue = { 1f } ) - val STATUS_WEBHOOK_URL: PreferencesProperty by property( + val STATUS_WEBHOOK_URL: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_status_webhook_url) }, getDescription = { stringResource(Res.string.s_sub_status_webhook_url) }, getDefaultValue = { ProjectBuildConfig.STATUS_WEBHOOK_URL ?: "" } ) - val STATUS_WEBHOOK_PAYLOAD: PreferencesProperty by property( + val STATUS_WEBHOOK_PAYLOAD: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_status_webhook_payload) }, getDescription = { stringResource(Res.string.s_sub_status_webhook_payload) }, getDefaultValue = { ProjectBuildConfig.STATUS_WEBHOOK_PAYLOAD ?: "{}" } ) - val THUMB_CACHE_ENABLED: PreferencesProperty by property( + val THUMB_CACHE_ENABLED: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_enable_thumbnail_cache) }, getDescription = { null }, getDefaultValue = { true } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/PlatformSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/PlatformSettings.kt index 469563d78..0a3289891 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/PlatformSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/PlatformSettings.kt @@ -7,11 +7,12 @@ import androidx.compose.material.icons.outlined.Web import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector import com.toasterofbread.spmp.ProjectBuildConfig +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getPlatformCategoryItems -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_android @@ -35,43 +36,43 @@ import spmp.shared.generated.resources.s_sub_local_server_command import spmp.shared.generated.resources.s_sub_server_local_start_automatically import spmp.shared.generated.resources.s_sub_startup_command -class PlatformSettings(val context: AppContext): SettingsGroup("DESKTOP", context.getPrefs()) { - val STARTUP_COMMAND: PreferencesProperty by property( +class PlatformSettings(val context: AppContext): SettingsGroupImpl("DESKTOP", context.getPrefs()) { + val STARTUP_COMMAND: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_startup_command) }, getDescription = { stringResource(Res.string.s_sub_startup_command) }, getDefaultValue = { "" } ) - val FORCE_SOFTWARE_RENDERER: PreferencesProperty by property( + val FORCE_SOFTWARE_RENDERER: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_force_software_renderer) }, getDescription = { stringResource(Res.string.s_sub_force_software_renderer) }, getDefaultValue = { false } ) - val SERVER_IP_ADDRESS: PreferencesProperty by property( + val SERVER_IP_ADDRESS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_server_ip) }, getDescription = { null }, getDefaultValue = { "127.0.0.1" } ) - val SERVER_PORT: PreferencesProperty by property( + val SERVER_PORT: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_server_port) }, getDescription = { null }, getDefaultValue = { ProjectBuildConfig.SERVER_PORT ?: 3973 } ) - val SERVER_LOCAL_COMMAND: PreferencesProperty by property( + val SERVER_LOCAL_COMMAND: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_local_server_command) }, getDescription = { stringResource(Res.string.s_sub_local_server_command) }, getDefaultValue = { "" } ) - val SERVER_LOCAL_START_AUTOMATICALLY: PreferencesProperty by property( + val SERVER_LOCAL_START_AUTOMATICALLY: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_server_local_start_automatically) }, getDescription = { stringResource(Res.string.s_sub_server_local_start_automatically) }, getDefaultValue = { true } ) - val ENABLE_EXTERNAL_SERVER_MODE: PreferencesProperty by property( + val ENABLE_EXTERNAL_SERVER_MODE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_enable_external_server_mode) }, getDescription = { stringResource(Res.string.s_sub_enable_external_server_mode) }, getDefaultValue = { false } ) - val EXTERNAL_SERVER_MODE_UI_ONLY: PreferencesProperty by property( + val EXTERNAL_SERVER_MODE_UI_ONLY: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_external_server_mode_ui_only) }, getDescription = { stringResource(Res.string.s_sub_external_server_mode_ui_only) }, getDefaultValue = { false } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/PlayerSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/PlayerSettings.kt index a39fa6e94..0fd74377c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/PlayerSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/PlayerSettings.kt @@ -4,11 +4,12 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.PlayArrow import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getPlayerCategoryItems import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.PlayerOverlayMenuAction -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_desc_player @@ -44,93 +45,93 @@ import spmp.shared.generated.resources.s_sub_player_show_repeat_shuffle_buttons import spmp.shared.generated.resources.s_sub_resume_on_bt_connect import spmp.shared.generated.resources.s_sub_resume_on_wired_connect -class PlayerSettings(val context: AppContext): SettingsGroup("PLAYER", context.getPrefs()) { - val MINI_SHOW_PREV_BUTTON: PreferencesProperty by property( +class PlayerSettings(val context: AppContext): SettingsGroupImpl("PLAYER", context.getPrefs()) { + val MINI_SHOW_PREV_BUTTON: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_mini_player_show_prev_button) }, getDescription = { null }, getDefaultValue = { false } ) - val MINI_OVERSCROLL_CLEAR_ENABLED: PreferencesProperty by property( + val MINI_OVERSCROLL_CLEAR_ENABLED: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_mini_player_overscroll_clear_enabled) }, getDescription = { null }, getDefaultValue = { false } ) - val MINI_OVERSCROLL_CLEAR_TIME: PreferencesProperty by property( + val MINI_OVERSCROLL_CLEAR_TIME: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_mini_player_overscroll_clear_time) }, getDescription = { null }, getDefaultValue = { 0.2f } ) - val MINI_OVERSCROLL_CLEAR_MODE: PreferencesProperty by enumProperty( + val MINI_OVERSCROLL_CLEAR_MODE: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_mini_player_overscroll_clear_mode) }, getDescription = { null }, getDefaultValue = { OverscrollClearMode.HIDE_IF_QUEUE_EMPTY } ) - val SHOW_REPEAT_SHUFFLE_BUTTONS: PreferencesProperty by property( + val SHOW_REPEAT_SHUFFLE_BUTTONS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_player_show_repeat_shuffle_buttons) }, getDescription = { stringResource(Res.string.s_sub_player_show_repeat_shuffle_buttons) }, getDefaultValue = { false } ) - val SHOW_SEEK_BAR_GRADIENT: PreferencesProperty by property( + val SHOW_SEEK_BAR_GRADIENT: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_player_show_progress_bar_gradient) }, getDescription = { null }, getDefaultValue = { true } ) - val LANDSCAPE_SWAP_CONTROLS_AND_IMAGE: PreferencesProperty by property( + val LANDSCAPE_SWAP_CONTROLS_AND_IMAGE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_player_landscape_swap_controls_and_image) }, getDescription = { null }, getDefaultValue = { false } ) - val OVERLAY_CUSTOM_ACTION: PreferencesProperty by enumProperty( + val OVERLAY_CUSTOM_ACTION: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_player_overlay_menu_custom_action) }, getDescription = { stringResource(Res.string.s_sub_player_overlay_menu_custom_action) }, getDefaultValue = { PlayerOverlayMenuAction.DEFAULT_CUSTOM } ) - val OVERLAY_SWAP_LONG_SHORT_PRESS_ACTIONS: PreferencesProperty by property( + val OVERLAY_SWAP_LONG_SHORT_PRESS_ACTIONS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_player_overlay_menu_swap_long_short_press_actions) }, getDescription = { null }, getDefaultValue = { false } ) - val QUEUE_ITEM_SWIPE_SENSITIVITY: PreferencesProperty by property( + val QUEUE_ITEM_SWIPE_SENSITIVITY: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_np_queue_item_swipe_sensitivity) }, getDescription = { stringResource(Res.string.s_sub_np_queue_item_swipe_sensitivity) }, getDefaultValue = { 1f } ) - val QUEUE_EXTRA_SIDE_PADDING: PreferencesProperty by property( + val QUEUE_EXTRA_SIDE_PADDING: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_np_queue_extra_side_padding) }, getDescription = { stringResource(Res.string.s_sub_np_queue_extra_side_padding) }, getDefaultValue = { 0f } ) - val QUEUE_WAVE_BORDER_MODE: PreferencesProperty by enumProperty( + val QUEUE_WAVE_BORDER_MODE: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_np_queue_wave_border_mode) }, getDescription = { stringResource(Res.string.s_sub_np_queue_wave_border_mode) }, getDefaultValue = { NowPlayingQueueWaveBorderMode.TIME } ) - val QUEUE_RADIO_INFO_POSITION: PreferencesProperty by enumProperty( + val QUEUE_RADIO_INFO_POSITION: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_np_queue_radio_info_position) }, getDescription = { null }, getDefaultValue = { NowPlayingQueueRadioInfoPosition.TOP_BAR } ) - val RESUME_ON_BT_CONNECT: PreferencesProperty by property( + val RESUME_ON_BT_CONNECT: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_resume_on_bt_connect) }, getDescription = { stringResource(Res.string.s_sub_resume_on_bt_connect) }, getDefaultValue = { true } ) - val PAUSE_ON_BT_DISCONNECT: PreferencesProperty by property( + val PAUSE_ON_BT_DISCONNECT: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_pause_on_bt_disconnect) }, getDescription = { null }, getDefaultValue = { true } ) - val RESUME_ON_WIRED_CONNECT: PreferencesProperty by property( + val RESUME_ON_WIRED_CONNECT: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_resume_on_wired_connect) }, getDescription = { stringResource(Res.string.s_sub_resume_on_wired_connect) }, getDefaultValue = { true } ) - val PAUSE_ON_WIRED_DISCONNECT: PreferencesProperty by property( + val PAUSE_ON_WIRED_DISCONNECT: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_pause_on_wired_disconnect) }, getDescription = { null }, getDefaultValue = { true } ) - val EXPAND_SWIPE_SENSITIVITY: PreferencesProperty by property( + val EXPAND_SWIPE_SENSITIVITY: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_player_expand_swipe_sensitivity) }, getDescription = { null }, getDefaultValue = { 3.5f } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/SearchSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/SearchSettings.kt index 22c193485..3a99d0fbd 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/SearchSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/SearchSettings.kt @@ -4,17 +4,18 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Search import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getSearchCategoryItems -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_key_search_search_for_non_music import spmp.shared.generated.resources.s_sub_search_search_for_non_music -class SearchSettings(val context: AppContext): SettingsGroup("SEARCH", context.getPrefs()) { - val SEARCH_FOR_NON_MUSIC: PreferencesProperty by property( +class SearchSettings(val context: AppContext): SettingsGroupImpl("SEARCH", context.getPrefs()) { + val SEARCH_FOR_NON_MUSIC: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_search_search_for_non_music) }, getDescription = { stringResource(Res.string.s_sub_search_search_for_non_music) }, getDefaultValue = { false } @@ -31,5 +32,5 @@ class SearchSettings(val context: AppContext): SettingsGroup("SEARCH", context.g override fun getConfigurationItems(): List = getSearchCategoryItems(context) - override fun getPage(): CategoryPage? = null + override val hidden: Boolean = true } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/SettingsGroup.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/SettingsGroup.kt deleted file mode 100644 index e67305686..000000000 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/SettingsGroup.kt +++ /dev/null @@ -1,147 +0,0 @@ -package com.toasterofbread.spmp.model.settings.category - -import LocalPlayerState -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.CardDefaults -import androidx.compose.material3.ElevatedCard -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.unit.dp -import com.toasterofbread.spmp.platform.AppContext -import dev.toastbits.composekit.platform.PlatformPreferences -import dev.toastbits.composekit.platform.PreferencesGroupImpl -import dev.toastbits.composekit.platform.composable.theme.LocalApplicationTheme -import dev.toastbits.composekit.settings.ui.SettingsInterface -import dev.toastbits.composekit.settings.ui.SettingsPageWithItems -import dev.toastbits.composekit.settings.ui.ThemeValues -import dev.toastbits.composekit.settings.ui.component.item.ComposableSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.utils.common.amplifyPercent - -sealed class SettingsGroup( - key: String, - prefs: PlatformPreferences -): PreferencesGroupImpl(key, prefs) { - override val group_key: String = key - - // val id: String = id.uppercase() - // abstract val keys: List - -// abstract val page: CategoryPage? - - open fun showPage(exporting: Boolean): Boolean = true - - // fun getNameOfKey(key: SettingsKey): String = - // "${id}_${(key as Enum<*>).name}" - - // fun getKeyOfName(name: String): SettingsKey? { - // val split: List = name.split('_', limit = 2) - // if (split.size != 2 || split[0] != id) { - // return null - // } - - // return keys.firstOrNull { - // (it as Enum<*>).name == split[1] - // } - // } - - open fun getPage(): CategoryPage? = - SimplePage( - { getTitle() }, - { getDescription() }, - { getConfigurationItems() }, - { getIcon() }, - { titleBarEndContent(it) } - ) - - @Composable - protected open fun titleBarEndContent(modifier: Modifier) {} - - abstract class CategoryPage( - val group: SettingsGroup, - val getTitle: @Composable () -> String - ) { - abstract fun getTitleItem(context: AppContext): SettingsItem? - abstract fun openPage(context: AppContext) - open fun getItems(context: AppContext): List? = null - } - - protected open inner class SimplePage( - getTitle: @Composable () -> String, - val getDescription: @Composable () -> String, - private val getPageItems: () -> List, - private val getPageIcon: @Composable () -> ImageVector, - private val titleBarEndContent: @Composable (Modifier) -> Unit = {} - ): CategoryPage(this, getTitle) { - private var items: List? = null - - private val settings_interface: SettingsInterface - get() = SpMp.player_state.app_page_state.Settings.settings_interface - - override fun openPage(context: AppContext) { - settings_interface.openPage( - object : SettingsPageWithItems( - getTitle = getTitle, - getItems = { getItems(context) }, - getIcon = getPageIcon - ) { - @Composable - override fun TitleBarEndContent(modifier: Modifier) { - titleBarEndContent(modifier) - super.TitleBarEndContent(modifier) - } - - @Composable - override fun canResetKeys(): Boolean = - getItems(LocalPlayerState.current.context).isNotEmpty() - } - ) - } - - override fun getItems(context: AppContext): List { - if (items == null) { - items = getPageItems().filter { item -> - item.getProperties().none { it.isHidden() } - } - } - return items!! - } - - override fun getTitleItem(context: AppContext): SettingsItem? = - ComposableSettingsItem { modifier -> - val theme: ThemeValues = LocalApplicationTheme.current - ElevatedCard( - onClick = { - openPage(context) - }, - modifier = modifier.fillMaxWidth(), - colors = CardDefaults.elevatedCardColors( - containerColor = theme.background.amplifyPercent(0.03f), - contentColor = theme.on_background - ) - ) { - Row( - Modifier.padding(15.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(15.dp) - ) { - Icon(getPageIcon(), null) - Column(verticalArrangement = Arrangement.spacedBy(5.dp)) { - Text(getTitle(), style = MaterialTheme.typography.titleMedium) - Text(getDescription(), style = MaterialTheme.typography.labelMedium, modifier = Modifier.alpha(0.7f)) - } - } - } - } - } -} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ShortcutSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ShortcutSettings.kt index 05d7b49ed..f805ec9a4 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ShortcutSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ShortcutSettings.kt @@ -5,10 +5,11 @@ import androidx.compose.material.icons.outlined.Adjust import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector import com.toasterofbread.spmp.model.appaction.shortcut.Shortcut +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getShortcutCategoryItems -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_desc_shortcut @@ -16,13 +17,13 @@ import spmp.shared.generated.resources.s_cat_shortcut import spmp.shared.generated.resources.s_key_configured_shortcuts import spmp.shared.generated.resources.s_key_navigate_song_with_numbers -class ShortcutSettings(val context: AppContext): SettingsGroup("SHORTCUT", context.getPrefs()) { - val CONFIGURED_SHORTCUTS: PreferencesProperty?> by nullableSerialisableProperty( +class ShortcutSettings(val context: AppContext): SettingsGroupImpl("SHORTCUT", context.getPrefs()) { + val CONFIGURED_SHORTCUTS: PlatformSettingsProperty?> by nullableSerialisableProperty( getName = { stringResource(Res.string.s_key_configured_shortcuts) }, getDescription = { null }, getDefaultValue = { null } ) - val NAVIGATE_SONG_WITH_NUMBERS: PreferencesProperty by property( + val NAVIGATE_SONG_WITH_NUMBERS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_navigate_song_with_numbers) }, getDescription = { null }, getDefaultValue = { true } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/StreamingSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/StreamingSettings.kt index bd4e0f910..32b264d5c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/StreamingSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/StreamingSettings.kt @@ -5,11 +5,12 @@ import androidx.compose.material.icons.outlined.Speaker import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector import com.toasterofbread.spmp.model.mediaitem.song.SongAudioQuality +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.download.DownloadMethod import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getStreamingCategoryItems -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import dev.toastbits.ytmkt.formats.VideoFormatsEndpoint import dev.toastbits.ytmkt.model.YtmApi import org.jetbrains.compose.resources.stringResource @@ -37,58 +38,58 @@ import spmp.shared.generated.resources.video_format_endpoint_newpipe import spmp.shared.generated.resources.video_format_endpoint_piped import spmp.shared.generated.resources.video_format_endpoint_youtubei -class StreamingSettings(val context: AppContext): SettingsGroup("STREAMING", context.getPrefs()) { - val VIDEO_FORMATS_METHOD: PreferencesProperty by enumProperty( +class StreamingSettings(val context: AppContext): SettingsGroupImpl("STREAMING", context.getPrefs()) { + val VIDEO_FORMATS_METHOD: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_video_formats_endpoint) }, getDescription = { null }, getDefaultValue = { VideoFormatsEndpointType.DEFAULT } ) - val ENABLE_VIDEO_FORMAT_FALLBACK: PreferencesProperty by property( + val ENABLE_VIDEO_FORMAT_FALLBACK: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_enable_video_format_fallback) }, getDescription = { null }, getDefaultValue = { true } ) - val AUTO_DOWNLOAD_ENABLED: PreferencesProperty by property( + val AUTO_DOWNLOAD_ENABLED: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_auto_download_enabled) }, getDescription = { null }, getDefaultValue = { true } ) - val AUTO_DOWNLOAD_THRESHOLD: PreferencesProperty by property( + val AUTO_DOWNLOAD_THRESHOLD: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_auto_download_threshold) }, getDescription = { stringResource(Res.string.s_sub_auto_download_threshold) }, getDefaultValue = { 1 } // Listens ) - val AUTO_DOWNLOAD_ON_METERED: PreferencesProperty by property( + val AUTO_DOWNLOAD_ON_METERED: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_auto_download_on_metered) }, getDescription = { null }, getDefaultValue = { false } ) - val STREAM_AUDIO_QUALITY: PreferencesProperty by enumProperty( + val STREAM_AUDIO_QUALITY: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_stream_audio_quality) }, getDescription = { stringResource(Res.string.s_sub_stream_audio_quality) }, getDefaultValue = { SongAudioQuality.HIGH } ) - val DOWNLOAD_AUDIO_QUALITY: PreferencesProperty by enumProperty( + val DOWNLOAD_AUDIO_QUALITY: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_download_audio_quality) }, getDescription = { stringResource(Res.string.s_sub_download_audio_quality) }, getDefaultValue = { SongAudioQuality.HIGH } ) - val ENABLE_AUDIO_NORMALISATION: PreferencesProperty by property( + val ENABLE_AUDIO_NORMALISATION: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_enable_audio_normalisation) }, getDescription = { stringResource(Res.string.s_sub_enable_audio_normalisation) }, getDefaultValue = { false } ) - val ENABLE_SILENCE_SKIPPING: PreferencesProperty by property( + val ENABLE_SILENCE_SKIPPING: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_enable_silence_skipping) }, getDescription = { null }, getDefaultValue = { false } ) - val DOWNLOAD_METHOD: PreferencesProperty by enumProperty( + val DOWNLOAD_METHOD: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_download_method) }, getDescription = { stringResource(Res.string.s_sub_download_method) }, getDefaultValue = { DownloadMethod.DEFAULT } ) - val SKIP_DOWNLOAD_METHOD_CONFIRMATION: PreferencesProperty by property( + val SKIP_DOWNLOAD_METHOD_CONFIRMATION: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_skip_download_method_confirmation) }, getDescription = { stringResource(Res.string.s_sub_skip_download_method_confirmation) }, getDefaultValue = { false } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/SystemSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/SystemSettings.kt deleted file mode 100644 index ceec4d953..000000000 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/SystemSettings.kt +++ /dev/null @@ -1,113 +0,0 @@ -package com.toasterofbread.spmp.model.settings.category - -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.Tune -import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.vector.ImageVector -import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.resources.Language -import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getSystemCategoryItems -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import org.jetbrains.compose.resources.FontResource -import org.jetbrains.compose.resources.stringResource -import spmp.shared.generated.resources.Res -import spmp.shared.generated.resources.`font_option_default_$x` -import spmp.shared.generated.resources.font_option_hc_maru_gothic -import spmp.shared.generated.resources.font_option_system -import spmp.shared.generated.resources.hc_maru_gothic -import spmp.shared.generated.resources.s_cat_desc_general -import spmp.shared.generated.resources.s_cat_general -import spmp.shared.generated.resources.s_key_add_songs_to_history -import spmp.shared.generated.resources.s_key_data_lang -import spmp.shared.generated.resources.s_key_font -import spmp.shared.generated.resources.s_key_interface_lang -import spmp.shared.generated.resources.s_key_library_path -import spmp.shared.generated.resources.s_key_persistent_queue -import spmp.shared.generated.resources.s_key_ui_scale -import spmp.shared.generated.resources.s_sub_data_lang -import spmp.shared.generated.resources.s_sub_interface_lang -import spmp.shared.generated.resources.s_sub_library_path -import spmp.shared.generated.resources.s_sub_persistent_queue - -class SystemSettings( - val context: AppContext, - private val available_languages: List -): SettingsGroup("SYSTEM", context.getPrefs()) { - val LANG_UI: PreferencesProperty by property( - getName = { stringResource(Res.string.s_key_interface_lang) }, - getDescription = { stringResource(Res.string.s_sub_interface_lang) }, - getDefaultValue = { "" } - ) - val LANG_DATA: PreferencesProperty by property( - getName = { stringResource(Res.string.s_key_data_lang) }, - getDescription = { stringResource(Res.string.s_sub_data_lang) }, - getDefaultValue = { "" } - ) - val FONT: PreferencesProperty by enumProperty( - getName = { stringResource(Res.string.s_key_font) }, - getDescription = { null }, - getDefaultValue = { FontMode.DEFAULT } - ) - val UI_SCALE: PreferencesProperty by property( - getName = { stringResource(Res.string.s_key_ui_scale) }, - getDescription = { null }, - getDefaultValue = { 1f } - ) - val LIBRARY_PATH: PreferencesProperty by property( - getName = { stringResource(Res.string.s_key_library_path) }, - getDescription = { stringResource(Res.string.s_sub_library_path) }, - getDefaultValue = { "" } - ) - val PERSISTENT_QUEUE: PreferencesProperty by property( - getName = { stringResource(Res.string.s_key_persistent_queue) }, - getDescription = { stringResource(Res.string.s_sub_persistent_queue) }, - getDefaultValue = { true } - ) - val ADD_SONGS_TO_HISTORY: PreferencesProperty by property( - getName = { stringResource(Res.string.s_key_add_songs_to_history) }, - getDescription = { stringResource(Res.string.s_key_add_songs_to_history) }, - getDefaultValue = { false } - ) - - @Composable - override fun getTitle(): String = stringResource(Res.string.s_cat_general) - - @Composable - override fun getDescription(): String = stringResource(Res.string.s_cat_desc_general) - - @Composable - override fun getIcon(): ImageVector = Icons.Outlined.Tune - - override fun getConfigurationItems(): List = getSystemCategoryItems(context, available_languages) -} - -enum class FontMode { - DEFAULT, SYSTEM, HC_MARU_GOTHIC; - - fun getFontResource(language: String): FontResource? = - when (this) { - DEFAULT -> getDefaultFont(language).getFontResource(language) - SYSTEM -> null - HC_MARU_GOTHIC -> Res.font.hc_maru_gothic - } - - @Composable - fun getReadable(language: String): String = - when (this) { - DEFAULT -> { - val default_font: String = getDefaultFont(language).getReadable(language) - stringResource(Res.string.`font_option_default_$x`).replace("\$x", default_font) - } - SYSTEM -> stringResource(Res.string.font_option_system) - HC_MARU_GOTHIC -> stringResource(Res.string.font_option_hc_maru_gothic) - } - - companion object { - fun getDefaultFont(language: String): FontMode = - when (language) { - "ja-JP" -> HC_MARU_GOTHIC - else -> SYSTEM - } - } -} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ThemeSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ThemeSettings.kt index c2722c241..99292724d 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ThemeSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/ThemeSettings.kt @@ -1,30 +1,23 @@ package com.toasterofbread.spmp.model.settings.category -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Palette import androidx.compose.runtime.Composable -import androidx.compose.runtime.State -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember import androidx.compose.ui.graphics.vector.ImageVector +import com.toasterofbread.spmp.model.settings.SettingsGroup import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getThemeCategoryItems import com.toasterofbread.spmp.ui.layout.nowplaying.ThemeMode -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.NamedTheme -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.getDefaultCatppuccinThemes -import dev.toastbits.composekit.settings.ui.getSystemTheme +import dev.toastbits.composekit.commonsettings.impl.group.impl.ComposeKitSettingsGroupThemeImpl +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.util.platform.Platform import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_desc_theme import spmp.shared.generated.resources.s_cat_theme import spmp.shared.generated.resources.s_key_accent_source -import spmp.shared.generated.resources.s_key_current_theme import spmp.shared.generated.resources.s_key_enable_window_transparency import spmp.shared.generated.resources.s_key_np_default_background_image_video_opacity import spmp.shared.generated.resources.s_key_np_default_gradient_depth @@ -40,60 +33,48 @@ import spmp.shared.generated.resources.s_key_np_default_wave_speed import spmp.shared.generated.resources.s_key_np_theme_mode import spmp.shared.generated.resources.s_key_show_expanded_player_wave import spmp.shared.generated.resources.s_key_window_background_opacity -import spmp.shared.generated.resources.s_option_accent_theme -import spmp.shared.generated.resources.s_option_accent_thumbnail +import spmp.shared.generated.resources.s_optionAccent_theme +import spmp.shared.generated.resources.s_optionAccent_thumbnail import spmp.shared.generated.resources.s_sub_enable_window_transparency import spmp.shared.generated.resources.s_sub_window_background_opacity -import spmp.shared.generated.resources.s_theme_editor_title -import spmp.shared.generated.resources.theme_title_system -class ThemeSettings(val context: AppContext): SettingsGroup("THEME", context.getPrefs()) { - val CURRENT_THEME: PreferencesProperty by property( - getName = { stringResource(Res.string.s_key_current_theme) }, - getDescription = { null }, - getDefaultValue = { 0 } - ) - val THEMES: PreferencesProperty> by serialisableProperty( - getName = { stringResource(Res.string.s_theme_editor_title) }, - getDescription = { null }, - getDefaultValue = { getDefaultCatppuccinThemes() } - ) - val ACCENT_COLOUR_SOURCE: PreferencesProperty by enumProperty( +class ThemeSettings(val context: AppContext): ComposeKitSettingsGroupThemeImpl("THEME", context.getPrefs()), SettingsGroup { + val ACCENT_COLOUR_SOURCE: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_accent_source) }, getDescription = { null }, getDefaultValue = { AccentColourSource.DEFAULT } ) - val NOWPLAYING_THEME_MODE: PreferencesProperty by enumProperty( + val NOWPLAYING_THEME_MODE: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_np_theme_mode) }, getDescription = { null }, getDefaultValue = { ThemeMode.DEFAULT } ) - val NOWPLAYING_DEFAULT_GRADIENT_DEPTH: PreferencesProperty by property( + val NOWPLAYING_DEFAULT_GRADIENT_DEPTH: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_np_default_gradient_depth) }, getDescription = { null }, getDefaultValue = { 1f } ) - val NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY: PreferencesProperty by property( + val NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_np_default_background_image_video_opacity) }, getDescription = { null }, getDefaultValue = { 0.5f } ) - val NOWPLAYING_DEFAULT_VIDEO_POSITION: PreferencesProperty by enumProperty( + val NOWPLAYING_DEFAULT_VIDEO_POSITION: PlatformSettingsProperty by enumProperty( getName = { stringResource(Res.string.s_key_np_default_video_position) }, getDescription = { null }, getDefaultValue = { VideoPosition.NONE } ) - val NOWPLAYING_DEFAULT_LANDSCAPE_QUEUE_OPACITY: PreferencesProperty by property( + val NOWPLAYING_DEFAULT_LANDSCAPE_QUEUE_OPACITY: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_np_default_landscape_queue_opacity) }, getDescription = { null }, getDefaultValue = { 0.5f } ) - val NOWPLAYING_DEFAULT_SHADOW_RADIUS: PreferencesProperty by property( + val NOWPLAYING_DEFAULT_SHADOW_RADIUS: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_np_default_shadow_radius) }, getDescription = { null }, getDefaultValue = { 0.5f } ) - val NOWPLAYING_DEFAULT_IMAGE_CORNER_ROUNDING: PreferencesProperty by property( + val NOWPLAYING_DEFAULT_IMAGE_CORNER_ROUNDING: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_np_default_image_corner_rounding) }, getDescription = { null }, getDefaultValue = { @@ -104,27 +85,27 @@ class ThemeSettings(val context: AppContext): SettingsGroup("THEME", context.get } } ) - val NOWPLAYING_DEFAULT_WAVE_SPEED: PreferencesProperty by property( + val NOWPLAYING_DEFAULT_WAVE_SPEED: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_np_default_wave_speed) }, getDescription = { null }, getDefaultValue = { 0.5f } ) - val NOWPLAYING_DEFAULT_WAVE_OPACITY: PreferencesProperty by property( + val NOWPLAYING_DEFAULT_WAVE_OPACITY: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_np_default_wave_opacity) }, getDescription = { null }, getDefaultValue = { 0.5f } ) - val SHOW_EXPANDED_PLAYER_WAVE: PreferencesProperty by property( + val SHOW_EXPANDED_PLAYER_WAVE: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_show_expanded_player_wave) }, getDescription = { null }, getDefaultValue = { true } ) - val ENABLE_WINDOW_TRANSPARENCY: PreferencesProperty by property( + val ENABLE_WINDOW_TRANSPARENCY: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_enable_window_transparency) }, getDescription = { stringResource(Res.string.s_sub_enable_window_transparency) }, getDefaultValue = { false } ) - val WINDOW_BACKGROUND_OPACITY: PreferencesProperty by property( + val WINDOW_BACKGROUND_OPACITY: PlatformSettingsProperty by property( getName = { stringResource(Res.string.s_key_window_background_opacity) }, getDescription = { stringResource(Res.string.s_sub_window_background_opacity) }, getDefaultValue = { 1f } @@ -139,7 +120,7 @@ class ThemeSettings(val context: AppContext): SettingsGroup("THEME", context.get @Composable override fun getIcon(): ImageVector = Icons.Outlined.Palette - override fun getConfigurationItems(): List = getThemeCategoryItems(context) + override fun getConfigurationItems(): List = super.getConfigurationItems() + getThemeCategoryItems(context) enum class VideoPosition { NONE, BACKGROUND, THUMBNAIL; @@ -159,32 +140,11 @@ enum class AccentColourSource { fun getNameResource(): StringResource = when (this) { - THEME -> Res.string.s_option_accent_theme - THUMBNAIL -> Res.string.s_option_accent_thumbnail + THEME -> Res.string.s_optionAccent_theme + THUMBNAIL -> Res.string.s_optionAccent_thumbnail } companion object { val DEFAULT: AccentColourSource = THUMBNAIL } } - -@Composable -fun observeCurrentTheme(context: AppContext, index_override: Int? = null): State { - val dark_mode: Boolean = isSystemInDarkTheme() - val system_theme_name: String = stringResource(Res.string.theme_title_system) - - val theme_index: Int by context.settings.theme.CURRENT_THEME.observe() - val themes: List by context.settings.theme.THEMES.observe() - - return remember(dark_mode, index_override) { derivedStateOf { - val system_theme: NamedTheme = getSystemTheme(system_theme_name, dark_mode, context) - themes.getOrNull((index_override ?: theme_index) - 1) ?: system_theme - } } -} - -suspend fun getCurrentTheme(context: AppContext, system_theme: NamedTheme, index_override: Int? = null): NamedTheme { - val theme_index: Int = context.settings.theme.CURRENT_THEME.get() - val themes: List = context.settings.theme.THEMES.get() - - return themes.getOrNull((index_override ?: theme_index) - 1) ?: system_theme -} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/WidgetSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/WidgetSettings.kt index 9f7b05898..136dfde1e 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/WidgetSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/WidgetSettings.kt @@ -4,6 +4,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Widgets import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getWidgetCategoryItems import com.toasterofbread.spmp.widget.SpMpWidgetType @@ -11,9 +12,9 @@ import com.toasterofbread.spmp.widget.action.TypeWidgetClickAction import com.toasterofbread.spmp.widget.configuration.base.BaseWidgetConfig import com.toasterofbread.spmp.widget.configuration.SpMpWidgetConfiguration import com.toasterofbread.spmp.widget.configuration.type.TypeWidgetConfig -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_desc_widget @@ -21,15 +22,15 @@ import spmp.shared.generated.resources.s_cat_widget class WidgetSettings( val context: AppContext -): SettingsGroup("WIDGET", context.getPrefs()) { - val DEFAULT_BASE_WIDGET_CONFIGURATION: PreferencesProperty by serialisableProperty( +): SettingsGroupImpl("WIDGET", context.getPrefs()) { + val DEFAULT_BASE_WIDGET_CONFIGURATION: PlatformSettingsProperty by serialisableProperty( getName = { "" }, getDescription = { null }, getDefaultValue = { BaseWidgetConfig() }, json = SpMpWidgetConfiguration.json ) - val DEFAULT_TYPE_WIDGET_CONFIGURATIONS: PreferencesProperty>> by serialisableProperty( + val DEFAULT_TYPE_WIDGET_CONFIGURATIONS: PlatformSettingsProperty>> by serialisableProperty( getName = { "" }, getDescription = { null }, getDefaultValue = { emptyMap() }, @@ -45,8 +46,7 @@ class WidgetSettings( @Composable override fun getIcon(): ImageVector = Icons.Outlined.Widgets - override fun showPage(exporting: Boolean): Boolean = - Platform.ANDROID.isCurrent() + override val hidden: Boolean = !Platform.ANDROID.isCurrent() override fun getConfigurationItems(): List = getWidgetCategoryItems(context) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/YTApiSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/YTApiSettings.kt index 1656818a3..aafa71336 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/YTApiSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/YTApiSettings.kt @@ -4,21 +4,19 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.PlayCircle import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.youtubeapi.YtmApiType -import com.toasterofbread.spmp.platform.AppContext -import dev.toastbits.composekit.platform.PlatformPreferences -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settings.PlatformSettings +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem -class YTApiSettings(prefs: PlatformPreferences): SettingsGroup("YTAPI", prefs) { - override fun getPage(): CategoryPage? = null - - val API_TYPE: PreferencesProperty by enumProperty( +class YTApiSettings(prefs: PlatformSettings): SettingsGroupImpl("YTAPI", prefs) { + val API_TYPE: PlatformSettingsProperty by enumProperty( getName = { "" }, getDescription = { null }, getDefaultValue = { YtmApiType.DEFAULT } ) - val API_URL: PreferencesProperty by property( + val API_URL: PlatformSettingsProperty by property( getName = { "" }, getDescription = { null }, getDefaultValue = { YtmApiType.DEFAULT.getDefaultUrl() } @@ -34,4 +32,6 @@ class YTApiSettings(prefs: PlatformPreferences): SettingsGroup("YTAPI", prefs) { override fun getIcon(): ImageVector = Icons.Outlined.PlayCircle override fun getConfigurationItems(): List = emptyList() + + override val hidden: Boolean = true } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/YoutubeAuthSettings.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/YoutubeAuthSettings.kt index b01752230..c4d38ce58 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/YoutubeAuthSettings.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/model/settings/category/YoutubeAuthSettings.kt @@ -1,17 +1,21 @@ package com.toasterofbread.spmp.model.settings.category +import LocalPlayerState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.PlayCircle import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import com.toasterofbread.spmp.ProjectBuildConfig +import com.toasterofbread.spmp.model.settings.SettingsGroupImpl import com.toasterofbread.spmp.model.settings.packSetData import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.ui.layout.apppage.settingspage.PrefsPageScreen +import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.apppage.settingspage.getYtmAuthItem -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.SettingsInterface -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settings.ComposeKitSettingsGroupWithCustomPreview +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import dev.toastbits.ytmkt.model.ApiAuthenticationState import io.ktor.http.Headers import kotlinx.serialization.json.Json @@ -19,13 +23,13 @@ import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_cat_youtube_auth -class YoutubeAuthSettings(val context: AppContext): SettingsGroup("YTAUTH", context.getPrefs()) { - override fun getUnregisteredProperties(): List> = +class YoutubeAuthSettings(val context: AppContext): SettingsGroupImpl("YTAUTH", context.getPrefs()), ComposeKitSettingsGroupWithCustomPreview { + override fun getUnregisteredProperties(): List> = listOf( - context.settings.system.ADD_SONGS_TO_HISTORY + context.settings.Misc.ADD_SONGS_TO_HISTORY ) - val YTM_AUTH: PreferencesProperty> by property( + val YTM_AUTH: PlatformSettingsProperty> by property( getName = { "" }, getDescription = { null }, getDefaultValue = { @@ -46,22 +50,12 @@ class YoutubeAuthSettings(val context: AppContext): SettingsGroup("YTAUTH", cont } ) - override fun getPage(): CategoryPage? = - object : CategoryPage( - this, - { stringResource(Res.string.s_cat_youtube_auth) } - ) { - override fun openPage(context: AppContext) { - val manual: Boolean = false - SpMp.player_state.app_page_state.Settings.settings_interface.openPageById(PrefsPageScreen.YOUTUBE_MUSIC_LOGIN.ordinal, manual) - } - - override fun getTitleItem(context: AppContext): SettingsItem? = - getYtmAuthItem( - context, - YTM_AUTH - ) - } + @Composable + override fun PreviewContent(modifier: Modifier, onSelected: () -> Unit) { + val player: PlayerState = LocalPlayerState.current + val item: SettingsItem = remember { getYtmAuthItem(player.context, YTM_AUTH) } + item.Item(modifier) + } @Composable override fun getTitle(): String = stringResource(Res.string.s_cat_youtube_auth) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/AppContext.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/AppContext.kt index c0479c5a1..4d0ea717c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/AppContext.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/AppContext.kt @@ -2,13 +2,11 @@ package com.toasterofbread.spmp.platform import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.State import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.intl.Locale @@ -17,113 +15,66 @@ import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.db.Database import com.toasterofbread.spmp.model.settings.Settings import com.toasterofbread.spmp.model.settings.category.AccentColourSource -import com.toasterofbread.spmp.model.settings.category.getCurrentTheme -import com.toasterofbread.spmp.model.settings.category.observeCurrentTheme import com.toasterofbread.spmp.platform.download.PlayerDownloadManager import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.PlatformContextImpl -import dev.toastbits.composekit.platform.PlatformPreferences -import dev.toastbits.composekit.platform.PlatformPreferencesListener -import dev.toastbits.composekit.settings.ui.NamedTheme -import dev.toastbits.composekit.settings.ui.ThemeManager -import dev.toastbits.composekit.settings.ui.ThemeValues -import dev.toastbits.composekit.settings.ui.rememberSystemTheme +import dev.toastbits.composekit.commonsettings.impl.group.theme.SettingsThemeManager +import dev.toastbits.composekit.context.PlatformContext +import dev.toastbits.composekit.settings.PlatformSettings +import dev.toastbits.composekit.settings.PlatformSettingsListener +import dev.toastbits.composekit.theme.core.ThemeManager +import dev.toastbits.composekit.theme.core.ThemeValues +import dev.toastbits.composekit.util.platform.Platform import dev.toastbits.ytmkt.model.YtmApi -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import org.jetbrains.compose.resources.stringResource -import spmp.shared.generated.resources.Res -import spmp.shared.generated.resources.theme_title_system +import dev.toastbits.composekit.util.model.Locale as ComposeKitLocale -expect class AppContext: PlatformContextImpl { +expect class AppContext: PlatformContext { val database: Database val download_manager: PlayerDownloadManager val ytapi: YtmApi - val theme: AppThemeManager + val theme: ThemeManager val settings: Settings - fun getPrefs(): PlatformPreferences + fun getPrefs(): PlatformSettings } class AppThemeManager( private val context: AppContext -): ThemeValues { - override val accent: Color - get() = _manager?.accent ?: Color.Unspecified - override val background: Color - get() = _manager?.background ?: Color.Unspecified - override val card: Color - get() = _manager?.card ?: Color.Unspecified - override val on_background: Color - get() = _manager?.on_background ?: Color.Unspecified - override val error: Color - get() = _manager?.error ?: Color.Unspecified - - private var accent_colour_source: AccentColourSource? by mutableStateOf(null) - - var _manager: ThemeManager? = null - private set - val manager: ThemeManager get() = _manager!! - - @Composable - fun Update(): Boolean { - val system_theme: NamedTheme = rememberSystemTheme(stringResource(Res.string.theme_title_system), context) - val composable_coroutine_scope: CoroutineScope = rememberCoroutineScope() - var initialised: Boolean by remember { mutableStateOf(false) } - - LaunchedEffect(Unit) { - val initial_theme: NamedTheme = getCurrentTheme(context, system_theme) - - _manager = object : ThemeManager( - initial_theme.theme, - composable_coroutine_scope - ) { - override fun selectAccentColour(values: ThemeValues, thumbnail_colour: Color?): Color = - when(accent_colour_source ?: AccentColourSource.THEME) { - AccentColourSource.THEME -> values.accent - AccentColourSource.THUMBNAIL -> thumbnail_colour ?: values.accent - } - } - - initialised = true +): SettingsThemeManager(context.settings) { + private var accent_colour_source: AccentColourSource? by + mutableStateOf(context.settings.Theme.ACCENT_COLOUR_SOURCE.get()) + private var background_opacity: Float by + mutableStateOf(context.settings.Theme.NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY.get()) + + override fun selectAccentColour(values: ThemeValues, contextualColour: Color?): Color = + when(accent_colour_source ?: AccentColourSource.THEME) { + AccentColourSource.THEME -> values.accent + AccentColourSource.THUMBNAIL -> contextualColour ?: values.accent } - val theme: NamedTheme by observeCurrentTheme(context) - - LaunchedEffect(theme, initialised) { - if (!initialised) { - return@LaunchedEffect - } - - manager.setTheme(theme.theme) - } - - return initialised - } - - fun onCurrentThumbnailColourChanged(thumbnail_colour: Color?) { - manager.onThumbnailColourChanged(thumbnail_colour) - } - - private val prefs_listener: PlatformPreferencesListener = - PlatformPreferencesListener { key -> + private val prefs_listener: PlatformSettingsListener = + PlatformSettingsListener { key -> when (key) { - context.settings.theme.ACCENT_COLOUR_SOURCE.key -> { - context.coroutine_scope.launch { - accent_colour_source = context.settings.theme.ACCENT_COLOUR_SOURCE.get() - } + context.settings.Theme.ACCENT_COLOUR_SOURCE.key -> { + accent_colour_source = context.settings.Theme.ACCENT_COLOUR_SOURCE.get() + } + context.settings.Theme.NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY.key -> { + background_opacity = context.settings.Theme.NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY.get() } } } + override val background: Color + get() = super.background.copy(alpha = background_opacity) + + override val card: Color + get() = super.card.copy(alpha = background_opacity) + init { - val prefs: PlatformPreferences = context.getPrefs() + val prefs: PlatformSettings = context.getPrefs() prefs.addListener(prefs_listener) - context.coroutine_scope.launch { - accent_colour_source = context.settings.theme.ACCENT_COLOUR_SOURCE.get() - } + accent_colour_source = context.settings.Theme.ACCENT_COLOUR_SOURCE.get() } } @@ -137,33 +88,34 @@ fun PlayerState.getDefaultVerticalPadding(): Dp = @Composable fun PlayerState.getDefaultPaddingValues(): PaddingValues = PaddingValues(horizontal = getDefaultHorizontalPadding(), vertical = getDefaultVerticalPadding()) -suspend fun AppContext.getUiLanguage(): String = - settings.system.LANG_UI.get().ifEmpty { getDefaultLanguage() } +suspend fun AppContext.getUiLanguage() = + settings.Interface.UI_LOCALE.get() ?: getDefaultLanguage() @Composable -fun AppContext.observeUiLanguage(): State { - val lang_ui: String by settings.system.LANG_UI.observe() +fun AppContext.observeUiLanguage(): State { + val lang_ui: ComposeKitLocale? by settings.Interface.UI_LOCALE.observe() return remember { derivedStateOf { - lang_ui.ifEmpty { getDefaultLanguage() } + lang_ui ?: getDefaultLanguage() } } } -suspend fun AppContext.getDataLanguage(): String = - settings.system.LANG_DATA.get().ifEmpty { getDefaultLanguage() } - .let { if (it == "en-GB") "en-US" else it } +suspend fun AppContext.getDataLanguage(): ComposeKitLocale = + settings.Interface.DATA_LOCALE.get() ?: getDefaultLanguage() + .let { + if (it == ComposeKitLocale("en", "GB")) ComposeKitLocale("en", "US") + else it + } @Composable -fun AppContext.observeDataLanguage(): State { - val lang_data: String by settings.system.LANG_DATA.observe() +fun AppContext.observeDataLanguage(): State { + val lang_data: ComposeKitLocale? by settings.Interface.DATA_LOCALE.observe() return remember { derivedStateOf { - lang_data.ifEmpty { getDefaultLanguage() } + lang_data ?: getDefaultLanguage() } } } -fun AppContext.getDefaultLanguage(): String = - Locale.current.run { - "$language-$region" - } +fun AppContext.getDefaultLanguage(): ComposeKitLocale = + ComposeKitLocale(Locale.current.language, Locale.current.region) fun Result.getOrNotify(context: AppContext, error_key: String): T? = fold( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/ProjectJson.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/ProjectJson.kt index 22f327254..a6da831a8 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/ProjectJson.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/ProjectJson.kt @@ -7,5 +7,6 @@ object ProjectJson { Json { ignoreUnknownKeys = true explicitNulls = false + useArrayPolymorphism = true } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/download/DownloadMethodSelectionDialog.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/download/DownloadMethodSelectionDialog.kt index 7684f6033..ae5f2e028 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/download/DownloadMethodSelectionDialog.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/download/DownloadMethodSelectionDialog.kt @@ -21,15 +21,18 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.WidthShrinkText import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.mediaitempreview.MediaItemPreviewLong +import dev.toastbits.composekit.util.composable.WidthShrinkText +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.action_cancel @@ -46,22 +49,23 @@ fun DownloadMethodSelectionDialog( songs: List? = null ) { val player: PlayerState = LocalPlayerState.current + val coroutine_scope: CoroutineScope = rememberCoroutineScope() - var download_method: DownloadMethod by player.settings.streaming.DOWNLOAD_METHOD.observe() - var skip_confirmation: Boolean by player.settings.streaming.SKIP_DOWNLOAD_METHOD_CONFIRMATION.observe() + var download_method: DownloadMethod by player.settings.Streaming.DOWNLOAD_METHOD.observe() + var skip_confirmation: Boolean by player.settings.Streaming.SKIP_DOWNLOAD_METHOD_CONFIRMATION.observe() var show: Boolean by remember { mutableStateOf(false) } var initial_download_method: DownloadMethod? by remember { mutableStateOf(null) } var initial_skip_confirmation: Boolean? by remember { mutableStateOf(null) } LaunchedEffect(Unit) { - initial_download_method = player.settings.streaming.DOWNLOAD_METHOD.get() - initial_skip_confirmation = player.settings.streaming.SKIP_DOWNLOAD_METHOD_CONFIRMATION.get() + initial_download_method = player.settings.Streaming.DOWNLOAD_METHOD.get() + initial_skip_confirmation = player.settings.Streaming.SKIP_DOWNLOAD_METHOD_CONFIRMATION.get() } - fun cancel() { - player.settings.streaming.DOWNLOAD_METHOD.set(initial_download_method!!) - player.settings.streaming.SKIP_DOWNLOAD_METHOD_CONFIRMATION.set(initial_skip_confirmation!!) + suspend fun cancel() { + player.settings.Streaming.DOWNLOAD_METHOD.set(initial_download_method!!) + player.settings.Streaming.SKIP_DOWNLOAD_METHOD_CONFIRMATION.set(initial_skip_confirmation!!) onCancelled() } @@ -81,11 +85,15 @@ fun DownloadMethodSelectionDialog( AlertDialog( modifier = modifier, onDismissRequest = { - cancel() + coroutine_scope.launch { + cancel() + } }, dismissButton = { Button({ - cancel() + coroutine_scope.launch { + cancel() + } }) { Text(stringResource(Res.string.action_cancel)) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.kt index 457d67cc1..1f1cb1da6 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.kt @@ -11,9 +11,8 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.PlatformFile -import dev.toastbits.composekit.platform.synchronized +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary import com.toasterofbread.spmp.model.mediaitem.song.Song @@ -48,7 +47,7 @@ enum class DownloadMethod { CUSTOM -> stringResource(Res.string.download_method_desc_custom) } - suspend fun execute(context: AppContext, songs: List, callback: DownloadRequestCallback?) = + suspend fun execute(context: AppContext, songs: List, callback: DownloadRequestCallback?) { when (this) { LIBRARY -> { for (song in songs) { @@ -57,67 +56,66 @@ enum class DownloadMethod { } CUSTOM -> { if (songs.size == 1) { - context.promptUserForFileCreation( - // TODO | Remove hardcoded MIME type - "audio/mp4", - songs.single().getActiveTitle(context.database), - false - ) { uri -> - if (uri == null) { - callback?.invoke(null) - return@promptUserForFileCreation - } - - context.download_manager.startDownload( - songs.single(), - custom_uri = uri, - download_lyrics = false, - direct = true, - callback = callback + val file: PlatformFile? = + context.promptUserForFileCreation( + // TODO | Remove hardcoded MIME type + "audio/mp4", + songs.single().getActiveTitle(context.database), + false ) + + if (file == null) { + callback?.invoke(null) + return } + + context.download_manager.startDownload( + songs.single(), + custom_uri = file.uri, + download_lyrics = false, + direct = true, + callback = callback + ) } else { - context.promptUserForDirectory(persist = true) { uri -> - if (uri == null) { - callback?.invoke(null) - return@promptUserForDirectory - } - - val directory: PlatformFile = context.getUserDirectoryFile(uri) ?: return@promptUserForDirectory - - Platform.ANDROID.only { - directory.mkdirs() - } + val directory: PlatformFile? = context.promptUserForDirectory(persist = true) + if (directory == null) { + callback?.invoke(null) + return + } - context.coroutine_scope.launch { - for (song in songs) { - var file: PlatformFile - val name: String = song.getActiveTitle(context.database) ?: getString(MediaItemType.SONG.getReadable(false)) - - var i: Int = 0 - do { - // TODO | Remove hardcoded file type - var file_name = name + ".m4a" - if (i++ >= 1) { - file_name += " (${i + 1})" - } - file = directory.resolve(file_name) - } - while (file.exists) + Platform.ANDROID.only { + directory.mkdirs() + } - Platform.ANDROID.only { - // File must be created at this stage on Android, it will fail if done later - file.createFile() + context.coroutineScope.launch { + for (song in songs) { + var file: PlatformFile + val name: String = song.getActiveTitle(context.database) ?: getString(MediaItemType.SONG.getReadable(false)) + + var i: Int = 0 + do { + // TODO | Remove hardcoded file type + var file_name = name + ".m4a" + if (i++ >= 1) { + file_name += " (${i + 1})" } + file = directory.resolve(file_name) + } + while (file.exists) - context.download_manager.startDownload(song, custom_uri = file.uri, download_lyrics = false, callback = callback) + Platform.ANDROID.only { + // File must be created at this stage on Android, it will fail if done later + file.createFile() } + + context.download_manager.startDownload(song, custom_uri = file.uri, download_lyrics = false, callback = callback) } } } } } + } companion object { val DEFAULT: DownloadMethod = LIBRARY diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ExternalPlayerService.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ExternalPlayerService.kt index bacd242a1..5a414661e 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ExternalPlayerService.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/ExternalPlayerService.kt @@ -32,7 +32,7 @@ import com.toasterofbread.spmp.model.radio.RadioInstance import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.service.playercontroller.RadioHandler -import dev.toastbits.composekit.settings.ui.on_accent +import dev.toastbits.composekit.theme.core.onAccent import dev.toastbits.spms.socketapi.shared.SpMsPlayerRepeatMode import dev.toastbits.spms.socketapi.shared.SpMsPlayerState import kotlinx.coroutines.CoroutineScope @@ -61,9 +61,9 @@ open class ExternalPlayerService(plays_audio: Boolean): SpMsPlayerService(plays_ private var local_server_process: Job? by mutableStateOf(null) override suspend fun getIpAddress(): String = - if (local_server_process != null) "127.0.0.1" else context.settings.platform.SERVER_IP_ADDRESS.get() + if (local_server_process != null) "127.0.0.1" else context.settings.Platform.SERVER_IP_ADDRESS.get() override suspend fun getPort(): Int = - context.settings.platform.SERVER_PORT.get() + context.settings.Platform.SERVER_PORT.get() internal lateinit var _context: AppContext override val context: AppContext get() = _context @@ -293,7 +293,7 @@ open class ExternalPlayerService(plays_audio: Boolean): SpMsPlayerService(plays_ LocalServer.startLocalServer( player.context, - player.settings.platform.SERVER_PORT.get() + player.settings.Platform.SERVER_PORT.get() ).fold( onSuccess = { local_server_process = it @@ -344,7 +344,7 @@ open class ExternalPlayerService(plays_audio: Boolean): SpMsPlayerService(plays_ colors = ButtonDefaults.buttonColors( containerColor = player.theme.accent, - contentColor = player.theme.on_accent + contentColor = player.theme.onAccent ), modifier = item_modifier ) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlayerService.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlayerService.kt index 73b07428b..80e884e16 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlayerService.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlayerService.kt @@ -52,8 +52,8 @@ interface PlayerService: Player { } fun PlayerService.seekToPreviousOrRepeat() { - context.coroutine_scope.launch { - val threshold_s: Float = context.settings.behaviour.REPEAT_SONG_ON_PREVIOUS_THRESHOLD_S.get() + context.coroutineScope.launch { + val threshold_s: Float = context.settings.Behaviour.REPEAT_SONG_ON_PREVIOUS_THRESHOLD_S.get() val threshold: Duration? = if (threshold_s < 0f) null else (threshold_s * 1000).roundToLong().milliseconds diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlayerServicePlayer.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlayerServicePlayer.kt index 42af2db30..fb239c2d9 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlayerServicePlayer.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlayerServicePlayer.kt @@ -20,10 +20,8 @@ import com.toasterofbread.spmp.platform.PlayerListener import com.toasterofbread.spmp.service.playercontroller.DiscordStatusHandler import com.toasterofbread.spmp.service.playercontroller.PersistentQueueHandler import com.toasterofbread.spmp.service.playercontroller.RadioHandler -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.PlatformPreferencesListener -import dev.toastbits.composekit.platform.assert -import dev.toastbits.composekit.platform.synchronized +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.settings.PlatformSettingsListener import dev.toastbits.spms.socketapi.shared.SpMsPlayerRepeatMode import dev.toastbits.spms.socketapi.shared.SpMsPlayerState import io.ktor.client.HttpClient @@ -82,7 +80,7 @@ abstract class PlayerServicePlayer(internal val service: PlayerService) { abstract fun onUndoStateChanged() private val prefs_listener = - PlatformPreferencesListener { key -> + PlatformSettingsListener { key -> when (key) { // Settings.KEY_ACC_VOL_INTERCEPT_NOTIFICATION.name -> { // vol_notif_enabled = Settings.KEY_ACC_VOL_INTERCEPT_NOTIFICATION.get(preferences = prefs) @@ -139,14 +137,14 @@ abstract class PlayerServicePlayer(internal val service: PlayerService) { } private suspend fun sendStatusWebhook(song: Song?): Result = runCatching { - val webhook_url: String = context.settings.misc.STATUS_WEBHOOK_URL.get() + val webhook_url: String = context.settings.Misc.STATUS_WEBHOOK_URL.get() if (webhook_url.isBlank()) { return@runCatching } val payload: MutableMap - val user_payload: String = context.settings.misc.STATUS_WEBHOOK_PAYLOAD.get() + val user_payload: String = context.settings.Misc.STATUS_WEBHOOK_PAYLOAD.get() if (!user_payload.isBlank()) { payload = try { @@ -573,7 +571,7 @@ abstract class PlayerServicePlayer(internal val service: PlayerService) { song.incrementPlayCount(context) val mark_endpoint = context.ytapi.user_auth_state?.MarkSongAsWatched - if (mark_endpoint?.isImplemented() == true && context.settings.system.ADD_SONGS_TO_HISTORY.get()) { + if (mark_endpoint?.isImplemented() == true && context.settings.Misc.ADD_SONGS_TO_HISTORY.get()) { val result = mark_endpoint.markSongAsWatched(song.id) result.onFailure { context.sendNotification(it) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMs.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMs.kt index 80ab721a0..e09c735b0 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMs.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMs.kt @@ -2,7 +2,7 @@ package com.toasterofbread.spmp.platform.playerservice import androidx.compose.runtime.Composable import dev.toastbits.spms.socketapi.shared.SpMsClientType -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.platform.AppContext import okio.buffer import okio.use diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMsPlayerService.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMsPlayerService.kt index 126057b4a..f12923aaf 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMsPlayerService.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMsPlayerService.kt @@ -11,10 +11,9 @@ import com.toasterofbread.spmp.platform.PlatformServiceImpl import com.toasterofbread.spmp.platform.PlayerListener import com.toasterofbread.spmp.platform.download.DownloadStatus import com.toasterofbread.spmp.platform.getUiLanguage -import dev.toastbits.composekit.platform.PlatformPreferencesListener -import dev.toastbits.composekit.platform.getPlatformHostName -import dev.toastbits.composekit.platform.getPlatformOSName -import dev.toastbits.composekit.platform.synchronized +import dev.toastbits.composekit.settings.PlatformSettingsListener +import dev.toastbits.composekit.util.platform.getPlatformHostName +import dev.toastbits.composekit.util.platform.getPlatformOSName import dev.toastbits.spms.server.CLIENT_HEARTBEAT_MAX_PERIOD import dev.toastbits.spms.server.CLIENT_HEARTBEAT_TARGET_PERIOD import dev.toastbits.spms.socketapi.shared.SPMS_EXPECT_REPLY_CHAR @@ -79,10 +78,10 @@ abstract class SpMsPlayerService(val plays_audio: Boolean): PlatformServiceImpl( return getString(Res.string.app_name) + " [$os, $host]" } - private val prefs_listener: PlatformPreferencesListener = - PlatformPreferencesListener { key -> + private val prefs_listener: PlatformSettingsListener = + PlatformSettingsListener { key -> when (key) { - context.settings.youtube_auth.YTM_AUTH.key -> { + context.settings.YoutubeAuth.YTM_AUTH.key -> { sendYtmAuthToPlayers() } } @@ -212,7 +211,7 @@ abstract class SpMsPlayerService(val plays_audio: Boolean): PlatformServiceImpl( name = getClientName(), type = if (plays_audio) SpMsClientType.SPMP_PLAYER else SpMsClientType.SPMP_STANDALONE, machine_id = getSpMsMachineId(context), - language = context.getUiLanguage() + language = context.getUiLanguage().toTag() ) val server_handshake: SpMsServerHandshake = @@ -447,16 +446,16 @@ abstract class SpMsPlayerService(val plays_audio: Boolean): PlatformServiceImpl( override suspend fun sendAuthInfoToPlayers(ytm_auth: Pair?): Result = withContext(Dispatchers.PlatformIO) { return@withContext runCatching { - runCommandOnEachLocalPlayer( - "setAuthInfo", - ytm_auth?.second?.let { - buildJsonObject { - for ((key, value) in it.flattenEntries()) { - put(key, value) - } - } - } - ) + // runCommandOnEachLocalPlayer( + // "setAuthInfo", + // ytm_auth?.second?.let { + // buildJsonObject { + // for ((key, value) in it.flattenEntries()) { + // put(key, value) + // } + // } + // } + // ) } } @@ -482,7 +481,7 @@ abstract class SpMsPlayerService(val plays_audio: Boolean): PlatformServiceImpl( name = getClientName(), type = SpMsClientType.SPMP_STANDALONE, machine_id = getSpMsMachineId(context), - language = context.getUiLanguage() + language = context.getUiLanguage().toTag() ) val server_handshake: SpMsServerHandshake? = @@ -528,7 +527,7 @@ abstract class SpMsPlayerService(val plays_audio: Boolean): PlatformServiceImpl( player_status_coroutine_scope.launch { val ytm_auth: Pair? = ApiAuthenticationState.unpackSetData( - context.settings.youtube_auth.YTM_AUTH.get(), + context.settings.YoutubeAuth.YTM_AUTH.get(), context ).takeIf { it?.first != null } sendAuthInfoToPlayers(ytm_auth) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/UndoHandler.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/UndoHandler.kt index 8258070d0..7210c8beb 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/UndoHandler.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/platform/playerservice/UndoHandler.kt @@ -3,9 +3,6 @@ package com.toasterofbread.spmp.platform.playerservice import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.setValue -import dev.toastbits.composekit.utils.common.synchronizedBlock -import dev.toastbits.composekit.platform.assert -import dev.toastbits.composekit.platform.synchronized import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.util.removeLastBuiltIn @@ -147,7 +144,7 @@ internal class UndoHandler(val player: PlayerServicePlayer, val service: PlayerS } fun performAction(action: UndoRedoAction) { - synchronizedBlock(action_list) { + synchronized(action_list) { action.redo(service) val current = current_action diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/resources/Resources.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/resources/Resources.kt index ab5f510b9..67581a3e1 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/resources/Resources.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/resources/Resources.kt @@ -17,6 +17,7 @@ import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.allStringResources import spmp.shared.generated.resources.language_name +// TODO | Replace with ComposeKit Locale data class Language( val family: String, val locale: String?, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/DiscordStatusHandler.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/DiscordStatusHandler.kt index c28bd8f1e..7f51da8a6 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/DiscordStatusHandler.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/DiscordStatusHandler.kt @@ -8,9 +8,9 @@ import com.toasterofbread.spmp.model.settings.category.DiscordSettings import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.DiscordStatus import com.toasterofbread.spmp.platform.playerservice.PlayerServicePlayer -import dev.toastbits.composekit.platform.PlatformPreferencesListener -import dev.toastbits.composekit.utils.common.associateNotNull -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.settings.PlatformSettingsListener +import dev.toastbits.composekit.util.associateNotNull +import dev.toastbits.composekit.util.platform.launchSingle import dev.toastbits.ytmkt.model.external.ThumbnailProvider import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -55,17 +55,17 @@ internal class DiscordStatusHandler(val player: PlayerServicePlayer, val context private var current_status: StatusInfo? = null - private val prefs_listener: PlatformPreferencesListener = - PlatformPreferencesListener { key -> + private val prefs_listener: PlatformSettingsListener = + PlatformSettingsListener { key -> when (key) { - context.settings.discord_auth.DISCORD_ACCOUNT_TOKEN.key -> { + context.settings.DiscordAuth.DISCORD_ACCOUNT_TOKEN.key -> { load_coroutine_scope.launch { onDiscordAccountTokenChanged() } } - context.settings.discord.STATUS_ENABLE.key, - context.settings.discord.LARGE_IMAGE_SOURCE.key, - context.settings.discord.SMALL_IMAGE_SOURCE.key -> { + context.settings.Discord.STATUS_ENABLE.key, + context.settings.Discord.LARGE_IMAGE_SOURCE.key, + context.settings.Discord.SMALL_IMAGE_SOURCE.key -> { updateDiscordStatus(null) } } @@ -84,7 +84,7 @@ internal class DiscordStatusHandler(val player: PlayerServicePlayer, val context private suspend fun onDiscordAccountTokenChanged() { discord_rpc?.close() - val account_token: String = context.settings.discord_auth.DISCORD_ACCOUNT_TOKEN.get() + val account_token: String = context.settings.DiscordAuth.DISCORD_ACCOUNT_TOKEN.get() if (!DiscordStatus.isSupported() || (account_token.isBlank() && DiscordStatus.isAccountTokenRequired())) { discord_rpc = null return @@ -115,7 +115,7 @@ internal class DiscordStatusHandler(val player: PlayerServicePlayer, val context val current_song: Song? = song ?: player.getSong() val status_info: StatusInfo? = - if (context.settings.discord.STATUS_ENABLE.get()) withContext(Dispatchers.Main) { + if (context.settings.Discord.STATUS_ENABLE.get()) withContext(Dispatchers.Main) { StatusInfo( current_song, current_song?.getActiveTitle(context.database), @@ -125,8 +125,8 @@ internal class DiscordStatusHandler(val player: PlayerServicePlayer, val context System.currentTimeMillis() + player.duration_ms - player.current_position_ms ) else null, - context.settings.discord.LARGE_IMAGE_SOURCE.get(), - context.settings.discord.SMALL_IMAGE_SOURCE.get() + context.settings.Discord.LARGE_IMAGE_SOURCE.get(), + context.settings.Discord.SMALL_IMAGE_SOURCE.get() ) } else null @@ -156,10 +156,10 @@ internal class DiscordStatusHandler(val player: PlayerServicePlayer, val context return@launchSingle } - val name: String = formatText(context.settings.discord.STATUS_NAME.get(), status_info.song, status_info.title) - val text_a: String = formatText(context.settings.discord.STATUS_TEXT_A.get(), status_info.song, status_info.title) - val text_b: String = formatText(context.settings.discord.STATUS_TEXT_B.get(), status_info.song, status_info.title) - val text_c: String = formatText(context.settings.discord.STATUS_TEXT_C.get(), status_info.song, status_info.title) + val name: String = formatText(context.settings.Discord.STATUS_NAME.get(), status_info.song, status_info.title) + val text_a: String = formatText(context.settings.Discord.STATUS_TEXT_A.get(), status_info.song, status_info.title) + val text_b: String = formatText(context.settings.Discord.STATUS_TEXT_B.get(), status_info.song, status_info.title) + val text_c: String = formatText(context.settings.Discord.STATUS_TEXT_C.get(), status_info.song, status_info.title) val large_image: String? val small_image: String? @@ -198,11 +198,11 @@ internal class DiscordStatusHandler(val player: PlayerServicePlayer, val context } val buttons: MutableList> = mutableListOf>().apply { - if (context.settings.discord.SHOW_SONG_BUTTON.get()) { - add(context.settings.discord.SONG_BUTTON_TEXT.get() to status_info.song.getUrl(context)) + if (context.settings.Discord.SHOW_SONG_BUTTON.get()) { + add(context.settings.Discord.SONG_BUTTON_TEXT.get() to status_info.song.getUrl(context)) } - if (context.settings.discord.SHOW_PROJECT_BUTTON.get()) { - add(context.settings.discord.PROJECT_BUTTON_TEXT.get() to getString(Res.string.project_url)) + if (context.settings.Discord.SHOW_PROJECT_BUTTON.get()) { + add(context.settings.Discord.PROJECT_BUTTON_TEXT.get() to getString(Res.string.project_url)) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PersistentQueueHandler.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PersistentQueueHandler.kt index 895a9c155..e7d0990af 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PersistentQueueHandler.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PersistentQueueHandler.kt @@ -6,7 +6,7 @@ import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.mediaitem.song.SongData import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.playerservice.PlayerServicePlayer -import dev.toastbits.composekit.platform.Platform +import dev.toastbits.composekit.util.platform.Platform import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.joinAll @@ -17,7 +17,7 @@ import kotlinx.coroutines.sync.withPermit import kotlinx.coroutines.withContext import PlatformIO import com.toasterofbread.spmp.db.persistentqueue.PersistentQueueMetadata -import dev.toastbits.composekit.platform.lazyAssert +import dev.toastbits.composekit.util.platform.lazyAssert internal class PersistentQueueHandler(val player: PlayerServicePlayer, val context: AppContext) { private var persistent_queue_loaded: Boolean = false @@ -27,7 +27,7 @@ internal class PersistentQueueHandler(val player: PlayerServicePlayer, val conte PersistentQueueMetadata(0, player.current_item_index.toLong(), player.current_position_ms) suspend fun savePersistentQueue() { - if (!persistent_queue_loaded || !context.settings.system.PERSISTENT_QUEUE.get() || ProjectBuildConfig.DISABLE_PERSISTENT_QUEUE == true) { + if (!persistent_queue_loaded || !context.settings.Misc.PERSISTENT_QUEUE.get() || ProjectBuildConfig.DISABLE_PERSISTENT_QUEUE == true) { return } @@ -80,7 +80,7 @@ internal class PersistentQueueHandler(val player: PlayerServicePlayer, val conte } withContext(Dispatchers.PlatformIO) { - if (!context.settings.system.PERSISTENT_QUEUE.get()) { + if (!context.settings.Misc.PERSISTENT_QUEUE.get()) { println("loadPersistentQueue: Skipping, feature disabled") return@withContext diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerClickOverrides.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerClickOverrides.kt index a30fbae2c..a6d2ff1d1 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerClickOverrides.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerClickOverrides.kt @@ -30,8 +30,8 @@ data class PlayerClickOverrides( player.onPlayActionOccurred() } else if ( item is Playlist - && player.settings.behaviour.TREAT_SINGLES_AS_SONG.get() - && player.settings.behaviour.TREAT_ANY_SINGLE_ITEM_PLAYLIST_AS_SINGLE.get() + && player.settings.Behaviour.TREAT_SINGLES_AS_SONG.get() + && player.settings.Behaviour.TREAT_ANY_SINGLE_ITEM_PLAYLIST_AS_SINGLE.get() ) { player.coroutine_scope.launch { item.loadData(player.context).onSuccess { data -> diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerState.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerState.kt index df83e2b9f..20ed4c73e 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerState.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerState.kt @@ -63,14 +63,13 @@ import com.toasterofbread.spmp.ui.layout.nowplaying.ThemeMode import com.toasterofbread.spmp.ui.layout.nowplaying.container.npAnchorToDp import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.PlayerOverlayMenu import com.toasterofbread.spmp.ui.layout.playlistpage.PlaylistAppPage -import dev.toastbits.composekit.platform.PlatformPreferencesListener -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.platform.synchronized -import dev.toastbits.composekit.settings.ui.ThemeValues -import dev.toastbits.composekit.settings.ui.on_accent -import dev.toastbits.composekit.utils.composable.OnChangedEffect -import dev.toastbits.composekit.utils.composable.getEnd -import dev.toastbits.composekit.utils.composable.getStart +import dev.toastbits.composekit.settings.PlatformSettingsListener +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.components.utils.composable.getEnd +import dev.toastbits.composekit.components.utils.composable.getStart +import dev.toastbits.composekit.theme.core.ThemeManager +import dev.toastbits.composekit.theme.core.onAccent +import dev.toastbits.composekit.util.composable.OnChangedEffect import dev.toastbits.ytmkt.model.external.YoutubePage import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -93,7 +92,7 @@ class PlayerState( ) { val database: Database get() = context.database val settings: Settings get() = context.settings - val theme: AppThemeManager get() = context.theme + val theme: ThemeManager get() = context.theme val app_page: AppPage get() = app_page_state.current_page private var _player: PlayerService? by mutableStateOf(null) @@ -105,15 +104,14 @@ class PlayerState( private set private val low_memory_listener: () -> Unit - private val prefs_listner: PlatformPreferencesListener = - PlatformPreferencesListener { key -> + private val prefs_listner: PlatformSettingsListener = + PlatformSettingsListener { key -> when (key) { - settings.theme.NOWPLAYING_THEME_MODE.key -> coroutine_scope.launch { - np_theme_mode = settings.theme.NOWPLAYING_THEME_MODE.get() + settings.Theme.NOWPLAYING_THEME_MODE.key -> coroutine_scope.launch { + np_theme_mode = settings.Theme.NOWPLAYING_THEME_MODE.get() } - settings.theme.ACCENT_COLOUR_SOURCE.key -> theme._manager?.updateColours() - settings.player.EXPAND_SWIPE_SENSITIVITY.key -> coroutine_scope.launch { - np_swipe_sensitivity = settings.player.EXPAND_SWIPE_SENSITIVITY.get() + settings.Player.EXPAND_SWIPE_SENSITIVITY.key -> coroutine_scope.launch { + np_swipe_sensitivity = settings.Player.EXPAND_SWIPE_SENSITIVITY.get() } } } @@ -231,7 +229,7 @@ class PlayerState( if (PlatformInternalPlayerService.isServiceAttached(context)) { return PlatformInternalPlayerService } - if (settings.platform.ENABLE_EXTERNAL_SERVER_MODE.get()) { + if (settings.Platform.ENABLE_EXTERNAL_SERVER_MODE.get()) { return PlatformExternalPlayerService } return PlatformInternalPlayerService @@ -510,7 +508,7 @@ class PlayerState( fun onPlayActionOccurred() { coroutine_scope.launch { - if (np_swipe_state.targetValue == 0 && context.settings.behaviour.OPEN_NP_ON_SONG_PLAYED.get()) { + if (np_swipe_state.targetValue == 0 && context.settings.Behaviour.OPEN_NP_ON_SONG_PLAYED.get()) { switchNowPlayingPage(1) } } @@ -522,7 +520,7 @@ class PlayerState( if (item is Song) { playSong( item, - start_radio = context.settings.behaviour.START_RADIO_ON_SONG_PRESS.get(), + start_radio = context.settings.Behaviour.START_RADIO_ON_SONG_PRESS.get(), shuffle = shuffle, at_index = at_index ) @@ -615,7 +613,7 @@ class PlayerState( Box(Modifier.fillMaxSize().padding(15.dp)) { val background_colour: Color = theme.accent - CompositionLocalProvider(LocalContentColor provides theme.on_accent) { + CompositionLocalProvider(LocalContentColor provides theme.onAccent) { main_multiselect_context.MultiSelectInfoDisplayContent( Modifier .width(IntrinsicSize.Max) @@ -647,7 +645,7 @@ class PlayerState( val form_factor: FormFactor by FormFactor.observe() - CompositionLocalProvider(LocalContentColor provides context.theme.on_background) { + CompositionLocalProvider(LocalContentColor provides context.theme.onBackground) { val bottom_padding: Dp by animateDpAsState( if (form_factor.is_large && main_multiselect_context.is_active) multiselect_info_display_height else 0.dp diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerStatus.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerStatus.kt index d153fe976..5c075e100 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerStatus.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/PlayerStatus.kt @@ -123,7 +123,7 @@ class PlayerStatus internal constructor() { val context: AppContext = player?.context ?: return val song: Song = m_song ?: return - context.coroutine_scope.launch(Dispatchers.IO) { + context.coroutineScope.launch(Dispatchers.IO) { song.Duration.set(duration_ms, context.database) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/openUri.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/openUri.kt index e47ad4cde..ff7f7686b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/openUri.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/service/playercontroller/openUri.kt @@ -1,6 +1,6 @@ package com.toasterofbread.spmp.service.playercontroller -import dev.toastbits.composekit.utils.common.indexOfOrNull +import dev.toastbits.composekit.util.indexOfOrNull import com.toasterofbread.spmp.model.mediaitem.artist.ArtistRef import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylistRef import com.toasterofbread.spmp.model.mediaitem.song.Song diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/ColourSelectionDialog.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/ColourSelectionDialog.kt index 6dc81ee46..b89381f46 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/ColourSelectionDialog.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/ColourSelectionDialog.kt @@ -1,63 +1,62 @@ package com.toasterofbread.spmp.ui.component -import androidx.compose.ui.Modifier -import androidx.compose.runtime.* +import LocalPlayerState +import androidx.compose.animation.Crossfade +import androidx.compose.animation.animateContentSize +import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.ui.unit.dp -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.background -import LocalPlayerState -import com.toasterofbread.spmp.service.playercontroller.PlayerState -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Text -import androidx.compose.material3.MaterialTheme import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.border +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Done import androidx.compose.material3.AlertDialog -import androidx.compose.animation.Crossfade -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape import androidx.compose.material3.Button -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.utils.composable.ColourPicker -import androidx.compose.material.icons.filled.Done +import androidx.compose.material3.ButtonColors +import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon -import androidx.compose.material.icons.Icons import androidx.compose.material3.IconButtonDefaults -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.ShapedIconButton -import com.toasterofbread.spmp.ui.theme.appHover -import com.toasterofbread.spmp.ui.layout.nowplaying.getNPBackground -import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.ColourSource -import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.ThemeColourSource -import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.PlayerBackgroundColourSource -import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.CustomColourSource -import dev.toastbits.composekit.utils.modifier.bounceOnClick import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.material3.ButtonColors -import androidx.compose.material3.ButtonDefaults -import androidx.compose.animation.animateContentSize -import androidx.compose.foundation.lazy.items -import dev.toastbits.composekit.settings.ui.ThemeValues +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.dp +import com.toasterofbread.spmp.service.playercontroller.PlayerState +import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.ColourSource +import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.CustomColourSource +import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.PlayerBackgroundColourSource +import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.ThemeColourSource +import com.toasterofbread.spmp.ui.layout.nowplaying.getNPBackground +import com.toasterofbread.spmp.ui.theme.appHover +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.components.utils.composable.ColourPicker +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.utils.modifier.bounceOnClick +import dev.toastbits.composekit.theme.core.ThemeValues +import dev.toastbits.composekit.theme.core.get +import dev.toastbits.composekit.theme.core.readableName +import dev.toastbits.composekit.util.getContrasted import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res -import spmp.shared.generated.resources.colour_selector_dialog_title -import spmp.shared.generated.resources.colour_selector_dialog_select_theme -import spmp.shared.generated.resources.colour_selector_dialog_select_custom import spmp.shared.generated.resources.action_cancel import spmp.shared.generated.resources.colour_selector_dialog_player_background +import spmp.shared.generated.resources.colour_selector_dialog_select_custom +import spmp.shared.generated.resources.colour_selector_dialog_select_theme +import spmp.shared.generated.resources.colour_selector_dialog_title import spmp.shared.generated.resources.colour_selector_dialog_transparent -import spmp.shared.generated.resources.theme_colour_background -import spmp.shared.generated.resources.theme_colour_accent -import spmp.shared.generated.resources.theme_colour_vibrant_accent -import spmp.shared.generated.resources.theme_colour_card -import spmp.shared.generated.resources.theme_colour_on_background -import spmp.shared.generated.resources.theme_colour_on_accent -import spmp.shared.generated.resources.theme_colour_error @Composable fun ColourSelectionDialog( @@ -86,7 +85,7 @@ fun ColourSelectionDialog( confirmButton = { val button_colours: ButtonColors = ButtonDefaults.buttonColors( containerColor = player.theme.background, - contentColor = player.theme.on_background + contentColor = player.theme.onBackground ) Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) { @@ -121,12 +120,12 @@ private fun ThemeColourSelectionList( val player: PlayerState = LocalPlayerState.current LazyColumn(modifier, verticalArrangement = Arrangement.spacedBy(10.dp)) { - items(ThemeValues.Colour.entries) { colour -> + items(ThemeValues.Slot.entries) { slot -> ColourCard( - colour = colour.get(player.theme), - name = colour.getReadable(), + colour = player.theme[slot], + name = slot.readableName, onSelected = { - onSelected(ThemeColourSource(colour)) + onSelected(ThemeColourSource(slot)) } ) } @@ -186,7 +185,8 @@ private fun CustomColourSelector( verticalArrangement = Arrangement.spacedBy(10.dp) ) { ColourPicker( - current_colour, + Unit, + { current_colour }, modifier, bottomRowExtraContent = { ShapedIconButton( @@ -204,15 +204,3 @@ private fun CustomColourSelector( } } } - -@Composable -fun ThemeValues.Colour.getReadable(): String = - when (this) { - ThemeValues.Colour.BACKGROUND -> stringResource(Res.string.theme_colour_background) - ThemeValues.Colour.ACCENT -> stringResource(Res.string.theme_colour_accent) - ThemeValues.Colour.VIBRANT_ACCENT -> stringResource(Res.string.theme_colour_vibrant_accent) - ThemeValues.Colour.CARD -> stringResource(Res.string.theme_colour_card) - ThemeValues.Colour.ON_BACKGROUND -> stringResource(Res.string.theme_colour_on_background) - ThemeValues.Colour.ON_ACCENT -> stringResource(Res.string.theme_colour_on_accent) - ThemeValues.Colour.ERROR -> stringResource(Res.string.theme_colour_error) - } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/ErrorInfoDisplay.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/ErrorInfoDisplay.kt index 60dcf738e..6fbf5fe0f 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/ErrorInfoDisplay.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/ErrorInfoDisplay.kt @@ -56,11 +56,11 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Density import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalDensity -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.ShapedIconButton -import dev.toastbits.composekit.utils.composable.WidthShrinkText -import dev.toastbits.composekit.utils.modifier.background -import dev.toastbits.composekit.utils.modifier.disableParentScroll +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton +import dev.toastbits.composekit.util.composable.WidthShrinkText +import dev.toastbits.composekit.components.utils.modifier.background +import dev.toastbits.composekit.components.utils.modifier.disableParentScroll import com.toasterofbread.spmp.ProjectBuildConfig import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.model.JsonHttpClient @@ -76,7 +76,7 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import kotlinx.serialization.Serializable import SpMp.isDebugBuild -import dev.toastbits.composekit.settings.ui.on_accent +import dev.toastbits.composekit.theme.core.onAccent import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.action_load_retry @@ -145,20 +145,20 @@ fun ErrorInfoDisplay( Icon( if (expanded) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown, null, - tint = player.theme.on_accent + tint = player.theme.onAccent ) } WidthShrinkText( message ?: pair_error?.first ?: error!!::class.simpleName ?: error!!::class.toString(), modifier = Modifier.fillMaxWidth().weight(1f), - style = LocalTextStyle.current.copy(color = player.theme.on_accent), + style = LocalTextStyle.current.copy(color = player.theme.onAccent), max_lines = 2 ) val button_colours = ButtonDefaults.buttonColors( containerColor = player.theme.background, - contentColor = player.theme.on_background + contentColor = player.theme.onBackground ) if (onExtraButtonPressed != null) { @@ -187,7 +187,7 @@ fun ErrorInfoDisplay( shape = shape, colours = IconButtonDefaults.iconButtonColors( containerColor = player.theme.background, - contentColor = player.theme.on_background + contentColor = player.theme.onBackground ) ) { Icon(Icons.Default.Close, null) @@ -218,7 +218,7 @@ private fun LongTextDisplay(text: String, wrap_text: Boolean, modifier: Modifier modifier .verticalScroll(rememberScrollState()) .padding(bottom = 50.dp), - color = player.theme.on_background, + color = player.theme.onBackground, softWrap = wrap_text ) } @@ -240,7 +240,7 @@ private fun ExpandedContent( var wrap_text by remember { mutableStateOf(false) } val button_colours = ButtonDefaults.buttonColors( containerColor = player.theme.accent, - contentColor = player.theme.on_accent + contentColor = player.theme.onAccent ) var current_error: Throwable? by remember(error) { mutableStateOf(error) } @@ -253,7 +253,7 @@ private fun ExpandedContent( .background({ player.theme.background }) .padding(10.dp) ) { - CompositionLocalProvider(LocalContentColor provides player.theme.on_background) { + CompositionLocalProvider(LocalContentColor provides player.theme.onBackground) { Column( Modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(10.dp) @@ -261,7 +261,7 @@ private fun ExpandedContent( Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(10.dp)) { Text( stringResource(Res.string.wrap_text_switch_label), - color = player.theme.on_background + color = player.theme.onBackground ) Switch(wrap_text, { wrap_text = !wrap_text }, Modifier.padding(end = 10.dp)) @@ -284,7 +284,7 @@ private fun ExpandedContent( colors = button_colours, contentPadding = PaddingValues(0.dp), ) { - Text(stringResource(Res.string.upload_to_paste_dot_ee), textAlign = TextAlign.Center, style = LocalTextStyle.current.copy(color = player.theme.on_accent), softWrap = false) + Text(stringResource(Res.string.upload_to_paste_dot_ee), textAlign = TextAlign.Center, style = LocalTextStyle.current.copy(color = player.theme.onAccent), softWrap = false) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LargeFilterList.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LargeFilterList.kt index 39c1e3f6c..dd30a940e 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LargeFilterList.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LargeFilterList.kt @@ -11,12 +11,13 @@ import androidx.compose.ui.* import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.composable.* -import dev.toastbits.composekit.utils.modifier.horizontal -import dev.toastbits.composekit.utils.modifier.vertical +import dev.toastbits.composekit.util.* +import dev.toastbits.composekit.components.utils.composable.* +import dev.toastbits.composekit.components.utils.modifier.horizontal +import dev.toastbits.composekit.components.utils.modifier.vertical import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.composable.WidthShrinkText @Composable fun LargeFilterList( @@ -42,12 +43,12 @@ fun LargeFilterList( Modifier.padding(horizontal_padding).aspectRatio(1f), colors = if (is_selected) CardDefaults.cardColors( - containerColor = player.theme.vibrant_accent, - contentColor = player.theme.vibrant_accent.getContrasted() + containerColor = player.theme.vibrantAccent, + contentColor = player.theme.vibrantAccent.getContrasted() ) else CardDefaults.cardColors( containerColor = player.theme.accent.blendWith(player.theme.background, 0.05f), - contentColor = player.theme.on_background + contentColor = player.theme.onBackground ), shape = RoundedCornerShape(25.dp) ) { @@ -60,7 +61,7 @@ fun LargeFilterList( Modifier.aspectRatio(1f).fillMaxHeight().weight(1f).padding(10.dp), tint = if (is_selected) LocalContentColor.current - else player.theme.vibrant_accent + else player.theme.vibrantAccent ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LikeDislikeButton.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LikeDislikeButton.kt index 4e8907e5a..3b4399a4b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LikeDislikeButton.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LikeDislikeButton.kt @@ -20,12 +20,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.rotate import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.PlatformClickableIconButton -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator -import dev.toastbits.composekit.utils.modifier.bounceOnClick +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.util.platform.launchSingle +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.components.utils.composable.PlatformClickableIconButton +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.utils.modifier.bounceOnClick import com.toasterofbread.spmp.model.mediaitem.loader.SongLikedLoader import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.mediaitem.song.updateLiked diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LyricsLineDisplay.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LyricsLineDisplay.kt index 139dcbc10..23bdf1bbf 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LyricsLineDisplay.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/LyricsLineDisplay.kt @@ -14,11 +14,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalTextStyle import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -26,13 +22,10 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.sp import com.toasterofbread.spmp.model.lyrics.SongLyrics -import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.util.LyricsLineState -import com.toasterofbread.spmp.youtubeapi.lyrics.LyricsFuriganaTokeniser -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.utils.composable.AlignableCrossfade -import dev.toastbits.composekit.utils.composable.NullableValueAnimatedVisibility -import kotlinx.coroutines.delay +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.util.composable.AlignableCrossfade +import dev.toastbits.composekit.components.utils.composable.animatedvisibility.NullableValueAnimatedVisibility @Composable fun HorizontalLyricsLineDisplay( @@ -49,7 +42,7 @@ fun HorizontalLyricsLineDisplay( ) { require(lyrics.synced) - val show_furigana_option: Boolean by LocalPlayerState.current.settings.lyrics.DEFAULT_FURIGANA.observe() + val show_furigana_option: Boolean by LocalPlayerState.current.settings.Lyrics.DEFAULT_FURIGANA.observe() val current_line_state: LyricsLineState? = LyricsLineState.rememberCurrentLineState(lyrics, lyrics_linger, getTime = getTime) val lyrics_text_style: TextStyle = diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/MediaItemThumbnail.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/MediaItemThumbnail.kt index 76ea70b89..776532922 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/MediaItemThumbnail.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/MediaItemThumbnail.kt @@ -22,9 +22,9 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.composable.OnChangedEffect -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.util.platform.launchSingle +import dev.toastbits.composekit.util.composable.OnChangedEffect +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import com.toasterofbread.spmp.model.mediaitem.MediaItem import dev.toastbits.ytmkt.model.external.ThumbnailProvider import dev.toastbits.ytmkt.model.external.ThumbnailProvider.Quality diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/MediaItemTitleEditDialog.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/MediaItemTitleEditDialog.kt index 9a69b9c45..ae581ced3 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/MediaItemTitleEditDialog.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/MediaItemTitleEditDialog.kt @@ -12,7 +12,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.util.platform.launchSingle import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField import org.jetbrains.compose.resources.stringResource diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/PillMenu.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/PillMenu.kt index 638d1db3e..a5da714f7 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/PillMenu.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/PillMenu.kt @@ -46,15 +46,15 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex -import dev.toastbits.composekit.utils.common.addUnique -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.NoRipple +import dev.toastbits.composekit.util.addUnique +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.components.utils.composable.NoRipple import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingTopOffsetSection import kotlin.math.sign -import dev.toastbits.composekit.utils.composable.RowOrColumn +import dev.toastbits.composekit.components.utils.composable.RowOrColumn class PillMenu( private val action_count: Int = 0, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/PinnedItemsList.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/PinnedItemsList.kt index 42b07c1d9..8222d0c07 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/PinnedItemsList.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/PinnedItemsList.kt @@ -8,9 +8,9 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.* -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.common.thenWith +import dev.toastbits.composekit.components.utils.composable.* +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.util.thenWith import com.toasterofbread.spmp.model.mediaitem.* import com.toasterofbread.spmp.model.mediaitem.db.rememberPinnedItems import com.toasterofbread.spmp.ui.component.longpressmenu.LongPressMenuData @@ -92,10 +92,10 @@ fun PinnedItemsList( !vertical, arrangement = arrangement, alignment = -1, - show_scrollbar = false + showScrollbar = false ) { items(pinned_items) { item -> - Item(item, vertical, multiselect_context, onClick, Modifier.animateItemPlacement()) + Item(item, vertical, multiselect_context, onClick, Modifier.animateItem()) } } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/VerticalFuriganaText.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/VerticalFuriganaText.kt index 5827f40af..b6ad9b4eb 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/VerticalFuriganaText.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/VerticalFuriganaText.kt @@ -15,7 +15,7 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity -import dev.toastbits.composekit.utils.common.* +import dev.toastbits.composekit.util.* import com.toasterofbread.spmp.model.lyrics.SongLyrics private const val BRACKET_CHARS: String = "「」[](){}<>" diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/WaveBorder.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/WaveBorder.kt index e9edc3fdc..0c1bd17c7 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/WaveBorder.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/WaveBorder.kt @@ -15,10 +15,10 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.wave.WaveShape +import dev.toastbits.composekit.util.thenIf import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.settings.ui.ThemeValues +import com.toasterofbread.spmp.ui.util.WaveShape +import dev.toastbits.composekit.theme.core.ThemeValues const val WAVE_BORDER_HEIGHT_DP: Float = 20f diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.android.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.android.kt index 269d1a23b..3a5dfe9dd 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.android.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.android.kt @@ -41,16 +41,16 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.Density import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.layout.onSizeChanged -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.utils.common.contrastAgainst -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.composable.getBottom -import dev.toastbits.composekit.utils.composable.getEnd -import dev.toastbits.composekit.utils.composable.getStart +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.util.contrastAgainst +import dev.toastbits.composekit.util.platform.launchSingle +import dev.toastbits.composekit.components.utils.composable.getEnd +import dev.toastbits.composekit.components.utils.composable.getStart import com.toasterofbread.spmp.model.mediaitem.db.rememberThemeColour import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.BarColourState import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.CustomColourSource +import dev.toastbits.composekit.components.utils.composable.getBottom import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlin.math.roundToInt @@ -172,7 +172,7 @@ internal fun AndroidLongPressMenu( } Box(Modifier.fillMaxSize(), contentAlignment = Alignment.BottomCenter) { - val close_on_action: Boolean by player.settings.behaviour.LPM_CLOSE_ON_ACTION.observe() + val close_on_action: Boolean by player.settings.Behaviour.LPM_CLOSE_ON_ACTION.observe() LongPressMenuContent( data, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.desktop.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.desktop.kt index 0306aa47f..4f81570f4 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.desktop.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.desktop.kt @@ -22,7 +22,6 @@ import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.IconButton import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material3.Icon @@ -49,22 +48,22 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.utils.common.blendWith -import dev.toastbits.composekit.utils.common.contrastAgainst -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.common.snapOrAnimateTo -import dev.toastbits.composekit.utils.composable.OnChangedEffect -import dev.toastbits.composekit.utils.composable.ShapedIconButton -import dev.toastbits.composekit.utils.composable.getBottom -import dev.toastbits.composekit.utils.composable.getEnd -import dev.toastbits.composekit.utils.composable.getStart +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.util.blendWith +import dev.toastbits.composekit.util.contrastAgainst +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.platform.launchSingle +import dev.toastbits.composekit.util.composable.snapOrAnimateTo +import dev.toastbits.composekit.util.composable.OnChangedEffect +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.utils.composable.getEnd +import dev.toastbits.composekit.components.utils.composable.getStart import com.toasterofbread.spmp.model.mediaitem.db.rememberThemeColour import com.toasterofbread.spmp.ui.layout.apppage.mainpage.MINIMISED_NOW_PLAYING_HEIGHT_DP import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.CustomColourSource import com.toasterofbread.spmp.ui.layout.BarColourState import com.toasterofbread.spmp.service.playercontroller.PlayerState +import dev.toastbits.composekit.components.utils.composable.getBottom import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -181,7 +180,7 @@ internal fun DesktopLongPressMenu( if (show_dialog) { val fade_tween: FiniteAnimationSpec = tween(100) - val keep_on_background_scroll: Boolean by player.settings.behaviour.DESKTOP_LPM_KEEP_ON_BACKGROUND_SCROLL.observe() + val keep_on_background_scroll: Boolean by player.settings.Behaviour.DESKTOP_LPM_KEEP_ON_BACKGROUND_SCROLL.observe() AnimatedVisibility( show_background, @@ -274,7 +273,7 @@ internal fun DesktopLongPressMenu( verticalArrangement = Arrangement.spacedBy(10.dp) ) { val background_colour: Color = player.theme.accent.blendWith(player.theme.background, 0.1f) - val close_on_action: Boolean by player.settings.behaviour.LPM_CLOSE_ON_ACTION.observe() + val close_on_action: Boolean by player.settings.Behaviour.LPM_CLOSE_ON_ACTION.observe() LongPressMenuContent( data, @@ -287,7 +286,7 @@ internal fun DesktopLongPressMenu( bottom = MENU_CONTENT_PADDING_DP.dp + WindowInsets.systemBars.getBottom() ), { accent_colour }, - modifier = Modifier.border(2.dp, player.theme.on_background.copy(alpha = 0.1f), shape), + modifier = Modifier.border(2.dp, player.theme.onBackground.copy(alpha = 0.1f), shape), onAction = { if (show_background && close_on_action) { close() diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.kt index 9314cc026..c3504f6b7 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenu.kt @@ -7,7 +7,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.scale -import dev.toastbits.composekit.platform.Platform +import dev.toastbits.composekit.util.platform.Platform import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.songtheme.DEFAULT_THUMBNAIL_ROUNDING private const val LONG_PRESS_ICON_INDICATION_SCALE: Float = 0.4f diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuActionProvider.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuActionProvider.kt index 0b6a5b642..3098875b0 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuActionProvider.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuActionProvider.kt @@ -22,9 +22,9 @@ import androidx.compose.ui.graphics.isUnspecified import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.common.thenIf +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.util.thenIf import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.platform.playerservice.PlayerService import com.toasterofbread.spmp.service.playercontroller.LocalPlayerClickOverrides diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuActions.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuActions.kt index 83726a8f3..b44a74c42 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuActions.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuActions.kt @@ -23,8 +23,8 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.toasterofbread.spmp.model.appaction.SongAppAction -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.WidthShrinkText +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.composable.WidthShrinkText import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.playlist.Playlist import com.toasterofbread.spmp.model.mediaitem.song.Song diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuContent.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuContent.kt index ec425fe5c..c33068b8c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuContent.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuContent.kt @@ -48,16 +48,15 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.common.copy -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.AlignableCrossfade -import dev.toastbits.composekit.utils.composable.Marquee -import dev.toastbits.composekit.utils.composable.NoRipple -import dev.toastbits.composekit.utils.composable.PlatformClickableIconButton -import dev.toastbits.composekit.utils.modifier.bounceOnClick +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.util.composable.AlignableCrossfade +import dev.toastbits.composekit.components.utils.composable.Marquee +import dev.toastbits.composekit.components.utils.composable.NoRipple +import dev.toastbits.composekit.components.utils.composable.PlatformClickableIconButton +import dev.toastbits.composekit.components.utils.modifier.bounceOnClick import com.toasterofbread.spmp.model.mediaitem.MediaItem import dev.toastbits.ytmkt.model.external.ThumbnailProvider import com.toasterofbread.spmp.model.mediaitem.artist.Artist @@ -70,6 +69,8 @@ import com.toasterofbread.spmp.ui.component.WaveBorder import com.toasterofbread.spmp.ui.component.mediaitempreview.MediaItemPreviewLong import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.songtheme.DEFAULT_THUMBNAIL_ROUNDING +import dev.toastbits.composekit.util.composable.copy +import dev.toastbits.composekit.util.composable.thenIf import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.isActive import org.jetbrains.compose.resources.stringResource diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuData.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuData.kt index b74d951b8..eb3f23fdf 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuData.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/LongPressMenuData.kt @@ -14,7 +14,7 @@ import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.positionInRoot import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntSize -import dev.toastbits.composekit.utils.common.getContrasted +import dev.toastbits.composekit.util.getContrasted import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.MediaItemPreviewInteractionPressStage import com.toasterofbread.spmp.model.mediaitem.artist.Artist diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/artist/ArtistLongPressMenuInfo.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/artist/ArtistLongPressMenuInfo.kt index 01e50be92..6beba3c5d 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/artist/ArtistLongPressMenuInfo.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/artist/ArtistLongPressMenuInfo.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.utils.composable.WidthShrinkText +import dev.toastbits.composekit.util.composable.WidthShrinkText import com.toasterofbread.spmp.model.mediaitem.artist.Artist import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/playlist/PlaylistLongPressMenuInfo.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/playlist/PlaylistLongPressMenuInfo.kt index 43ef0e000..fe38c4337 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/playlist/PlaylistLongPressMenuInfo.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/playlist/PlaylistLongPressMenuInfo.kt @@ -15,7 +15,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.utils.composable.WidthShrinkText +import dev.toastbits.composekit.util.composable.WidthShrinkText import com.toasterofbread.spmp.model.mediaitem.playlist.Playlist import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/song/SongLongPressMenuActions.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/song/SongLongPressMenuActions.kt index 379099873..c1d06d598 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/song/SongLongPressMenuActions.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/song/SongLongPressMenuActions.kt @@ -41,10 +41,10 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.common.getValue -import dev.toastbits.composekit.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton import com.toasterofbread.spmp.model.mediaitem.MEDIA_ITEM_RELATED_CONTENT_ICON import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.artist.Artist @@ -60,7 +60,7 @@ import com.toasterofbread.spmp.platform.download.rememberDownloadStatus import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.longpressmenu.LongPressMenuActionProvider import com.toasterofbread.spmp.ui.layout.PlaylistSelectMenu -import dev.toastbits.composekit.settings.ui.on_accent +import dev.toastbits.composekit.theme.core.onAccent import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.launch @@ -129,7 +129,7 @@ fun LongPressMenuActionProvider.SongLongPressMenuActions( val button_colours = IconButtonDefaults.iconButtonColors( containerColor = player.theme.accent, - contentColor = player.theme.on_accent + contentColor = player.theme.onAccent ) Row( @@ -152,7 +152,7 @@ fun LongPressMenuActionProvider.SongLongPressMenuActions( }, colors = ButtonDefaults.buttonColors( containerColor = player.theme.accent, - contentColor = player.theme.on_accent + contentColor = player.theme.onAccent ) ) { Text(stringResource(Res.string.playlist_create)) @@ -218,7 +218,7 @@ private fun LongPressMenuActionProvider.LPMActions( }} ) - val lpm_increment_play_after: Boolean by player.settings.behaviour.LPM_INCREMENT_PLAY_AFTER.observe() + val lpm_increment_play_after: Boolean by player.settings.Behaviour.LPM_INCREMENT_PLAY_AFTER.observe() ActiveQueueIndexAction( { distance -> diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/song/SongLongPressMenuInfo.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/song/SongLongPressMenuInfo.kt index 8c74e4800..a0c51a070 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/song/SongLongPressMenuInfo.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/longpressmenu/song/SongLongPressMenuInfo.kt @@ -18,7 +18,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.utils.composable.WidthShrinkText +import dev.toastbits.composekit.util.composable.WidthShrinkText import com.toasterofbread.spmp.model.mediaitem.song.Song import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemCard.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemCard.kt index 8285c6ae1..5ba53f27a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemCard.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemCard.kt @@ -65,9 +65,9 @@ import com.toasterofbread.spmp.ui.component.longpressmenu.longPressMenuIcon import com.toasterofbread.spmp.ui.component.mediaitempreview.MediaItemPreviewLong import com.toasterofbread.spmp.ui.component.mediaitempreview.getThumbShape import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.settings.ui.vibrant_accent -import dev.toastbits.composekit.utils.common.getContrasted +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.getContrasted import dev.toastbits.ytmkt.model.external.ThumbnailProvider import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res @@ -210,8 +210,8 @@ fun MediaItemCard( Modifier.fillMaxWidth(), shape = shape, colors = ButtonDefaults.buttonColors( - containerColor = accent_colour ?: player.theme.vibrant_accent, - contentColor = (accent_colour ?: player.theme.vibrant_accent).getContrasted() + containerColor = accent_colour ?: player.theme.vibrantAccent, + contentColor = (accent_colour ?: player.theme.vibrantAccent).getContrasted() ) ) { Text( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemGrid.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemGrid.kt index 7e3c15074..295b43b8b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemGrid.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemGrid.kt @@ -30,10 +30,10 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.* -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.utils.modifier.background -import dev.toastbits.composekit.utils.modifier.horizontal -import dev.toastbits.composekit.utils.modifier.vertical +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.components.utils.modifier.background +import dev.toastbits.composekit.components.utils.modifier.horizontal +import dev.toastbits.composekit.components.utils.modifier.vertical import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.MediaItemHolder import com.toasterofbread.spmp.model.mediaitem.getUid @@ -172,7 +172,7 @@ fun MediaItemGrid( items(filtered_items.size, { filtered_items[it].item.getUid() }) { i -> val item: MediaItem = filtered_items[i].item - val preview_modifier: Modifier = Modifier.animateItemPlacement().size(item_size) + val preview_modifier: Modifier = Modifier.animateItem().size(item_size) if (grid_params.alt_style) { MediaItemPreviewLong( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemLayoutTitleBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemLayoutTitleBar.kt index 0eaa5d4e7..489860661 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemLayoutTitleBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitemlayout/MediaItemLayoutTitleBar.kt @@ -37,8 +37,8 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.PlatformClickableIconButton -import dev.toastbits.composekit.utils.composable.WidthShrinkText +import dev.toastbits.composekit.components.utils.composable.PlatformClickableIconButton +import dev.toastbits.composekit.util.composable.WidthShrinkText import com.toasterofbread.spmp.model.getString import com.toasterofbread.spmp.model.mediaitem.MediaItemHolder import com.toasterofbread.spmp.model.mediaitem.layout.open @@ -91,7 +91,7 @@ fun TitleBar( modifier = modifier.weight(1f) ) { subtitle_string?.also { subtitle -> - WidthShrinkText(subtitle, style = layout_params.getTitleTextStyle(MaterialTheme.typography.titleSmall.copy(color = player.theme.on_background))) + WidthShrinkText(subtitle, style = layout_params.getTitleTextStyle(MaterialTheme.typography.titleSmall.copy(color = player.theme.onBackground))) } title_string?.also { title -> @@ -101,7 +101,7 @@ fun TitleBar( style = MaterialTheme.typography.headlineMedium.let { style -> layout_params.getTitleTextStyle( style.copy( - color = player.theme.on_background, + color = player.theme.onBackground, fontSize = font_size ?: style.fontSize ) ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitempreview/MediaItemPreview.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitempreview/MediaItemPreview.kt index 6e5bd2f0c..abe7d50c4 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitempreview/MediaItemPreview.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/mediaitempreview/MediaItemPreview.kt @@ -37,8 +37,8 @@ import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.utils.common.getValue -import dev.toastbits.composekit.utils.common.thenIf +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.util.thenIf import com.toasterofbread.spmp.model.mediaitem.MediaItem import dev.toastbits.ytmkt.model.external.ThumbnailProvider import com.toasterofbread.spmp.model.mediaitem.artist.Artist diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MediaItemMultiSelectContext.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MediaItemMultiSelectContext.kt index 41ae044fb..df173991a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MediaItemMultiSelectContext.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MediaItemMultiSelectContext.kt @@ -17,8 +17,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.platform.lazyAssert +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.platform.lazyAssert import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.MediaItemHolder import com.toasterofbread.spmp.platform.AppContext @@ -66,16 +66,16 @@ open class MediaItemMultiSelectContext { } fun onActionPerformed() { - context.coroutine_scope.launch { - if (context.settings.behaviour.MULTISELECT_CANCEL_ON_ACTION.get()) { + context.coroutineScope.launch { + if (context.settings.Behaviour.MULTISELECT_CANCEL_ON_ACTION.get()) { setActive(false) } } } private fun onSelectedItemsChanged() { - context.coroutine_scope.launch { - if (selected_items.isEmpty() && context.settings.behaviour.MULTISELECT_CANCEL_ON_NONE_SELECTED.get()) { + context.coroutineScope.launch { + if (selected_items.isEmpty() && context.settings.Behaviour.MULTISELECT_CANCEL_ON_NONE_SELECTED.get()) { setActive(false) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectInfoDisplay.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectInfoDisplay.kt index 6bfe13c97..ed82ca0b7 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectInfoDisplay.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectInfoDisplay.kt @@ -14,7 +14,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.graphics.Color -import dev.toastbits.composekit.platform.composable.BackHandler +import dev.toastbits.composekit.components.platform.composable.BackHandler import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.ui.component.multiselect_context.MultiSelectGeneralActions import com.toasterofbread.spmp.ui.component.multiselect_context.MultiSelectOverflowActions diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectNextRowActions.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectNextRowActions.kt index 1ea5ece9f..423831492 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectNextRowActions.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectNextRowActions.kt @@ -30,7 +30,7 @@ import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.service.playercontroller.LocalPlayerClickOverrides import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.mediaitempreview.MediaItemPreviewLong -import dev.toastbits.composekit.platform.vibrateShort +import dev.toastbits.composekit.context.vibrateShort @Composable internal fun ColumnScope.MultiSelectNextRowActions(multiselect_context: MediaItemMultiSelectContext) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectOverflowActions.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectOverflowActions.kt index 8a897ba8f..2df8dc9a5 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectOverflowActions.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/multiselect/MultiSelectOverflowActions.kt @@ -44,10 +44,10 @@ import com.toasterofbread.spmp.platform.getOrNotify import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import com.toasterofbread.spmp.ui.layout.PlaylistSelectMenu -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.settings.ui.on_accent -import dev.toastbits.composekit.utils.composable.PlatformClickableButton -import dev.toastbits.composekit.utils.composable.ShapedIconButton +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.theme.core.onAccent +import dev.toastbits.composekit.components.utils.composable.PlatformClickableButton +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.launch @@ -145,8 +145,8 @@ private fun AddToPlaylistDialog(multiselect_context: MediaItemMultiSelectContext val button_colours = IconButtonDefaults.iconButtonColors( containerColor = player.theme.accent, disabledContainerColor = player.theme.accent, - contentColor = player.theme.on_accent, - disabledContentColor = player.theme.on_accent.copy(alpha = 0.5f) + contentColor = player.theme.onAccent, + disabledContentColor = player.theme.onAccent.copy(alpha = 0.5f) ) fun onPlaylistsSelected() { @@ -188,7 +188,7 @@ private fun AddToPlaylistDialog(multiselect_context: MediaItemMultiSelectContext }, colors = ButtonDefaults.buttonColors( containerColor = player.theme.accent, - contentColor = player.theme.on_accent + contentColor = player.theme.onAccent ) ) { Text(stringResource(Res.string.playlist_create)) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/radio/RadioStatusDisplay.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/radio/RadioStatusDisplay.kt index b94a8559b..891813ffe 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/radio/RadioStatusDisplay.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/radio/RadioStatusDisplay.kt @@ -12,11 +12,11 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.AlignableCrossfade -import dev.toastbits.composekit.utils.composable.ShapedIconButton -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator -import dev.toastbits.composekit.utils.modifier.bounceOnClick +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.composable.AlignableCrossfade +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.utils.modifier.bounceOnClick import com.toasterofbread.spmp.model.radio.RadioInstance import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.ErrorInfoDisplay diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/shortcut/ShortcutPreview.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/shortcut/ShortcutPreview.kt index 1de86f5de..ce53f1b36 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/shortcut/ShortcutPreview.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/component/shortcut/ShortcutPreview.kt @@ -12,12 +12,12 @@ import androidx.compose.runtime.* import androidx.compose.ui.* import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.NullableValueAnimatedVisibility +import dev.toastbits.composekit.components.utils.composable.animatedvisibility.NullableValueAnimatedVisibility import com.toasterofbread.spmp.model.appaction.AppAction import com.toasterofbread.spmp.model.appaction.shortcut.* import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.shortcut.trigger.* -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.theme.core.vibrantAccent import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.shortcut_editor_trigger_label @@ -36,13 +36,13 @@ fun ShortcutPreview( Column( modifier - .background(player.theme.vibrant_accent.copy(alpha = 0.25f), shape) + .background(player.theme.vibrantAccent.copy(alpha = 0.25f), shape) .padding(horizontal = 20.dp) ) { FlowRow { val item_modifier: Modifier = Modifier.align(Alignment.CenterVertically) - CompositionLocalProvider(LocalContentColor provides player.theme.on_background) { + CompositionLocalProvider(LocalContentColor provides player.theme.onBackground) { val action_type: AppAction.Type = shortcut.action.getType() Icon(action_type.getIcon(), null, item_modifier) Spacer(Modifier.width(10.dp)) @@ -94,6 +94,7 @@ fun ShortcutPreview( Spacer(Modifier.fillMaxWidth().weight(1f)) ShortcutTriggerSelector( + stringResource(Res.string.shortcut_editor_trigger), shortcut.trigger, onModification = { onModification(shortcut.copy(trigger = it)) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/DiscordLogin.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/DiscordLogin.kt index c1d0517a3..8569862b6 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/DiscordLogin.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/DiscordLogin.kt @@ -42,10 +42,10 @@ import com.toasterofbread.spmp.platform.getDiscordAccountInfo import com.toasterofbread.spmp.platform.getOrNotify import com.toasterofbread.spmp.platform.isWebViewLoginSupported import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.LinkifyText -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.components.utils.composable.LinkifyText +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import org.jetbrains.compose.resources.stringResource diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/DiscordManualLogin.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/DiscordManualLogin.kt index d79742f13..82f52f04a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/DiscordManualLogin.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/DiscordManualLogin.kt @@ -3,7 +3,7 @@ package com.toasterofbread.spmp.ui.layout import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.util.platform.launchSingle import com.toasterofbread.spmp.platform.getDiscordAccountInfo import androidx.compose.foundation.layout.PaddingValues import kotlinx.serialization.json.Json diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/GenericFeedViewMorePage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/GenericFeedViewMorePage.kt index 71b14d2bd..85f3feab4 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/GenericFeedViewMorePage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/GenericFeedViewMorePage.kt @@ -28,11 +28,9 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.compose.ui.zIndex -import dev.toastbits.composekit.utils.common.copy -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator -import dev.toastbits.composekit.utils.composable.spanItem -import dev.toastbits.composekit.utils.modifier.horizontal +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.utils.composable.spanItem +import dev.toastbits.composekit.components.utils.modifier.horizontal import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.layout.getDefaultMediaItemPreviewSize import com.toasterofbread.spmp.model.mediaitem.layout.getMediaItemPreviewSquareAdditionalHeight diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/ManualLoginPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/ManualLoginPage.kt index 0d8d679ab..cb6dda50a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/ManualLoginPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/ManualLoginPage.kt @@ -36,9 +36,9 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.utils.composable.Marquee -import dev.toastbits.composekit.utils.composable.WidthShrinkText -import dev.toastbits.composekit.utils.modifier.horizontal +import dev.toastbits.composekit.components.utils.composable.Marquee +import dev.toastbits.composekit.util.composable.WidthShrinkText +import dev.toastbits.composekit.components.utils.modifier.horizontal import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingTopOffsetSection diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/PlaylistSelectMenu.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/PlaylistSelectMenu.kt index bdc0cd2c6..e72ff02d6 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/PlaylistSelectMenu.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/PlaylistSelectMenu.kt @@ -22,16 +22,16 @@ import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.composable.SwipeRefresh -import dev.toastbits.composekit.utils.common.addUnique -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.components.platform.composable.SwipeRefresh +import dev.toastbits.composekit.util.addUnique +import dev.toastbits.composekit.util.platform.launchSingle import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary import com.toasterofbread.spmp.model.mediaitem.library.rememberLocalPlaylists import com.toasterofbread.spmp.model.mediaitem.playlist.Playlist import com.toasterofbread.spmp.model.mediaitem.playlist.rememberOwnedPlaylists import com.toasterofbread.spmp.service.playercontroller.LocalPlayerClickOverrides import com.toasterofbread.spmp.ui.component.mediaitempreview.MediaItemPreviewLong -import dev.toastbits.composekit.settings.ui.on_accent +import dev.toastbits.composekit.theme.core.onAccent @Composable fun PlaylistSelectMenu( @@ -120,7 +120,7 @@ private fun PlaylistItem(selected: SnapshotStateList, playlist: Playli colors = CheckboxDefaults.colors( uncheckedColor = LocalContentColor.current, checkedColor = player.theme.accent, - checkmarkColor = player.theme.on_accent + checkmarkColor = player.theme.onAccent ) ) MediaItemPreviewLong(playlist) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/ProjectInfoDialog.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/ProjectInfoDialog.kt index 3e86d9592..8ca8c511d 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/ProjectInfoDialog.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/ProjectInfoDialog.kt @@ -122,7 +122,7 @@ fun ProjectInfoDialog(modifier: Modifier = Modifier, close: () -> Unit) { FilledTonalButton( { val settings_page: SettingsAppPage = player.app_page_state.Settings - player.settings.deps.getPage()!!.openPage(player.context) + settings_page.openGroup(player.settings.Deps) if (player.app_page != settings_page) { player.openAppPage(settings_page) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/SongRelatedPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/SongRelatedPage.kt index b5a111a51..ff19f723b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/SongRelatedPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/SongRelatedPage.kt @@ -29,10 +29,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator -import dev.toastbits.composekit.utils.modifier.horizontal -import dev.toastbits.composekit.utils.modifier.vertical +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.utils.modifier.horizontal +import dev.toastbits.composekit.components.utils.modifier.vertical import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.MediaItemData import com.toasterofbread.spmp.model.mediaitem.song.Song diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/AppPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/AppPage.kt index 84e1c0d84..a8fa91769 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/AppPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/AppPage.kt @@ -21,9 +21,6 @@ import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import com.toasterofbread.spmp.ui.layout.artistpage.ArtistAppPage import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot -import dev.toastbits.composekit.navigation.Screen -import dev.toastbits.composekit.navigation.compositionlocal.LocalNavigator -import dev.toastbits.composekit.navigation.navigator.Navigator import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.app_page_control_panel @@ -75,7 +72,7 @@ abstract class AppPage { open fun onOpened(from_item: MediaItemHolder? = null) {} open fun onReopened() {} - open fun onClosed(next_page: AppPage?) {} + open fun onClosed(next_page: AppPage?, going_back: Boolean) {} open fun onBackNavigation(): Boolean = false open fun canReload(): Boolean = false diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/AppPageState.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/AppPageState.kt index 0c7c45700..ef5aa8e12 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/AppPageState.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/AppPageState.kt @@ -1,17 +1,14 @@ package com.toasterofbread.spmp.ui.layout.apppage -import LocalPlayerState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.ui.layout.apppage.library.LibraryAppPage import com.toasterofbread.spmp.service.playercontroller.PlayerState +import com.toasterofbread.spmp.ui.layout.apppage.library.LibraryAppPage +import com.toasterofbread.spmp.ui.layout.apppage.searchpage.SearchAppPage import com.toasterofbread.spmp.ui.layout.apppage.settingspage.SettingsAppPage import com.toasterofbread.spmp.ui.layout.apppage.songfeedpage.SongFeedAppPage -import com.toasterofbread.spmp.ui.layout.apppage.searchpage.SearchAppPage -import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingTopOffsetSection class AppPageState(val player: PlayerState) { val SongFeed = SongFeedAppPage(this) @@ -32,7 +29,7 @@ class AppPageState(val player: PlayerState) { val old_page = current_page current_page = new_page - old_page.onClosed(new_page) + old_page.onClosed(new_page, going_back) if (!going_back) { new_page.onOpened( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/ControlPanelAppPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/ControlPanelAppPage.kt index 6ee5f1cbf..82b1cd9dd 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/ControlPanelAppPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/ControlPanelAppPage.kt @@ -12,9 +12,9 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.utils.common.copy -import dev.toastbits.composekit.utils.modifier.horizontal +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.util.composable.copy +import dev.toastbits.composekit.components.utils.modifier.horizontal import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import com.toasterofbread.spmp.ui.layout.apppage.controlpanelpage.ControlPanelDownloadsPage import com.toasterofbread.spmp.ui.layout.apppage.controlpanelpage.ControlPanelServerPage diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/controlpanelpage/ControlPanelDownloadsPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/controlpanelpage/ControlPanelDownloadsPage.kt index cc6b6644b..237be8bad 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/controlpanelpage/ControlPanelDownloadsPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/controlpanelpage/ControlPanelDownloadsPage.kt @@ -11,8 +11,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.composable.ScrollBarLazyColumn -import dev.toastbits.composekit.utils.common.copy +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyColumn +import dev.toastbits.composekit.util.composable.copy import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.platform.download.DownloadStatus import com.toasterofbread.spmp.platform.download.rememberSongDownloads diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/controlpanelpage/ControlPanelServerPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/controlpanelpage/ControlPanelServerPage.kt index 0e640b195..f1c710961 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/controlpanelpage/ControlPanelServerPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/controlpanelpage/ControlPanelServerPage.kt @@ -57,11 +57,11 @@ import com.toasterofbread.spmp.platform.playerservice.getSpMsMachineId import com.toasterofbread.spmp.resources.stringResourceTODO import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext -import dev.toastbits.composekit.platform.composable.ScrollBarLazyColumn -import dev.toastbits.composekit.settings.ui.vibrant_accent -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyColumn +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.platform.launchSingle +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import dev.toastbits.spms.socketapi.shared.SpMsClientInfo import dev.toastbits.spms.socketapi.shared.SpMsClientType import kotlinx.coroutines.CoroutineScope @@ -275,8 +275,8 @@ private fun ClientInfoDisplay(client: SpMsClientInfo, modifier: Modifier = Modif Card( modifier, colors = CardDefaults.cardColors( - containerColor = player.theme.vibrant_accent, - contentColor = player.theme.vibrant_accent.getContrasted() + containerColor = player.theme.vibrantAccent, + contentColor = player.theme.vibrantAccent.getContrasted() ) ) { Row(Modifier.padding(10.dp), verticalAlignment = Alignment.CenterVertically) { @@ -332,8 +332,8 @@ private fun ClientInfoDisplay(client: SpMsClientInfo, modifier: Modifier = Modif } }, colors = ButtonDefaults.buttonColors( - containerColor = player.theme.vibrant_accent, - contentColor = player.theme.vibrant_accent.getContrasted() + containerColor = player.theme.vibrantAccent, + contentColor = player.theme.vibrantAccent.getContrasted() ) ) { Text(stringResource(Res.string.control_panel_server_client_more_info)) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryAlbumsPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryAlbumsPage.kt index 3614b18d3..5dfba78ba 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryAlbumsPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryAlbumsPage.kt @@ -23,9 +23,9 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.utils.composable.LoadActionIconButton -import dev.toastbits.composekit.utils.composable.spanItem -import dev.toastbits.composekit.utils.composable.RowOrColumnScope +import dev.toastbits.composekit.components.utils.composable.LoadActionIconButton +import dev.toastbits.composekit.components.utils.composable.spanItem +import dev.toastbits.composekit.components.utils.composable.RowOrColumnScope import com.toasterofbread.spmp.model.mediaitem.enums.PlaylistType import com.toasterofbread.spmp.model.mediaitem.enums.getReadable import com.toasterofbread.spmp.model.mediaitem.layout.getDefaultMediaItemPreviewSize @@ -131,7 +131,7 @@ internal class LibraryAlbumsPage(context: AppContext): LibrarySubPage(context) { ) loaded = true }, - load_on_launch = true + loadOnLaunch = true ) { Icon(Icons.Default.Refresh, null) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryAppPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryAppPage.kt index 88278b137..1d579a356 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryAppPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryAppPage.kt @@ -21,11 +21,11 @@ import androidx.compose.ui.platform.* import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.* import androidx.compose.ui.unit.Dp -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.composable.* -import dev.toastbits.composekit.utils.modifier.scrollWithoutClip +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.util.* +import dev.toastbits.composekit.components.utils.composable.* +import dev.toastbits.composekit.components.utils.modifier.scrollWithoutClip import com.toasterofbread.spmp.model.mediaitem.* import com.toasterofbread.spmp.platform.* import com.toasterofbread.spmp.platform.FormFactor @@ -35,6 +35,7 @@ import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectCont import com.toasterofbread.spmp.ui.layout.apppage.* import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot import com.toasterofbread.spmp.ui.layout.apppage.library.pageselector.* +import dev.toastbits.composekit.util.composable.copy import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res @@ -109,7 +110,7 @@ class LibraryAppPage(override val state: AppPageState): AppPage() { setCurrentTab(tabs.first { !it.isHidden() }) } - override fun onClosed(next_page: AppPage?) { + override fun onClosed(next_page: AppPage?, going_back: Boolean) { external_load_error = null } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryArtistsPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryArtistsPage.kt index b06a9fd3a..30c1d9555 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryArtistsPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryArtistsPage.kt @@ -21,10 +21,9 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.platform.composable.ScrollBarLazyColumn -import dev.toastbits.composekit.utils.composable.EmptyListAndDataCrossfade -import dev.toastbits.composekit.utils.composable.LoadActionIconButton -import dev.toastbits.composekit.utils.composable.RowOrColumnScope +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyColumn +import dev.toastbits.composekit.components.utils.composable.LoadActionIconButton +import dev.toastbits.composekit.components.utils.composable.RowOrColumnScope import com.toasterofbread.spmp.model.mediaitem.MediaItemHolder import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.artist.ArtistRef @@ -42,6 +41,7 @@ import com.toasterofbread.spmp.ui.layout.apppage.AppPageState import com.toasterofbread.spmp.ui.layout.apppage.AppPageWithItem import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.artistpage.LocalArtistPage +import dev.toastbits.composekit.components.utils.composable.crossfade.EmptyListAndDataCrossfade import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res @@ -254,7 +254,7 @@ class LibraryArtistsPage(context: AppContext): LibrarySubPage(context) { ) loaded = true }, - load_on_launch = true + loadOnLaunch = true ) { Icon(Icons.Default.Refresh, null) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryPlaylistsPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryPlaylistsPage.kt index e0d55acbc..90b416dc1 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryPlaylistsPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibraryPlaylistsPage.kt @@ -20,10 +20,10 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.animation.expandHorizontally import androidx.compose.animation.shrinkHorizontally -import dev.toastbits.composekit.platform.composable.ScrollBarLazyVerticalGrid -import dev.toastbits.composekit.utils.composable.LoadActionIconButton -import dev.toastbits.composekit.utils.composable.spanItem -import dev.toastbits.composekit.utils.composable.RowOrColumnScope +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyVerticalGrid +import dev.toastbits.composekit.components.utils.composable.LoadActionIconButton +import dev.toastbits.composekit.components.utils.composable.spanItem +import dev.toastbits.composekit.components.utils.composable.RowOrColumnScope import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType import com.toasterofbread.spmp.model.mediaitem.layout.getDefaultMediaItemPreviewSize import com.toasterofbread.spmp.model.mediaitem.layout.getMediaItemPreviewSquareAdditionalHeight @@ -64,7 +64,7 @@ internal class LibraryPlaylistsPage(context: AppContext): LibrarySubPage(context val player: PlayerState = LocalPlayerState.current val api: YtmApi = player.context.ytapi - val show_likes_playlist: Boolean by player.settings.behaviour.SHOW_LIKES_PLAYLIST.observe() + val show_likes_playlist: Boolean by player.settings.Behaviour.SHOW_LIKES_PLAYLIST.observe() val local_playlists: List = MediaItemLibrary.rememberLocalPlaylists(player.context) ?: emptyList() val account_playlists: List = rememberOwnedPlaylists(api.user_auth_state?.own_channel_id, player.context) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibrarySongsPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibrarySongsPage.kt index 2e61f3c16..f474dc81a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibrarySongsPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/LibrarySongsPage.kt @@ -1,10 +1,7 @@ package com.toasterofbread.spmp.ui.layout.apppage.library import LocalPlayerState -import SpMp import SpMp.isDebugBuild -import dev.toastbits.ytmkt.model.ApiAuthenticationState -import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.Crossfade import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -22,20 +19,20 @@ import androidx.compose.material.icons.filled.Sync import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.model.mediaitem.MediaItem -import dev.toastbits.composekit.platform.composable.ScrollBarLazyColumn -import dev.toastbits.composekit.utils.common.getValue -import dev.toastbits.composekit.utils.composable.EmptyListCrossfade -import dev.toastbits.composekit.utils.composable.LoadActionIconButton -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator -import dev.toastbits.composekit.utils.composable.RowOrColumnScope import com.toasterofbread.spmp.model.mediaitem.db.rememberLocalLikedSongs import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary @@ -45,21 +42,27 @@ import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylistData import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylistRef import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.mediaitem.song.SongData -import com.toasterofbread.spmp.model.mediaitem.toMediaItemData import com.toasterofbread.spmp.model.radio.RadioState import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.download.DownloadStatus -import com.toasterofbread.spmp.platform.getUiLanguage import com.toasterofbread.spmp.platform.download.rememberSongDownloads +import com.toasterofbread.spmp.platform.getUiLanguage import com.toasterofbread.spmp.platform.observeUiLanguage import com.toasterofbread.spmp.service.playercontroller.LocalPlayerClickOverrides +import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.ErrorInfoDisplay import com.toasterofbread.spmp.ui.component.mediaitempreview.MediaItemPreviewLong import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext -import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.platform.assert -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyColumn +import dev.toastbits.composekit.components.utils.composable.LoadActionIconButton +import dev.toastbits.composekit.components.utils.composable.RowOrColumnScope +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.utils.composable.crossfade.EmptyListCrossfade +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.util.model.Locale +import dev.toastbits.composekit.util.platform.launchSingle import dev.toastbits.ytmkt.endpoint.LoadPlaylistEndpoint +import dev.toastbits.ytmkt.model.ApiAuthenticationState import dev.toastbits.ytmkt.model.implementedOrNull import dev.toastbits.ytmkt.uistrings.durationToString import kotlinx.coroutines.CoroutineScope @@ -71,14 +74,14 @@ import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.`library_$x_songs` +import spmp.shared.generated.resources.library_no_items_match_filter +import spmp.shared.generated.resources.library_no_liked_songs +import spmp.shared.generated.resources.library_no_local_songs import spmp.shared.generated.resources.library_songs_downloaded +import spmp.shared.generated.resources.library_songs_downloaded_title import spmp.shared.generated.resources.library_songs_liked import spmp.shared.generated.resources.library_songs_liked_title -import spmp.shared.generated.resources.library_songs_downloaded_title -import spmp.shared.generated.resources.library_no_items_match_filter -import spmp.shared.generated.resources.library_no_liked_songs import spmp.shared.generated.resources.local_songs_playlist_name -import spmp.shared.generated.resources.library_no_local_songs class LibrarySongsPage(context: AppContext): LibrarySubPage(context) { override fun getIcon(): ImageVector = @@ -206,10 +209,10 @@ class LibrarySongsPage(context: AppContext): LibrarySubPage(context) { show_play_count = true, show_download_indicator = false, getExtraInfo = { - val ui_language: String by player.context.observeUiLanguage() + val ui_language: Locale by player.context.observeUiLanguage() val duration_string: String? = remember(song.id, ui_language) { song.Duration.get(player.database)?.let { duration -> - durationToString(duration, ui_language, true) + durationToString(duration, ui_language.toTag(), true) } } @@ -269,7 +272,7 @@ private fun InfoRow(songs: List, modifier: Modifier = Modifier, show_sync_ return@LaunchedEffect } - total_duration_string = durationToString(duration, hl = player.context.getUiLanguage()) + total_duration_string = durationToString(duration, hl = player.context.getUiLanguage().toTag()) } Row( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/pageselector/LibraryIconButtonPageSelector.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/pageselector/LibraryIconButtonPageSelector.kt index c7f4a2e74..521fa0156 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/pageselector/LibraryIconButtonPageSelector.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/library/pageselector/LibraryIconButtonPageSelector.kt @@ -5,6 +5,8 @@ import androidx.compose.animation.* import androidx.compose.animation.core.tween import androidx.compose.foundation.* import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.input.TextFieldLineLimits +import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.FilterAlt import androidx.compose.material3.* @@ -22,11 +24,12 @@ import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.apppage.library.LibraryAppPage import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot -import dev.toastbits.composekit.settings.ui.on_accent -import dev.toastbits.composekit.settings.ui.vibrant_accent -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.composable.* -import dev.toastbits.composekit.utils.modifier.* +import dev.toastbits.composekit.theme.core.onAccent +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.* +import dev.toastbits.composekit.components.utils.composable.* +import dev.toastbits.composekit.components.utils.modifier.* +import kotlinx.coroutines.flow.collectLatest import kotlin.math.roundToInt @Composable @@ -113,15 +116,15 @@ fun LibraryAppPage.LibraryIconButtonPageSelector( vertical = slot.is_vertical, selected_button = tabs.indexOf(current_tab).takeIf { it != -1 }, buttons = tabs, - indicator_colour = player.theme.vibrant_accent, + indicator_colour = player.theme.vibrantAccent, scrolling = false, showButton = { tab -> !tab.isHidden() } ) { _, tab -> val colour: Color = - if (tab == current_tab) player.theme.on_accent - else player.theme.on_background + if (tab == current_tab) player.theme.onAccent + else player.theme.onBackground CompositionLocalProvider(LocalContentColor provides colour) { IconButton({ @@ -158,7 +161,7 @@ fun LibraryAppPage.LibraryIconButtonPageSelector( vertical = slot.is_vertical, selected_button = showing_alt_content.toInt(), buttons = if (show_source_buttons) listOf(false, true) else emptyList(), - indicator_colour = player.theme.vibrant_accent, + indicator_colour = player.theme.vibrantAccent, scrolling = false, alignment = 0, showButton = { @@ -209,8 +212,8 @@ fun LibraryAppPage.LibraryIconButtonPageSelector( } ) { _, show -> val colour: Color = - if (show == showing_alt_content) player.theme.on_accent - else player.theme.on_background + if (show == showing_alt_content) player.theme.onAccent + else player.theme.onBackground CompositionLocalProvider(LocalContentColor provides colour) { IconButton({ showing_alt_content = show }) { @@ -246,11 +249,20 @@ private fun LibraryAppPage.FilterBar(modifier: Modifier = Modifier) { SortButton() } - ResizableOutlinedTextField( - search_filter ?: "", - { search_filter = it }, + val state: TextFieldState = remember { TextFieldState(search_filter ?: "") } + + LaunchedEffect(state) { + snapshotFlow { state.text } + .collectLatest { + search_filter = it.toString() + } + } + + OutlinedTextField( + state, Modifier.fillMaxWidth().weight(1f).focusRequester(focus_requester), - singleLine = true + lineLimits = TextFieldLineLimits.SingleLine, + contentPadding = OutlinedTextFieldDefaults.contentPadding().horizontal ) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/mainpage/MainPageDisplay.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/mainpage/MainPageDisplay.kt index abf779976..f82835d6c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/mainpage/MainPageDisplay.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/mainpage/MainPageDisplay.kt @@ -3,29 +3,51 @@ package com.toasterofbread.spmp.ui.layout.apppage.mainpage import LocalPlayerState import androidx.compose.animation.Crossfade import androidx.compose.animation.core.animateDpAsState -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.material3.LocalContentColor -import androidx.compose.runtime.* -import androidx.compose.ui.* -import androidx.compose.ui.graphics.Color +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.* -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.* -import dev.toastbits.composekit.utils.composable.getTop -import dev.toastbits.composekit.utils.modifier.background -import com.toasterofbread.spmp.platform.* +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex +import com.toasterofbread.spmp.platform.FormFactor +import com.toasterofbread.spmp.platform.getDefaultHorizontalPadding +import com.toasterofbread.spmp.platform.getDefaultVerticalPadding import com.toasterofbread.spmp.service.playercontroller.PlayerState -import com.toasterofbread.spmp.ui.component.WAVE_BORDER_HEIGHT_DP import com.toasterofbread.spmp.ui.layout.BarColourState -import com.toasterofbread.spmp.ui.layout.contentbar.* -import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.* +import com.toasterofbread.spmp.ui.layout.contentbar.DisplayBar +import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.ColourSource +import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LandscapeLayoutSlot +import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot +import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.PortraitLayoutSlot +import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.rememberColourSource import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingTopOffsetSection -import dev.toastbits.composekit.navigation.navigator.ExtendableNavigator -import dev.toastbits.composekit.navigation.navigator.Navigator +import dev.toastbits.composekit.components.utils.composable.getEnd +import dev.toastbits.composekit.components.utils.composable.getStart +import dev.toastbits.composekit.components.utils.composable.getTop +import dev.toastbits.composekit.components.utils.modifier.background +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.thenIf @Composable fun MainPageDisplay(bottom_padding: Dp = 0.dp) { @@ -83,7 +105,7 @@ fun MainPageDisplay(bottom_padding: Dp = 0.dp) { } Column(Modifier.zIndex(1f)) { - CompositionLocalProvider(LocalContentColor provides (highest_colour?.get(player)?.getContrasted() ?: player.theme.on_background)) { + CompositionLocalProvider(LocalContentColor provides (highest_colour?.get(player)?.getContrasted() ?: player.theme.onBackground)) { player.main_multiselect_context.InfoDisplay( Modifier .fillMaxWidth() diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/mainpage/RootView.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/mainpage/RootView.kt index 7fee33d5c..ffac6cdfd 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/mainpage/RootView.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/mainpage/RootView.kt @@ -1,10 +1,8 @@ @file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") package com.toasterofbread.spmp.ui.layout.apppage.mainpage -import LocalPlayerState import androidx.compose.foundation.Canvas import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.* import androidx.compose.ui.Modifier @@ -16,8 +14,8 @@ import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.DpSize -import dev.toastbits.composekit.utils.common.addUnique -import dev.toastbits.composekit.utils.common.thenIf +import dev.toastbits.composekit.util.addUnique +import dev.toastbits.composekit.util.thenIf import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.maintab.getMinimisedPlayerHeight import com.toasterofbread.spmp.ui.layout.nowplaying.maintab.getMinimisedPlayerVPadding @@ -48,15 +46,14 @@ fun RootView(player: PlayerState) { ) var window_transparency_enabled: Boolean by remember { mutableStateOf(false) } - val background_opacity: Float by player.settings.theme.WINDOW_BACKGROUND_OPACITY.observe() LaunchedEffect(Unit) { - window_transparency_enabled = player.settings.theme.ENABLE_WINDOW_TRANSPARENCY.get() + window_transparency_enabled = player.settings.Theme.ENABLE_WINDOW_TRANSPARENCY.get() } Canvas(Modifier.fillMaxSize()) { drawRect( - player.theme.background.thenIf(window_transparency_enabled) { copy(alpha = background_opacity) }, + player.theme.background, blendMode = BlendMode.SrcIn ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/HorizontalSearchPageSecondaryBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/HorizontalSearchPageSecondaryBar.kt index 757944cb1..d3a6565cf 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/HorizontalSearchPageSecondaryBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/HorizontalSearchPageSecondaryBar.kt @@ -14,9 +14,9 @@ import androidx.compose.ui.draw.* import androidx.compose.ui.graphics.* import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.* -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.* -import dev.toastbits.composekit.utils.modifier.bounceOnClick +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.composable.* +import dev.toastbits.composekit.components.utils.modifier.bounceOnClick import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchAppPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchAppPage.kt index 47a8d248d..81e41913e 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchAppPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchAppPage.kt @@ -1,6 +1,5 @@ package com.toasterofbread.spmp.ui.layout.apppage.searchpage -import LocalNowPlayingExpansion import LocalPlayerState import SpMp.isDebugBuild import androidx.compose.animation.* @@ -20,14 +19,11 @@ import androidx.compose.ui.focus.* import androidx.compose.ui.graphics.* import androidx.compose.ui.graphics.Shape import androidx.compose.ui.platform.* -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.* -import dev.toastbits.composekit.platform.composable.* -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.composable.* -import dev.toastbits.composekit.utils.modifier.bounceOnClick +import dev.toastbits.composekit.components.platform.composable.* +import dev.toastbits.composekit.util.* +import dev.toastbits.composekit.util.platform.launchSingle +import dev.toastbits.composekit.components.utils.composable.* import com.toasterofbread.spmp.model.mediaitem.MediaItemHolder import com.toasterofbread.spmp.model.mediaitem.enums.* import com.toasterofbread.spmp.model.mediaitem.layout.* @@ -37,16 +33,12 @@ import com.toasterofbread.spmp.platform.* import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.ErrorInfoDisplay import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext -import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField import com.toasterofbread.spmp.ui.layout.apppage.AppPage import com.toasterofbread.spmp.ui.layout.apppage.AppPageState import com.toasterofbread.spmp.ui.layout.contentbar.* import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot -import com.toasterofbread.spmp.ui.layout.nowplaying.PlayerExpansionState -import com.toasterofbread.spmp.ui.theme.appHover import com.toasterofbread.spmp.ui.component.NotImplementedMessage -import dev.toastbits.composekit.platform.ReentrantLock -import dev.toastbits.composekit.platform.synchronized +import dev.toastbits.composekit.util.composable.copy import dev.toastbits.ytmkt.endpoint.* import dev.toastbits.ytmkt.endpoint.SearchFilter import dev.toastbits.ytmkt.endpoint.SearchResults @@ -56,6 +48,7 @@ import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.search_results_loading import spmp.shared.generated.resources.`search_suggested_correction_$x` +import java.util.concurrent.locks.ReentrantLock internal val SEARCH_FIELD_FONT_SIZE: TextUnit = 18.sp internal const val SEARCH_SUGGESTIONS_LOAD_DELAY_MS: Long = 200 @@ -138,7 +131,7 @@ class SearchAppPage(override val state: AppPageState, val context: AppContext): lazy: Boolean, modifier: Modifier ): Boolean { - val show_suggestions: Boolean by context.settings.behaviour.SEARCH_SHOW_SUGGESTIONS.observe() + val show_suggestions: Boolean by context.settings.Behaviour.SEARCH_SHOW_SUGGESTIONS.observe() var suggestions: List by remember { mutableStateOf(emptyList()) } LaunchedEffect(current_query, show_suggestions) { @@ -260,7 +253,7 @@ class SearchAppPage(override val state: AppPageState, val context: AppContext): Modifier.fillMaxSize().padding(padding), contentAlignment = Alignment.Center ) { - SubtleLoadingIndicator(getColour = { context.theme.on_background }, message = stringResource(Res.string.search_results_loading)) + SubtleLoadingIndicator(getColour = { context.theme.onBackground }, message = stringResource(Res.string.search_results_loading)) } } } @@ -297,7 +290,7 @@ class SearchAppPage(override val state: AppPageState, val context: AppContext): multiselect_context?.setActive(false) coroutine_scope.launchSingle { - val non_music: Boolean = context.settings.search.SEARCH_FOR_NON_MUSIC.get() + val non_music: Boolean = context.settings.Search.SEARCH_FOR_NON_MUSIC.get() search_endpoint.search(query, filter?.params, non_music = non_music).fold( { results -> for (result in results.categories) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchBar.kt index 29d905a54..419b603da 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchBar.kt @@ -16,15 +16,15 @@ import androidx.compose.ui.focus.* import androidx.compose.ui.graphics.Shape import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.ShapedIconButton -import dev.toastbits.composekit.utils.modifier.bounceOnClick +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.utils.modifier.bounceOnClick import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField import com.toasterofbread.spmp.ui.layout.nowplaying.PlayerExpansionState import com.toasterofbread.spmp.ui.theme.appHover -import dev.toastbits.composekit.settings.ui.on_accent -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.theme.core.onAccent +import dev.toastbits.composekit.theme.core.vibrantAccent import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.search_entry_field_hint @@ -69,7 +69,7 @@ internal fun SearchAppPage.SearchBar( singleLine = true, textStyle = LocalTextStyle.current.copy( fontSize = SEARCH_FIELD_FONT_SIZE, - color = context.theme.vibrant_accent.getContrasted() + color = context.theme.vibrantAccent.getContrasted() ), modifier = Modifier .height(SEARCH_BAR_HEIGHT_DP.dp) @@ -82,7 +82,7 @@ internal fun SearchAppPage.SearchBar( Row( Modifier .background( - context.theme.vibrant_accent, + context.theme.vibrantAccent, shape ) .padding(horizontal = 10.dp) @@ -95,7 +95,7 @@ internal fun SearchAppPage.SearchBar( // Query hint if (current_query.isEmpty()) { - Text(stringResource(Res.string.search_entry_field_hint), fontSize = SEARCH_FIELD_FONT_SIZE, color = context.theme.on_accent) + Text(stringResource(Res.string.search_entry_field_hint), fontSize = SEARCH_FIELD_FONT_SIZE, color = context.theme.onAccent) } // Text input @@ -104,7 +104,7 @@ internal fun SearchAppPage.SearchBar( // Clear field button IconButton({ current_query = "" }, Modifier.bounceOnClick().appHover(true)) { - Icon(Icons.Filled.Clear, null, Modifier, context.theme.on_accent) + Icon(Icons.Filled.Clear, null, Modifier, context.theme.onAccent) } } }, @@ -121,8 +121,8 @@ internal fun SearchAppPage.SearchBar( ShapedIconButton( { performSearch() }, IconButtonDefaults.iconButtonColors( - containerColor = context.theme.vibrant_accent, - contentColor = context.theme.vibrant_accent.getContrasted() + containerColor = context.theme.vibrantAccent, + contentColor = context.theme.vibrantAccent.getContrasted() ), Modifier .aspectRatio(1f) @@ -136,8 +136,8 @@ internal fun SearchAppPage.SearchBar( ShapedIconButton( { show_settings = true }, IconButtonDefaults.iconButtonColors( - containerColor = context.theme.vibrant_accent, - contentColor = context.theme.vibrant_accent.getContrasted() + containerColor = context.theme.vibrantAccent, + contentColor = context.theme.vibrantAccent.getContrasted() ), Modifier .aspectRatio(1f) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchFiltersRow.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchFiltersRow.kt index 473dae14e..1e2f18063 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchFiltersRow.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchFiltersRow.kt @@ -8,9 +8,9 @@ import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.ScrollableRowOrColumn +import dev.toastbits.composekit.components.utils.composable.ScrollableRowOrColumn import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.settings.ui.on_accent +import dev.toastbits.composekit.theme.core.onAccent import dev.toastbits.ytmkt.endpoint.* @Composable @@ -50,13 +50,13 @@ internal fun SearchAppPage.SearchFiltersRow( colors = with(player.theme) { FilterChipDefaults.elevatedFilterChipColors( containerColor = background, - labelColor = on_background, + labelColor = onBackground, selectedContainerColor = accent, - selectedLabelColor = on_accent + selectedLabelColor = onAccent ) }, border = FilterChipDefaults.filterChipBorder( - borderColor = player.theme.on_background, + borderColor = player.theme.onBackground, enabled = true, selected = selected ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchSettingsDialog.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchSettingsDialog.kt index 8da428268..578cd7b73 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchSettingsDialog.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchSettingsDialog.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.action_close @@ -26,7 +26,7 @@ import spmp.shared.generated.resources.s_cat_search @Composable fun SearchSettingsDialog(modifier: Modifier = Modifier, close: () -> Unit) { val player: PlayerState = LocalPlayerState.current - val settings_items: List = remember { player.settings.search.getConfigurationItems() } + val settings_items: List = remember { player.settings.Search.getConfigurationItems() } AlertDialog( onDismissRequest = close, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchSuggestionsColumn.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchSuggestionsColumn.kt index 782a436b9..bed43797f 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchSuggestionsColumn.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/SearchSuggestionsColumn.kt @@ -11,7 +11,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.History -import dev.toastbits.composekit.utils.composable.AlignableCrossfade +import dev.toastbits.composekit.util.composable.AlignableCrossfade import dev.toastbits.ytmkt.endpoint.SearchSuggestion @Composable @@ -70,7 +70,7 @@ private fun SearchAppPage.SearchSuggestion( Modifier.weight(1f, false), softWrap = false, overflow = TextOverflow.Ellipsis, - color = context.theme.on_background + color = context.theme.onBackground ) if (suggestion.is_from_history) { @@ -78,7 +78,7 @@ private fun SearchAppPage.SearchSuggestion( Icons.Default.History, null, Modifier.alpha(0.75f), - tint = context.theme.on_background + tint = context.theme.onBackground ) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/VerticalSearchPagePrimaryBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/VerticalSearchPagePrimaryBar.kt index e9d01277d..367b2b9de 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/VerticalSearchPagePrimaryBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/VerticalSearchPagePrimaryBar.kt @@ -11,8 +11,8 @@ import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot import com.toasterofbread.spmp.ui.layout.apppage.searchpage.getReadable import com.toasterofbread.spmp.ui.layout.apppage.searchpage.getIcon import dev.toastbits.ytmkt.endpoint.* -import dev.toastbits.composekit.utils.modifier.horizontal -import dev.toastbits.composekit.utils.modifier.vertical +import dev.toastbits.composekit.components.utils.modifier.horizontal +import dev.toastbits.composekit.components.utils.modifier.vertical @Composable internal fun SearchAppPage.VerticalSearchPrimaryBar( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/VerticalSearchPageSecondaryBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/VerticalSearchPageSecondaryBar.kt index bc285a0d1..0f3fefcd0 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/VerticalSearchPageSecondaryBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/searchpage/VerticalSearchPageSecondaryBar.kt @@ -14,8 +14,8 @@ import androidx.compose.ui.layout.* import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.unit.* import androidx.compose.ui.unit.Dp -import dev.toastbits.composekit.utils.common.copy -import dev.toastbits.composekit.utils.modifier.* +import dev.toastbits.composekit.util.composable.copy +import dev.toastbits.composekit.components.utils.modifier.* import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.LargeFilterList import com.toasterofbread.spmp.ui.layout.apppage.mainpage.MINIMISED_NOW_PLAYING_HEIGHT_DP diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/AppSliderItem.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/AppSliderItem.kt index e79a02e55..812604e39 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/AppSliderItem.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/AppSliderItem.kt @@ -1,12 +1,12 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage import androidx.compose.ui.Modifier -import dev.toastbits.composekit.utils.common.roundTo +import dev.toastbits.composekit.util.roundTo import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.SliderSettingsItem -import dev.toastbits.composekit.utils.common.CustomStringResource -import dev.toastbits.composekit.utils.common.toCustomResource +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.SliderSettingsItem +import dev.toastbits.composekit.util.CustomStringResource +import dev.toastbits.composekit.util.toCustomResource import org.jetbrains.compose.resources.getString import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.settings_value_not_int @@ -14,7 +14,7 @@ import spmp.shared.generated.resources.settings_value_not_float import spmp.shared.generated.resources.`settings_value_out_of_$range` fun AppSliderItem( - state: PreferencesProperty, + state: PlatformSettingsProperty, min_label: CustomStringResource? = null, max_label: CustomStringResource? = null, steps: Int = 0, @@ -26,13 +26,8 @@ fun AppSliderItem( ): SliderSettingsItem = SliderSettingsItem( state = state, - getErrMsgValueOutOfRange = { - getString(Res.string.`settings_value_out_of_$range`).replace("\$range", it.toString()) - }, - errmsg_value_not_int = Res.string.settings_value_not_int.toCustomResource(), - errmsg_value_not_float = Res.string.settings_value_not_float.toCustomResource(), - min_label = min_label, - max_label = max_label, + minLabel = min_label, + maxLabel = max_label, steps = steps, range = range, getValueText = getValueText, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/AppStringSetItem.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/AppStringSetItem.kt index f342768c6..4b3f7e744 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/AppStringSetItem.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/AppStringSetItem.kt @@ -5,15 +5,15 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.StringSetSettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.StringSetSettingsItem import org.jetbrains.compose.resources.StringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.settings_string_set_item_already_added import spmp.shared.generated.resources.settings_string_set_item_empty fun AppStringSetItem( - state: PreferencesProperty>, + state: PlatformSettingsProperty>, add_dialog_title: StringResource, single_line_content: Boolean = true, height: Dp = 300.dp, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/DiscordAuthItem.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/DiscordAuthItem.kt index 248b8bc90..e07134e37 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/DiscordAuthItem.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/DiscordAuthItem.kt @@ -1,6 +1,7 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage import LocalPlayerState +import SpMp import androidx.compose.foundation.layout.Row import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons @@ -21,12 +22,13 @@ import com.toasterofbread.spmp.platform.DiscordStatus import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.DiscordAccountPreview import com.toasterofbread.spmp.ui.layout.DiscordLoginConfirmation -import dev.toastbits.composekit.platform.PlatformPreferences -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.LargeToggleSettingsItem -import dev.toastbits.composekit.settings.ui.on_accent -import dev.toastbits.composekit.settings.ui.vibrant_accent -import dev.toastbits.composekit.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsEditor +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.LargeToggleSettingsItem +import dev.toastbits.composekit.theme.core.onAccent +import dev.toastbits.composekit.theme.core.vibrantAccent +import kotlinx.coroutines.launch import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.boolean @@ -45,46 +47,44 @@ fun getDiscordAuthItem( ignore_prerequisite: Boolean = false, StartIcon: (@Composable () -> Unit)? = null ): LargeToggleSettingsItem { - val discord_auth: PreferencesProperty = context.settings.discord_auth.DISCORD_ACCOUNT_TOKEN + val discord_auth: PlatformSettingsProperty = context.settings.DiscordAuth.DISCORD_ACCOUNT_TOKEN val login_required: Boolean = DiscordStatus.isAccountTokenRequired() - val prerequisite: PreferencesProperty? = + val prerequisite: PlatformSettingsProperty? = if (login_required) - context.settings.discord_auth.DISCORD_WARNING_ACCEPTED + context.settings.DiscordAuth.DISCORD_WARNING_ACCEPTED else null return LargeToggleSettingsItem( - object : PreferencesProperty { + object : PlatformSettingsProperty { override val key: String get() = throw IllegalStateException() @Composable override fun getName(): String = "" @Composable override fun getDescription(): String = "" - override suspend fun get(): Boolean = discord_auth.get().isNotEmpty() + override fun get(): Boolean = discord_auth.get().isNotEmpty() - override fun set(value: Boolean, editor: PlatformPreferences.Editor?) { + override suspend fun set(value: Boolean, editor: PlatformSettingsEditor?) { if (!value) { discord_auth.set("", editor) } } - override fun set(data: JsonElement, editor: PlatformPreferences.Editor?) { + override suspend fun set(data: JsonElement, editor: PlatformSettingsEditor?) { set(data.jsonPrimitive.boolean, editor) } override fun serialise(value: Any?): JsonElement = JsonPrimitive(value as Boolean?) - override fun reset() = discord_auth.reset() + override suspend fun reset(editor: PlatformSettingsEditor?) { + discord_auth.reset(editor) + } - override suspend fun getDefaultValue(): Boolean = + override fun getDefaultValue(): Boolean = discord_auth.getDefaultValue().isNotEmpty() - @Composable - override fun getDefaultValueComposable(): Boolean = - discord_auth.getDefaultValueComposable().isNotEmpty() - @Composable override fun observe(): MutableState { val auth: String by discord_auth.observe() @@ -130,7 +130,12 @@ fun getDiscordAuthItem( DiscordLoginConfirmation { manual -> dismiss() if (manual != null) { - SpMp.player_state.app_page_state.Settings.settings_interface.openPageById(PrefsPageScreen.DISCORD_LOGIN.ordinal, manual) + SpMp.player_state.app_page_state.Settings.openScreen( + DiscordLoginScreen( + context.settings.DiscordAuth.DISCORD_ACCOUNT_TOKEN, + manual + ) + ) } } }} @@ -153,8 +158,8 @@ fun getDiscordAuthItem( { show_info_dialog = !show_info_dialog }, shape = CircleShape, colours = IconButtonDefaults.iconButtonColors( - containerColor = if (enabled) player.theme.background else player.theme.vibrant_accent, - contentColor = if (enabled) player.theme.on_background else player.theme.on_accent + containerColor = if (enabled) player.theme.background else player.theme.vibrantAccent, + contentColor = if (enabled) player.theme.onBackground else player.theme.onAccent ) ) { Icon( @@ -168,10 +173,17 @@ fun getDiscordAuthItem( ) { target, setEnabled, _ -> if (target) { if (login_required) { - SpMp.player_state.app_page_state.Settings.settings_interface.openPageById(PrefsPageScreen.DISCORD_LOGIN.ordinal, null) + SpMp.player_state.app_page_state.Settings.openScreen( + DiscordLoginScreen( + context.settings.DiscordAuth.DISCORD_ACCOUNT_TOKEN, + false + ) + ) } else { - discord_auth.set("0") + context.coroutineScope.launch { + discord_auth.set("0") + } } } else { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/DiscordLoginPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/DiscordLoginPage.kt deleted file mode 100644 index 8849d62f3..000000000 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/DiscordLoginPage.kt +++ /dev/null @@ -1,85 +0,0 @@ -package com.toasterofbread.spmp.ui.layout.apppage.settingspage - -import LocalPlayerState -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import com.toasterofbread.spmp.model.settings.category.DiscordSettings -import com.toasterofbread.spmp.service.playercontroller.PlayerState -import com.toasterofbread.spmp.ui.layout.DiscordLogin -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.SettingsPage -import org.jetbrains.compose.resources.stringResource -import spmp.shared.generated.resources.Res -import spmp.shared.generated.resources.discord_manual_login_title - -internal fun getDiscordLoginPage(discord_auth: PreferencesProperty, manual: Boolean = false): SettingsPage { - return object : SettingsPage() { - override val scrolling: Boolean - @Composable - get() = false - - override val apply_padding: Boolean = false - - override val title: String? - @Composable - get() = if (manual) stringResource(Res.string.discord_manual_login_title) else null - override val icon: ImageVector? - @Composable - get() = if (manual) DiscordSettings.getDiscordIcon() else null - - @Composable - override fun hasTitleBar(): Boolean = false - - @Composable - override fun TitleBar(is_root: Boolean, modifier: Modifier, titleFooter: @Composable (() -> Unit)?) {} - - @Composable - override fun PageView( - content_padding: PaddingValues, - openPage: (Int, Any?) -> Unit, - openCustomPage: (SettingsPage) -> Unit, - goBack: () -> Unit, - ) { - val player: PlayerState = LocalPlayerState.current - var exited: Boolean by remember { mutableStateOf(false) } - - DiscordLogin(content_padding, Modifier.fillMaxSize(), manual = manual) { auth_info -> - if (exited) { - return@DiscordLogin - } - - if (auth_info == null) { - goBack() - exited = true - return@DiscordLogin - } - - auth_info.fold( - { - if (it != null) { - discord_auth.set(it) - } - goBack() - exited = true - }, - { error -> - error.message?.also { - player.context.sendToast(it) - } - } - ) - } - } - - override suspend fun resetKeys() { - discord_auth.reset() - } - } -} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/DiscordLoginScreen.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/DiscordLoginScreen.kt new file mode 100644 index 000000000..1c56e00d0 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/DiscordLoginScreen.kt @@ -0,0 +1,74 @@ +package com.toasterofbread.spmp.ui.layout.apppage.settingspage + +import LocalPlayerState +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import com.toasterofbread.spmp.service.playercontroller.PlayerState +import com.toasterofbread.spmp.ui.layout.DiscordLogin +import dev.toastbits.composekit.navigation.compositionlocal.LocalNavigator +import dev.toastbits.composekit.navigation.navigator.Navigator +import dev.toastbits.composekit.navigation.screen.Screen +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import org.jetbrains.compose.resources.stringResource +import spmp.shared.generated.resources.Res +import spmp.shared.generated.resources.discord_manual_login_title + +class DiscordLoginScreen( + private val authState: PlatformSettingsProperty, + private val manual: Boolean +): Screen { + override val title: String? + @Composable + get() = if (manual) stringResource(Res.string.discord_manual_login_title) else null + + +// override val icon: ImageVector? +// @Composable +// get() = if (manual) DiscordSettings.getDiscordIcon() else null + + @Composable + override fun Content(modifier: Modifier, contentPadding: PaddingValues) { + val player: PlayerState = LocalPlayerState.current + val navigator: Navigator = LocalNavigator.current + val coroutine_scope: CoroutineScope = rememberCoroutineScope() + var exited: Boolean by remember { mutableStateOf(false) } + + DiscordLogin(contentPadding, Modifier.fillMaxSize(), manual = manual) { auth_info -> + if (exited) { + return@DiscordLogin + } + + if (auth_info == null) { + navigator.navigateBackward(1) + exited = true + return@DiscordLogin + } + + auth_info.fold( + { + coroutine_scope.launch { + if (it != null) { + authState.set(it) + } + navigator.navigateBackward(1) + exited = true + } + }, + { error -> + error.message?.also { + player.context.sendToast(it) + } + } + ) + } + } +} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/PrefsPageSettingsInterface.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/PrefsPageSettingsInterface.kt deleted file mode 100644 index 4d1f2ff44..000000000 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/PrefsPageSettingsInterface.kt +++ /dev/null @@ -1,80 +0,0 @@ -package com.toasterofbread.spmp.ui.layout.apppage.settingspage - -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.settings.ui.SettingsInterface -import dev.toastbits.composekit.settings.ui.SettingsPageWithItems -import dev.toastbits.composekit.platform.PreferencesProperty -import com.toasterofbread.spmp.model.settings.Settings -import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.ui.component.PillMenu -import com.toasterofbread.spmp.ui.layout.apppage.AppPageState - -internal fun getPrefsPageSettingsInterface( - page_state: AppPageState, - pill_menu: PillMenu, - ytm_auth: PreferencesProperty> -): SettingsInterface { - lateinit var settings_interface: SettingsInterface - val context: AppContext = page_state.context - - val pill_menu_action_overrider: @Composable PillMenu.Action.(i: Int) -> Boolean = { i -> - if (i == 0) { - var go_back by remember { mutableStateOf(false) } - LaunchedEffect(go_back) { - if (go_back) { - settings_interface.goBack() - } - } - - ActionButton( - Icons.Filled.ArrowBack - ) { - go_back = true - } - true - } - else { - false - } - } - - val discord_auth: PreferencesProperty = context.settings.discord_auth.DISCORD_ACCOUNT_TOKEN - - settings_interface = SettingsInterface( - context, - context.getPrefs(), - { context.theme }, - PrefsPageScreen.ROOT.ordinal, - { index, param -> - when (PrefsPageScreen.entries[index]) { - PrefsPageScreen.ROOT -> SettingsPageWithItems( - { null }, - { emptyList() } - ) - PrefsPageScreen.YOUTUBE_MUSIC_LOGIN -> getYoutubeMusicLoginPage(ytm_auth, param) - PrefsPageScreen.DISCORD_LOGIN -> getDiscordLoginPage(discord_auth, manual = param == true) - PrefsPageScreen.UI_DEBUG_INFO -> getUiDebugInfoPage() - } - }, - { context.vibrateShort() }, - { page: Int? -> - if (page == PrefsPageScreen.ROOT.ordinal) { - pill_menu.removeActionOverrider(pill_menu_action_overrider) - } - else { - pill_menu.addActionOverrider(pill_menu_action_overrider) - } - } - ) - - return settings_interface -} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/SettingsAppPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/SettingsAppPage.kt index 7958f6652..18103ca50 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/SettingsAppPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/SettingsAppPage.kt @@ -2,71 +2,108 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage -import LocalPlayerState -import androidx.compose.animation.Crossfade -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.BoxWithConstraints -import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.calculateEndPadding -import androidx.compose.foundation.layout.calculateStartPadding -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Refresh -import androidx.compose.material3.LocalContentColor +import androidx.compose.foundation.text.selection.SelectionContainer +import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.platform.LocalLayoutDirection -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.compose.ui.zIndex -import dev.toastbits.composekit.settings.ui.SettingsInterface -import dev.toastbits.composekit.platform.PreferencesProperty -import com.toasterofbread.spmp.model.settings.Settings -import com.toasterofbread.spmp.ui.component.PillMenu -import com.toasterofbread.spmp.ui.component.WAVE_BORDER_HEIGHT_DP -import com.toasterofbread.spmp.ui.component.WaveBorder +import androidx.compose.ui.unit.sp +import com.toasterofbread.spmp.model.settings.SettingsGroup import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import com.toasterofbread.spmp.ui.layout.apppage.AppPage import com.toasterofbread.spmp.ui.layout.apppage.AppPageState -import com.toasterofbread.spmp.service.playercontroller.PlayerState -import androidx.compose.runtime.MutableState -import dev.toastbits.composekit.utils.common.copy +import dev.toastbits.composekit.components.utils.composable.pane.model.InitialPaneRatioSource +import dev.toastbits.composekit.navigation.navigator.BaseNavigator +import dev.toastbits.composekit.navigation.navigator.CurrentScreen +import dev.toastbits.composekit.navigation.navigator.Navigator +import dev.toastbits.composekit.navigation.screen.Screen +import dev.toastbits.composekit.settings.ui.screen.PlatformSettingsGroupScreen +import dev.toastbits.composekit.settings.ui.screen.PlatformSettingsScreen -internal const val PREFS_PAGE_EXTRA_PADDING_DP: Float = 10f +class SettingsAppPage(override val state: AppPageState): AppPage() { + fun openScreen(screen: Screen) { + settingsScreen.internalNavigator.pushScreen(screen) + } -internal enum class PrefsPageScreen { - ROOT, - YOUTUBE_MUSIC_LOGIN, - DISCORD_LOGIN, - UI_DEBUG_INFO -} + fun openGroup(group: SettingsGroup) { + openScreen(PlatformSettingsGroupScreen(group)) + } -class SettingsAppPage(override val state: AppPageState): AppPage() { - private val pill_menu: PillMenu = PillMenu(follow_player = true) - val ytm_auth: PreferencesProperty> = state.context.settings.youtube_auth.YTM_AUTH - val settings_interface: SettingsInterface = - getPrefsPageSettingsInterface( - state, - pill_menu, - ytm_auth + fun goBack() { + navigator.navigateBackward(1) + } + + private val settingsScreen: PlatformSettingsScreen = + object : PlatformSettingsScreen( + state.context.settings.preferences, + state.context.settings.groups_with_page, + initialStartPaneRatioSource = + InitialPaneRatioSource.Remembered( + "com.toasterofbread.spmp.ui.layout.apppage.settingspage.SettingsAppPage", + InitialPaneRatioSource.Ratio(0.4f) + ), + displayExtraButtonsAboveGroups = true + ) { + override var GroupsListFooterContent: (@Composable (Modifier) -> Unit)? = { modifier -> + Footer( + center = !isDisplayingBothPanes, + modifier = modifier + ) + } + } + + @Composable + private fun Footer( + center: Boolean, + modifier: Modifier = Modifier + ) { + FlowRow( + modifier + .fillMaxWidth() + .padding(top = 10.dp) + .alpha(0.5f), + horizontalArrangement = + if (center) Arrangement.Center + else Arrangement.Start + ) { + for (part in ProgramArguments.getVersionMessageComposable(split_lines = true).split("\n")) { + SelectionContainer { + Text( + part, + fontSize = 12.sp, + textAlign = + if (center) TextAlign.Center + else TextAlign.Start + ) + } + } + } + } + + private val navigator: Navigator = + BaseNavigator( + initialScreen = settingsScreen, + extraButtonsHandledExternally = true ) override fun onBackNavigation(): Boolean { - return settings_interface.goBack() + if (navigator.getNavigateBackwardCount() >= 1) { + navigator.navigateBackward(1) + return true + } + return false } - override fun onReopened() { - settings_interface.openPage(null) + override fun onClosed(next_page: AppPage?, going_back: Boolean) { + settingsScreen.reset() } @Composable @@ -76,76 +113,6 @@ class SettingsAppPage(override val state: AppPageState): AppPage() { content_padding: PaddingValues, close: () -> Unit, ) { - val player: PlayerState = LocalPlayerState.current - val show_reset_confirmation: MutableState = remember { mutableStateOf(false) } - - ResetConfirmationDialog( - show_reset_confirmation, - { - settings_interface.current_page.resetKeys() - } - ) - - val extra_action: @Composable PillMenu.Action.(action_count: Int) -> Unit = remember {{ - if (it == 1) { - ActionButton( - Icons.Filled.Refresh - ) { - show_reset_confirmation.value = true - } - } - }} - - DisposableEffect(settings_interface.current_page) { - if (settings_interface.current_page.id == PrefsPageScreen.ROOT.ordinal) { - pill_menu.addExtraAction(action = extra_action) - } - else { - pill_menu.removeExtraAction(extra_action) - } - - onDispose { - pill_menu.removeExtraAction(extra_action) - } - } - - Box(modifier) { - pill_menu.PillMenu() - - Column(Modifier.fillMaxSize()) { - val layout_direction: LayoutDirection = LocalLayoutDirection.current - - Crossfade(settings_interface.current_page.id != PrefsPageScreen.ROOT.ordinal) { open -> - if (!open) { - SettingsTopPage( - content_padding = content_padding.copy( - start = content_padding.calculateStartPadding(layout_direction) + PREFS_PAGE_EXTRA_PADDING_DP.dp, - end = content_padding.calculateEndPadding(layout_direction) + PREFS_PAGE_EXTRA_PADDING_DP.dp - ), - top_padding = content_padding.calculateTopPadding() - ) - } - else { - BoxWithConstraints( - Modifier.pointerInput(Unit) {} - ) { - CompositionLocalProvider(LocalContentColor provides player.theme.on_background) { - settings_interface.Interface( - Modifier.fillMaxSize(), - content_padding = content_padding.copy( - start = content_padding.calculateStartPadding(layout_direction) + PREFS_PAGE_EXTRA_PADDING_DP.dp, - end = content_padding.calculateEndPadding(layout_direction) + PREFS_PAGE_EXTRA_PADDING_DP.dp - ), - titleFooter = { - WaveBorder() - }, - page_top_padding = WAVE_BORDER_HEIGHT_DP.dp - ) - } - } - } - } - } - } + navigator.CurrentScreen(modifier, content_padding) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/SettingsTopPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/SettingsTopPage.kt deleted file mode 100644 index 5ba573322..000000000 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/SettingsTopPage.kt +++ /dev/null @@ -1,560 +0,0 @@ -package com.toasterofbread.spmp.ui.layout.apppage.settingspage - -import LocalPlayerState -import ProgramArguments -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.Crossfade -import androidx.compose.animation.expandHorizontally -import androidx.compose.animation.shrinkHorizontally -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.FlowRow -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.text.selection.SelectionContainer -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Done -import androidx.compose.material.icons.filled.FolderOpen -import androidx.compose.material.icons.filled.Save -import androidx.compose.material.icons.filled.SelectAll -import androidx.compose.material.icons.filled.Info -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Button -import androidx.compose.material3.Checkbox -import androidx.compose.material3.CheckboxDefaults -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.LocalTextStyle -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateListOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.layout.onSizeChanged -import androidx.compose.ui.platform.ClipboardManager -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.Density -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.platform.PlatformFile -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.utils.common.addUnique -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.common.toggleItemPresence -import dev.toastbits.composekit.utils.composable.WidthShrinkText -import dev.toastbits.composekit.utils.modifier.horizontal -import com.toasterofbread.spmp.model.settings.SettingsImportExport -import com.toasterofbread.spmp.model.settings.category.SettingsGroup -import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.service.playercontroller.PlayerState -import com.toasterofbread.spmp.ui.component.ErrorInfoDisplay -import com.toasterofbread.spmp.ui.layout.ProjectInfoDialog -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import org.jetbrains.compose.resources.painterResource -import spmp.shared.generated.resources.Res -import spmp.shared.generated.resources.* -import PlatformIO -import dev.toastbits.composekit.settings.ui.on_accent -import kotlinx.datetime.Clock -import kotlinx.datetime.LocalDateTime -import kotlinx.datetime.TimeZone -import kotlinx.datetime.format -import kotlinx.datetime.format.FormatStringsInDatetimeFormats -import kotlinx.datetime.format.byUnicodePattern -import kotlinx.datetime.toLocalDateTime -import okio.buffer -import okio.use -import org.jetbrains.compose.resources.getString -import org.jetbrains.compose.resources.stringResource -import spmp.shared.generated.resources.s_page_preferences -import spmp.shared.generated.resources.action_close -import spmp.shared.generated.resources.settings_import_error_title -import spmp.shared.generated.resources.settings_import_result_title -import spmp.shared.generated.resources.`settings_import_result_$x_from_file` -import spmp.shared.generated.resources.`settings_import_result_$x_from_default` -import spmp.shared.generated.resources.settings_import_button_import -import spmp.shared.generated.resources.action_cancel -import spmp.shared.generated.resources.settings_import_prep_title -import spmp.shared.generated.resources.settings_import_category_selection_subtitle -import spmp.shared.generated.resources.project_url -import spmp.shared.generated.resources.notif_copied_x_to_clipboard -import spmp.shared.generated.resources.project_url_name - -@Composable -internal fun SettingsAppPage.SettingsTopPage(modifier: Modifier = Modifier, content_padding: PaddingValues = PaddingValues(), top_padding: Dp = 0.dp) { - val player: PlayerState = LocalPlayerState.current - val coroutine_scope: CoroutineScope = rememberCoroutineScope() - - var importing: Boolean by remember { mutableStateOf(false) } - if (importing) { - SettingsImportDialog { importing = false } - } - - var exporting: Boolean by remember { mutableStateOf(false) } - val export_categories: MutableList = remember { mutableStateListOf() } - - BackHandler(exporting) { - exporting = false - } - - val horizontal_padding: PaddingValues = content_padding.horizontal - val category_pages: List = remember { player.settings.group_pages } - val item_spacing: Dp = 10.dp - - LazyColumn( - modifier, - contentPadding = - PaddingValues( - top = top_padding, - bottom = content_padding.calculateBottomPadding() + PREFS_PAGE_EXTRA_PADDING_DP.dp - ) - ) { - item { - Row( - Modifier.fillMaxWidth().padding(bottom = item_spacing + 10.dp).padding(horizontal_padding), - verticalAlignment = Alignment.CenterVertically - ) { - Text( - stringResource(Res.string.s_page_preferences), - style = MaterialTheme.typography.displaySmall - ) - - Spacer(Modifier.fillMaxWidth().weight(1f)) - - ImportExportButtons( - exporting, - export_categories, - category_pages, - { - export_categories.clear() - exporting = true - }, - { - exporting = false - coroutine_scope.launch { - peformExport(player.context, export_categories) - } - }, - { exporting = it }, - { importing = it } - ) - - AnimatedVisibility(!exporting) { - ProjectButton(Modifier.padding(start = 20.dp)) - } - - AnimatedVisibility(!exporting) { - InfoButton(Modifier.padding(start = 20.dp)) - } - } - } - - items(category_pages.filter { it.group.showPage(exporting) }) { page -> - val title_item: SettingsItem? = remember(page) { page.getTitleItem(player.context) } - if (title_item == null) { - return@items - } - - Row( - Modifier - .padding(bottom = item_spacing) - .padding(horizontal_padding), - verticalAlignment = Alignment.CenterVertically - ) { - AnimatedVisibility(exporting) { - StyledCheckbox( - checked = export_categories.contains(page.group), - onCheckedChange = { checked -> - export_categories.toggleItemPresence(page.group) - } - ) - } - - Box(Modifier.fillMaxWidth()) { - val density: Density = LocalDensity.current - - // Using IntrinsicHeight breaks some item animations - var item_height: Dp by remember { mutableStateOf(0.dp) } - - title_item.Item( - Modifier - .onSizeChanged { - item_height = with (density) { it.height.toDp() } - } - ) - - Box( - Modifier - .fillMaxWidth() - .height(item_height) - .thenIf(exporting) { - clickable(interactionSource = remember { MutableInteractionSource() }, indication = null) { - export_categories.toggleItemPresence(page.group) - } - } - ) - } - } - } - - item { - FlowRow( - Modifier - .fillMaxWidth() - .padding(top = 10.dp) - .padding(horizontal_padding) - .alpha(0.5f), - horizontalArrangement = Arrangement.Center - ) { - for (part in ProgramArguments.getVersionMessageComposable(split_lines = true).split("\n")) { - SelectionContainer { - Text( - part, - fontSize = 12.sp, - textAlign = TextAlign.Center - ) - } - } - } - } - } -} - -@Composable -internal fun SettingsImportDialog(modifier: Modifier = Modifier, onFinished: () -> Unit) { - val context: AppContext = LocalPlayerState.current.context - val coroutine_scope: CoroutineScope = rememberCoroutineScope() - - var import_data: SettingsImportExport.SettingsExportData? by remember { mutableStateOf(null) } - var import_error: Throwable? by remember { mutableStateOf(null) } - var import_result: SettingsImportExport.ImportResult? by remember { mutableStateOf(null) } - - LaunchedEffect(Unit) { - context.promptUserForFile(setOf("text/plain", "application/json"), persist = false) { path -> - if (path != null) { - coroutine_scope.launch { - try { - import_data = SettingsImportExport.loadSettingsFile(context.getUserDirectoryFile(path)!!) - } - catch (e: Throwable) { - import_error = e - } - } - } - else { - onFinished() - } - } - } - - import_error?.also { error -> - AlertDialog( - modifier = modifier, - onDismissRequest = onFinished, - confirmButton = { - Button(onFinished) { - Text(stringResource(Res.string.action_close)) - } - }, - title = { - Text(stringResource(Res.string.settings_import_error_title)) - }, - text = { - ErrorInfoDisplay(error, onDismiss = null) - } - ) - return - } - - import_result?.also { result -> - AlertDialog( - modifier = modifier, - onDismissRequest = onFinished, - confirmButton = { - Button(onFinished) { - Text(stringResource(Res.string.action_close)) - } - }, - title = { - WidthShrinkText(stringResource(Res.string.settings_import_result_title)) - }, - text = { - Column(verticalArrangement = Arrangement.spacedBy(20.dp)) { - CompositionLocalProvider(LocalTextStyle provides MaterialTheme.typography.bodyLarge) { - Text(stringResource(Res.string.`settings_import_result_$x_from_file`).replace("\$x", result.directly_imported_count.toString())) - Text(stringResource(Res.string.`settings_import_result_$x_from_default`).replace("\$x", result.default_imported_count.toString())) - } - } - } - ) - return - } - - import_data?.also { data -> - val included_groups: List = (data.getGroups(context) ?: emptyList()).ifEmpty { context.settings.groups_with_page } - val import_groups: MutableList = remember { - mutableStateListOf().apply { - addAll(included_groups) - } - } - - AlertDialog( - modifier = modifier, - onDismissRequest = onFinished, - confirmButton = { - Button( - { - try { - import_result = SettingsImportExport.importSettingsData(context, data, import_groups) - } - catch (e: Throwable) { - import_error = e - } - }, - enabled = import_groups.isNotEmpty() - ) { - Text(stringResource(Res.string.settings_import_button_import)) - } - }, - dismissButton = { - Row { - IconButton({ - if (import_groups.size == included_groups.size) { - import_groups.clear() - } - else { - for (category in included_groups) { - import_groups.addUnique(category) - } - } - }) { - Icon(Icons.Default.SelectAll, null) - } - - Button(onFinished) { - Text(stringResource(Res.string.action_cancel)) - } - } - }, - title = { - Text(stringResource(Res.string.settings_import_prep_title)) - }, - text = { - Column { - Text(stringResource(Res.string.settings_import_category_selection_subtitle), style = MaterialTheme.typography.titleMedium) - LazyColumn { - items(included_groups) { group -> - val title: String = group.getTitle().ifEmpty { - group.group_key.lowercase().replaceFirstChar { it.uppercaseChar() } - } - - Row( - Modifier.clickable { - import_groups.toggleItemPresence(group) - }, - verticalAlignment = Alignment.CenterVertically - ) { - StyledCheckbox( - import_groups.contains(group), - { import_groups.toggleItemPresence(group) } - ) - - Text(title, Modifier.fillMaxWidth().weight(1f), style = MaterialTheme.typography.labelLarge) - } - } - } - } - } - ) - } -} - -@Composable -private fun ProjectButton(modifier: Modifier = Modifier) { - val player: PlayerState = LocalPlayerState.current - val clipboard: ClipboardManager = LocalClipboardManager.current - - val project_url: String = stringResource(Res.string.project_url) - val project_url_name: String = stringResource(Res.string.project_url_name) - val notif_copied_x_to_clipboard: String = stringResource(Res.string.notif_copied_x_to_clipboard) - - fun copyProjectUrl() { - clipboard.setText(AnnotatedString(project_url)) - player.context.sendToast(notif_copied_x_to_clipboard.replace("\$x", project_url_name)) - } - - Icon( - painterResource(Res.drawable.ic_github), - null, - modifier.platformClickable( - onClick = { - if (player.context.canOpenUrl()) { - player.context.openUrl(project_url) - } - else { - copyProjectUrl() - } - }, - onAltClick = { - if (player.context.canOpenUrl()) { - copyProjectUrl() - player.context.vibrateShort() - } - } - ) - ) -} - -@Composable -private fun InfoButton(modifier: Modifier = Modifier) { - var show_info_dialog: Boolean by remember { mutableStateOf(false) } - - if (show_info_dialog) { - ProjectInfoDialog { show_info_dialog = false } - } - - Icon( - Icons.Default.Info, - null, - modifier.platformClickable( - onClick = { show_info_dialog = !show_info_dialog } - ) - ) -} - -@Composable -private fun StyledCheckbox(checked: Boolean, onCheckedChange: (Boolean) -> Unit) { - val player: PlayerState = LocalPlayerState.current - Checkbox( - checked, - onCheckedChange, - colors = CheckboxDefaults.colors( - checkedColor = player.theme.accent, - uncheckedColor = player.theme.accent, - checkmarkColor = player.theme.on_accent - ) - ) -} - -@OptIn(DelicateCoroutinesApi::class, FormatStringsInDatetimeFormats::class) -private suspend fun peformExport(context: AppContext, groups: List) { - val datetime: String = - Clock.System.now() - .toLocalDateTime(TimeZone.currentSystemDefault()) - .format( - LocalDateTime.Format { - byUnicodePattern("yyyy-MM-dd_HH:mm:ss") - } - ) - val filename: String = getString(Res.string.`settings_export_filename_$date`).replace("\$date", datetime) - - context.promptUserForFileCreation("application/json", filename, persist = false) { path -> - if (path == null) { - return@promptUserForFileCreation - } - - GlobalScope.launch(Dispatchers.PlatformIO) { - val settings_data: SettingsImportExport.SettingsExportData = - SettingsImportExport.exportSettingsData( - prefs = context.getPrefs(), - groups = groups - ) - - val file: PlatformFile = context.getUserDirectoryFile(path)!! - file.outputStream().buffer().use { writer -> - writer.writeUtf8(Json.encodeToString(settings_data)) - writer.flush() - } - } - } -} - -@Composable -private fun ImportExportButtons( - exporting: Boolean, - export_groups: MutableList, - group_pages: List, - beginExport: () -> Unit, - completeExport: () -> Unit, - setExporting: (Boolean) -> Unit, - setImporting: (Boolean) -> Unit -) { - val initial_icon_modifier: Modifier = Modifier.alpha(0.5f) - - AnimatedVisibility( - exporting, - enter = expandHorizontally(), - exit = shrinkHorizontally() - ) { - IconButton({ - if (export_groups.size == group_pages.size) { - export_groups.clear() - } - else { - for (page in group_pages) { - export_groups.addUnique(page.group) - } - } - }) { - Icon(Icons.Default.SelectAll, null) - } - } - - Crossfade(exporting) { ex -> - if (!ex) { - IconButton({ beginExport() }) { - Icon(Icons.Default.Save, null, initial_icon_modifier) - } - } - else { - IconButton({ setExporting(false) }) { - Icon(Icons.Default.Close, null) - } - } - } - - Crossfade(exporting) { ex -> - if (!ex) { - IconButton({ setImporting(true) }) { - Icon(Icons.Default.FolderOpen, null, initial_icon_modifier) - } - } - else { - IconButton({ completeExport() }) { - Icon(Icons.Default.Done, null) - } - } - } -} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/UiDebugInfoPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/UiDebugInfoPage.kt deleted file mode 100644 index 5c4767a79..000000000 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/UiDebugInfoPage.kt +++ /dev/null @@ -1,116 +0,0 @@ -package com.toasterofbread.spmp.ui.layout.apppage.settingspage - -import LocalPlayerState -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.ime -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.Density -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.settings.ui.SettingsPage -import dev.toastbits.composekit.settings.ui.SettingsPageWithItems -import dev.toastbits.composekit.settings.ui.component.item.ComposableSettingsItem -import dev.toastbits.composekit.utils.common.roundTo -import dev.toastbits.composekit.utils.composable.RecomposeOnInterval -import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField -import org.jetbrains.compose.resources.stringResource -import spmp.shared.generated.resources.Res -import spmp.shared.generated.resources.s_subpage_ui_debug_info - -@Composable -private fun SizeIndicator( - label: String, - show_indicator: Boolean = true, - show_percent_of_screen: Boolean = false, - getHeight: @Composable Density.(AppContext) -> Any?, -) { - val player = LocalPlayerState.current - val density = LocalDensity.current - - RecomposeOnInterval(500) { - it - - Column(Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(5.dp)) { - val value: Any? = getHeight(density, player.context) - - Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(5.dp)) { - Text(label) - - Spacer(Modifier.fillMaxWidth().weight(1f)) - - if (value != null) { - Text(value.toString()) - } - - if (show_percent_of_screen && value is Dp) { - val height_percent: Float = value / player.screen_size.height - Text("(${height_percent.roundTo(2).toString().padEnd(4, '0')}%)") - } - - Text("\u2022", Modifier.alpha(if (it) 1f else 0f)) - } - - if (show_indicator && value is Dp) { - Box( - Modifier - .fillMaxWidth() - .height(value) - .background(Color.Red) - ) - } - } - } -} - -fun getUiDebugInfoPage(): SettingsPage = - SettingsPageWithItems( - { stringResource(Res.string.s_subpage_ui_debug_info) }, - { - listOf( - ComposableSettingsItem { - SizeIndicator("Displaying above navigation bar") { context -> - context.isDisplayingAboveNavigationBar() - } - }, - - // Window height - ComposableSettingsItem { - SizeIndicator("Screen height", show_indicator = false) { context -> - LocalPlayerState.current.screen_size.height - } - }, - - // Keyboard height - ComposableSettingsItem { - Column(Modifier.fillMaxWidth()) { - SizeIndicator("Keyboard height", show_percent_of_screen = true) { context -> - WindowInsets.ime.getBottom(this).toDp() - } - OutlinedTextField( - "", - {}, - Modifier.fillMaxWidth().appTextField(), - placeholder = { - Text("Test field") - } - ) - } - } - ) - } - ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/YoutubeMusicLoginPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/YoutubeMusicLoginPage.kt deleted file mode 100644 index 25b008f18..000000000 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/YoutubeMusicLoginPage.kt +++ /dev/null @@ -1,106 +0,0 @@ -package com.toasterofbread.spmp.ui.layout.apppage.settingspage - -import LocalPlayerState -import SpMp.isDebugBuild -import dev.toastbits.ytmkt.model.ApiAuthenticationState -import androidx.compose.animation.Crossfade -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.settings.ui.SettingsPage -import dev.toastbits.composekit.platform.PreferencesProperty -import com.toasterofbread.spmp.model.settings.packSetData -import com.toasterofbread.spmp.ui.component.ErrorInfoDisplay -import com.toasterofbread.spmp.ui.layout.youtubemusiclogin.LoginPage - -internal fun getYoutubeMusicLoginPage( - ytm_auth: PreferencesProperty>, - confirm_param: Any? -): SettingsPage { - return object : SettingsPage() { - val login_page: LoginPage - @Composable - get() { - return LocalPlayerState.current.context.ytapi.LoginPage - } - - override val scrolling: Boolean - @Composable - get() = false - - override val apply_padding: Boolean = false - - override val title: String? - @Composable - get() = login_page.getTitle(confirm_param) - override val icon: ImageVector? - @Composable - get() = login_page.getIcon(confirm_param) - - @Composable - override fun hasTitleBar(): Boolean = false - - @Composable - override fun TitleBar(is_root: Boolean, modifier: Modifier, titleFooter: @Composable (() -> Unit)?) {} - - @Composable - override fun PageView( - content_padding: PaddingValues, - openPage: (Int, Any?) -> Unit, - openCustomPage: (SettingsPage) -> Unit, - goBack: () -> Unit - ) { - var login_error: Throwable? by remember { mutableStateOf(null) } - - BackHandler { - settings_interface.goBack() - } - - Crossfade(login_error) { error -> - if (error == null) { - login_page.LoginPage(Modifier.fillMaxSize(), confirm_param, content_padding) { result -> - result?.fold( - { auth_info -> - ytm_auth.set( - ApiAuthenticationState.packSetData(auth_info.own_channel_id, auth_info.headers) - ) - goBack() - }, - { error -> - login_error = error - } - ) - } - } - else { - Box(Modifier.fillMaxSize().padding(content_padding), contentAlignment = Alignment.Center) { - ErrorInfoDisplay( - error, - isDebugBuild(), - Modifier.fillMaxWidth(), - expanded_content_modifier = Modifier.fillMaxHeight(), - start_expanded = true, - onDismiss = goBack - ) - } - } - } - } - - override suspend fun resetKeys() { - ytm_auth.reset() - } - } -} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/YoutubeMusicLoginScreen.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/YoutubeMusicLoginScreen.kt new file mode 100644 index 000000000..42e81d295 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/YoutubeMusicLoginScreen.kt @@ -0,0 +1,85 @@ +package com.toasterofbread.spmp.ui.layout.apppage.settingspage + +import LocalPlayerState +import SpMp.isDebugBuild +import dev.toastbits.ytmkt.model.ApiAuthenticationState +import androidx.compose.animation.Crossfade +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import com.toasterofbread.spmp.model.settings.packSetData +import com.toasterofbread.spmp.ui.component.ErrorInfoDisplay +import com.toasterofbread.spmp.ui.layout.youtubemusiclogin.LoginPage +import dev.toastbits.composekit.navigation.compositionlocal.LocalNavigator +import dev.toastbits.composekit.navigation.navigator.Navigator +import dev.toastbits.composekit.navigation.screen.Screen +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +class YoutubeMusicLoginScreen( + private val ytmAuth: PlatformSettingsProperty>, + private val confirmParam: Any? +): Screen { + private val loginPage: LoginPage + @Composable + get() = LocalPlayerState.current.context.ytapi.LoginPage + + override val title: String? + @Composable + get() = loginPage.getTitle(confirmParam) + +// override val icon: ImageVector? +// @Composable +// get() = loginPage.getIcon(confirm_param) + + @Composable + override fun Content(modifier: Modifier, contentPadding: PaddingValues) { + val navigator: Navigator = LocalNavigator.current + val coroutine_scope: CoroutineScope = rememberCoroutineScope() + var login_error: Throwable? by remember { mutableStateOf(null) } + + Crossfade(login_error) { error -> + if (error == null) { + loginPage.LoginPage(Modifier.fillMaxSize(), confirmParam, contentPadding) { result -> + result?.fold( + { auth_info -> + coroutine_scope.launch { + ytmAuth.set( + ApiAuthenticationState.packSetData(auth_info.own_channel_id, auth_info.headers) + ) + navigator.navigateBackward(1) + } + }, + { error -> + login_error = error + } + ) + } + } + else { + Box(Modifier.fillMaxSize().padding(contentPadding), contentAlignment = Alignment.Center) { + ErrorInfoDisplay( + error, + isDebugBuild(), + Modifier.fillMaxWidth(), + expanded_content_modifier = Modifier.fillMaxHeight(), + start_expanded = true, + onDismiss = { navigator.navigateBackward(1) } + ) + } + } + } + } +} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/YtmAuthItem.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/YtmAuthItem.kt index b784a7d6d..6b6740d00 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/YtmAuthItem.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/YtmAuthItem.kt @@ -2,6 +2,8 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage import dev.toastbits.ytmkt.model.ApiAuthenticationState import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close @@ -12,86 +14,80 @@ import androidx.compose.material3.IconButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState -import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import dev.toastbits.composekit.platform.PlatformPreferences -import dev.toastbits.composekit.settings.ui.component.item.ComposableSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.LargeToggleSettingsItem -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.utils.composable.ShapedIconButton +import androidx.compose.ui.unit.dp +import dev.toastbits.composekit.settings.PlatformSettings +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ComposableSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.LargeToggleSettingsItem +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.artist.ArtistRef -import com.toasterofbread.spmp.model.settings.Settings import com.toasterofbread.spmp.model.settings.unpackSetData import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.component.mediaitempreview.MediaItemPreviewLong import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getYoutubeAccountCategory -import dev.toastbits.ytmkt.impl.youtubei.YoutubeiAuthenticationState import com.toasterofbread.spmp.platform.isWebViewLoginSupported import com.toasterofbread.spmp.ui.component.NotImplementedMessage import com.toasterofbread.spmp.ui.layout.youtubemusiclogin.LoginPage -import dev.toastbits.composekit.settings.ui.on_accent -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsEditor +import dev.toastbits.composekit.theme.core.onAccent +import dev.toastbits.composekit.theme.core.vibrantAccent import io.ktor.http.Headers import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.boolean import kotlinx.serialization.json.JsonPrimitive -import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.auth_not_signed_in import spmp.shared.generated.resources.auth_sign_in import spmp.shared.generated.resources.auth_sign_out -fun getYtmAuthItem(context: AppContext, ytm_auth: PreferencesProperty>): SettingsItem { +fun getYtmAuthItem(context: AppContext, ytmAuth: PlatformSettingsProperty>): SettingsItem { var own_channel: Artist? by mutableStateOf(null) val login_page: LoginPage = context.ytapi.LoginPage if (!login_page.isImplemented()) { - return ComposableSettingsItem { + return ComposableSettingsItem(resetComposeUiState = {}) { login_page.NotImplementedMessage(Modifier.fillMaxSize()) } } return LargeToggleSettingsItem( - object : PreferencesProperty { - override val key: String = ytm_auth.key + object : PlatformSettingsProperty { + override val key: String = ytmAuth.key @Composable - override fun getName(): String = ytm_auth.getName() + override fun getName(): String = ytmAuth.getName() @Composable - override fun getDescription(): String? = ytm_auth.getDescription() + override fun getDescription(): String? = ytmAuth.getDescription() - override suspend fun get(): Boolean = - ytm_auth.get().isNotEmpty() + override fun get(): Boolean = + ytmAuth.get().isNotEmpty() - override fun set(value: Boolean, editor: PlatformPreferences.Editor?) { + override suspend fun set(value: Boolean, editor: PlatformSettingsEditor?) { if (!value) { - ytm_auth.set(emptySet(), editor) + ytmAuth.set(emptySet(), editor) } } - override fun set(data: JsonElement, editor: PlatformPreferences.Editor?) { + override suspend fun set(data: JsonElement, editor: PlatformSettingsEditor?) { set(data.jsonPrimitive.boolean, editor) } override fun serialise(value: Any?): JsonElement = JsonPrimitive(value as Boolean?) - override suspend fun getDefaultValue(): Boolean = - ytm_auth.getDefaultValue().isNotEmpty() - - @Composable - override fun getDefaultValueComposable(): Boolean = - ytm_auth.getDefaultValueComposable().isNotEmpty() + override fun getDefaultValue(): Boolean = + ytmAuth.getDefaultValue().isNotEmpty() @Composable override fun observe(): MutableState { - val auth: Set by ytm_auth.observe() + val auth: Set by ytmAuth.observe() val state: MutableState = remember { mutableStateOf(auth.isNotEmpty()) } LaunchedEffect(auth.isNotEmpty()) { @@ -101,8 +97,9 @@ fun getYtmAuthItem(context: AppContext, ytm_auth: PreferencesProperty // val auth_value: Set = ytm_auth.get() @@ -114,14 +111,14 @@ fun getYtmAuthItem(context: AppContext, ytm_auth: PreferencesProperty by ytm_auth.observe() + val auth: Set by ytmAuth.observe() val data: Pair? = ApiAuthenticationState.unpackSetData(auth, context) if (data?.first != null) { own_channel = ArtistRef(data.first!!) } own_channel?.also { channel -> - MediaItemPreviewLong(channel, modifier, show_type = false) + MediaItemPreviewLong(channel, modifier.requiredHeight(45.dp), show_type = false) } }, extra_items = getYoutubeAccountCategory(context), @@ -135,7 +132,12 @@ fun getYtmAuthItem(context: AppContext, ytm_auth: PreferencesProperty dismiss() if (param != null) { - SpMp.player_state.app_page_state.Settings.settings_interface.openPageById(PrefsPageScreen.YOUTUBE_MUSIC_LOGIN.ordinal, param) + SpMp.player_state.app_page_state.Settings.openScreen( + YoutubeMusicLoginScreen( + context.settings.YoutubeAuth.YTM_AUTH, + param + ) + ) } } }, @@ -160,8 +162,8 @@ fun getYtmAuthItem(context: AppContext, ytm_auth: PreferencesProperty if (target) { - SpMp.player_state.app_page_state.Settings.settings_interface.openPageById(PrefsPageScreen.YOUTUBE_MUSIC_LOGIN.ordinal, null) + SpMp.player_state.app_page_state.Settings.openScreen( + YoutubeMusicLoginScreen( + context.settings.YoutubeAuth.YTM_AUTH, + null + ) + ) } else { setEnabled(false) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/BehaviourCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/BehaviourCategory.kt index 69b671336..1ac161162 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/BehaviourCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/BehaviourCategory.kt @@ -2,71 +2,71 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage.category import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.AppSliderItem -import dev.toastbits.composekit.settings.ui.component.item.GroupSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.GroupSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_group_long_press_menu internal fun getBehaviourCategoryItems(context: AppContext): List { return listOf( ToggleSettingsItem( - context.settings.behaviour.OPEN_NP_ON_SONG_PLAYED + context.settings.Behaviour.OPEN_NP_ON_SONG_PLAYED ), ToggleSettingsItem( - context.settings.behaviour.START_RADIO_ON_SONG_PRESS + context.settings.Behaviour.START_RADIO_ON_SONG_PRESS ), ToggleSettingsItem( - context.settings.behaviour.MULTISELECT_CANCEL_ON_ACTION + context.settings.Behaviour.MULTISELECT_CANCEL_ON_ACTION ), ToggleSettingsItem( - context.settings.behaviour.MULTISELECT_CANCEL_ON_NONE_SELECTED + context.settings.Behaviour.MULTISELECT_CANCEL_ON_NONE_SELECTED ), ToggleSettingsItem( - context.settings.behaviour.TREAT_SINGLES_AS_SONG + context.settings.Behaviour.TREAT_SINGLES_AS_SONG ), ToggleSettingsItem( - context.settings.behaviour.TREAT_ANY_SINGLE_ITEM_PLAYLIST_AS_SINGLE + context.settings.Behaviour.TREAT_ANY_SINGLE_ITEM_PLAYLIST_AS_SINGLE ), ToggleSettingsItem( - context.settings.behaviour.SHOW_LIKES_PLAYLIST + context.settings.Behaviour.SHOW_LIKES_PLAYLIST ), ToggleSettingsItem( - context.settings.behaviour.SEARCH_SHOW_SUGGESTIONS + context.settings.Behaviour.SEARCH_SHOW_SUGGESTIONS ), ToggleSettingsItem( - context.settings.behaviour.STOP_PLAYER_ON_APP_CLOSE + context.settings.Behaviour.STOP_PLAYER_ON_APP_CLOSE ), ToggleSettingsItem( - context.settings.behaviour.INCLUDE_PLAYBACK_POSITION_IN_SHARE_URL + context.settings.Behaviour.INCLUDE_PLAYBACK_POSITION_IN_SHARE_URL ), AppSliderItem( - context.settings.behaviour.REPEAT_SONG_ON_PREVIOUS_THRESHOLD_S, + context.settings.Behaviour.REPEAT_SONG_ON_PREVIOUS_THRESHOLD_S, range = -1f .. 10f ), GroupSettingsItem(Res.string.s_group_long_press_menu), ToggleSettingsItem( - context.settings.behaviour.LPM_CLOSE_ON_ACTION + context.settings.Behaviour.LPM_CLOSE_ON_ACTION ), ToggleSettingsItem( - context.settings.behaviour.LPM_INCREMENT_PLAY_AFTER + context.settings.Behaviour.LPM_INCREMENT_PLAY_AFTER ), ToggleSettingsItem( - context.settings.behaviour.DESKTOP_LPM_KEEP_ON_BACKGROUND_SCROLL + context.settings.Behaviour.DESKTOP_LPM_KEEP_ON_BACKGROUND_SCROLL ) ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/DiscordCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/DiscordCategory.kt index 0a108ff8a..78c967137 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/DiscordCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/DiscordCategory.kt @@ -24,13 +24,13 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.settings.ui.component.item.ComposableSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.GroupSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.InfoTextSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.TextFieldSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem -import dev.toastbits.composekit.utils.composable.LinkifyText +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ComposableSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.GroupSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.InfoTextSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.TextFieldSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem +import dev.toastbits.composekit.components.utils.composable.LinkifyText import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.DiscordStatus import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField @@ -40,11 +40,11 @@ import LocalProgramArguments import ProgramArguments import LocalPlayerState import com.toasterofbread.spmp.model.settings.category.DiscordSettings -import dev.toastbits.composekit.platform.composable.theme.LocalApplicationTheme -import dev.toastbits.composekit.settings.ui.ThemeValues -import dev.toastbits.composekit.settings.ui.component.item.DropdownSettingsItem -import dev.toastbits.composekit.settings.ui.on_accent -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.theme.core.ui.LocalComposeKitTheme +import dev.toastbits.composekit.theme.core.ThemeValues +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.DropdownSettingsItem +import dev.toastbits.composekit.theme.core.onAccent +import dev.toastbits.composekit.theme.core.vibrantAccent import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.action_warning_accept @@ -68,13 +68,14 @@ internal fun getDiscordCategoryItems(context: AppContext): List { return listOf( ComposableSettingsItem( shouldShowItem = { - val accepted: Boolean by context.settings.discord_auth.DISCORD_WARNING_ACCEPTED.observe() + val accepted: Boolean by context.settings.DiscordAuth.DISCORD_WARNING_ACCEPTED.observe() val warning_text: String? = DiscordStatus.getWarningText() return@ComposableSettingsItem warning_text != null && !accepted - } + }, + resetComposeUiState = {} ) { modifier -> - val theme: ThemeValues = LocalApplicationTheme.current - var accepted: Boolean by context.settings.discord_auth.DISCORD_WARNING_ACCEPTED.observe() + val theme: ThemeValues = LocalComposeKitTheme.current + var accepted: Boolean by context.settings.DiscordAuth.DISCORD_WARNING_ACCEPTED.observe() val warning_text: String? = DiscordStatus.getWarningText() AnimatedVisibility(warning_text != null && !accepted, enter = expandVertically(), exit = shrinkVertically()) { @@ -82,21 +83,21 @@ internal fun getDiscordCategoryItems(context: AppContext): List { modifier.fillMaxWidth(), colors = CardDefaults.cardColors( containerColor = theme.background, - contentColor = theme.on_background + contentColor = theme.onBackground ), border = BorderStroke(2.dp, Color.Red), ) { Column(Modifier.fillMaxSize().padding(15.dp), verticalArrangement = Arrangement.spacedBy(5.dp)) { Icon(Icons.Default.Warning, null, tint = Color.Red) - LinkifyText(warning_text ?: "", theme.accent, style = MaterialTheme.typography.bodyMedium.copy(color = theme.on_background)) + LinkifyText(warning_text ?: "", theme.accent, style = MaterialTheme.typography.bodyMedium.copy(color = theme.onBackground)) Button( { accepted = true }, Modifier.align(Alignment.End), colors = ButtonDefaults.buttonColors( containerColor = theme.accent, - contentColor = theme.on_accent + contentColor = theme.onAccent ) ) { Text( @@ -111,7 +112,8 @@ internal fun getDiscordCategoryItems(context: AppContext): List { ComposableSettingsItem( shouldShowItem = { LocalProgramArguments.current.is_flatpak - } + }, + resetComposeUiState = {} ) { modifier -> val program_arguments: ProgramArguments = LocalProgramArguments.current val player: PlayerState = LocalPlayerState.current @@ -119,7 +121,7 @@ internal fun getDiscordCategoryItems(context: AppContext): List { if (program_arguments.is_flatpak) { LinkifyText( stringResource(Res.string.`info_flatpak_discord_$url`).replace("\$url", stringResource(Res.string.flatpak_documentation_url) + " "), - player.theme.vibrant_accent, + player.theme.vibrantAccent, modifier = modifier ) } @@ -128,31 +130,31 @@ internal fun getDiscordCategoryItems(context: AppContext): List { getDiscordAuthItem(context), ToggleSettingsItem( - context.settings.discord.STATUS_ENABLE + context.settings.Discord.STATUS_ENABLE ), GroupSettingsItem(Res.string.s_group_discord_status_disable_when), ToggleSettingsItem( - context.settings.discord.STATUS_DISABLE_WHEN_INVISIBLE + context.settings.Discord.STATUS_DISABLE_WHEN_INVISIBLE ), ToggleSettingsItem( - context.settings.discord.STATUS_DISABLE_WHEN_DND + context.settings.Discord.STATUS_DISABLE_WHEN_DND ), ToggleSettingsItem( - context.settings.discord.STATUS_DISABLE_WHEN_IDLE + context.settings.Discord.STATUS_DISABLE_WHEN_IDLE ), ToggleSettingsItem( - context.settings.discord.STATUS_DISABLE_WHEN_OFFLINE + context.settings.Discord.STATUS_DISABLE_WHEN_OFFLINE ), ToggleSettingsItem( - context.settings.discord.STATUS_DISABLE_WHEN_ONLINE + context.settings.Discord.STATUS_DISABLE_WHEN_ONLINE ), GroupSettingsItem(Res.string.s_group_discord_status_images), - DropdownSettingsItem( - context.settings.discord.LARGE_IMAGE_SOURCE + DropdownSettingsItem.ofEnumState( + context.settings.Discord.LARGE_IMAGE_SOURCE ) { when (it) { DiscordSettings.ImageSource.SONG -> stringResource(Res.string.s_option_discord_status_image_source_song) @@ -162,8 +164,8 @@ internal fun getDiscordCategoryItems(context: AppContext): List { } }, - DropdownSettingsItem( - context.settings.discord.SMALL_IMAGE_SOURCE + DropdownSettingsItem.ofEnumState( + context.settings.Discord.SMALL_IMAGE_SOURCE ) { when (it) { DiscordSettings.ImageSource.SONG -> stringResource(Res.string.s_option_discord_status_image_source_song) @@ -178,33 +180,33 @@ internal fun getDiscordCategoryItems(context: AppContext): List { InfoTextSettingsItem(Res.string.s_discord_status_text_info), TextFieldSettingsItem( - context.settings.discord.STATUS_NAME, + context.settings.Discord.STATUS_NAME, getFieldModifier = { Modifier.appTextField() } ), TextFieldSettingsItem( - context.settings.discord.STATUS_TEXT_A, + context.settings.Discord.STATUS_TEXT_A, getFieldModifier = { Modifier.appTextField() } ), TextFieldSettingsItem( - context.settings.discord.STATUS_TEXT_B, + context.settings.Discord.STATUS_TEXT_B, getFieldModifier = { Modifier.appTextField() } ), TextFieldSettingsItem( - context.settings.discord.STATUS_TEXT_C, + context.settings.Discord.STATUS_TEXT_C, getFieldModifier = { Modifier.appTextField() } ), ToggleSettingsItem( - context.settings.discord.SHOW_SONG_BUTTON + context.settings.Discord.SHOW_SONG_BUTTON ), TextFieldSettingsItem( - context.settings.discord.SONG_BUTTON_TEXT + context.settings.Discord.SONG_BUTTON_TEXT ), ToggleSettingsItem( - context.settings.discord.SHOW_PROJECT_BUTTON + context.settings.Discord.SHOW_PROJECT_BUTTON ), TextFieldSettingsItem( - context.settings.discord.PROJECT_BUTTON_TEXT, + context.settings.Discord.PROJECT_BUTTON_TEXT, getFieldModifier = { Modifier.appTextField() } ) ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ExperimentalCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ExperimentalCategory.kt index 8eed9542b..818530d6d 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ExperimentalCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ExperimentalCategory.kt @@ -9,9 +9,9 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.platform.AppContext -import dev.toastbits.composekit.settings.ui.component.item.ComposableSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ComposableSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.button_android_monet_open_dependency @@ -20,9 +20,9 @@ import spmp.shared.generated.resources.url_android_monet_open_dependency internal fun getExperimentalCategoryItems(context: AppContext): List = listOf( - ToggleSettingsItem(context.settings.experimental.ANDROID_MONET_COLOUR_ENABLE), + ToggleSettingsItem(context.settings.Experimental.ANDROID_MONET_COLOUR_ENABLE), - ComposableSettingsItem { modifier -> + ComposableSettingsItem(resetComposeUiState = {}) { modifier -> Column( modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(5.dp) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/FeedCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/FeedCategory.kt index c6fbabe74..40788efd1 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/FeedCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/FeedCategory.kt @@ -6,9 +6,8 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem -import dev.toastbits.composekit.platform.PreferencesProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem import com.toasterofbread.spmp.model.deserialise import com.toasterofbread.spmp.model.getString import com.toasterofbread.spmp.model.serialise @@ -16,25 +15,24 @@ import com.toasterofbread.spmp.ui.layout.apppage.settingspage.AppSliderItem import com.toasterofbread.spmp.ui.layout.apppage.settingspage.AppStringSetItem import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.utils.common.toCustomResource +import dev.toastbits.composekit.util.toCustomResource import dev.toastbits.ytmkt.uistrings.RawUiString import dev.toastbits.ytmkt.uistrings.UiString -import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_hidden_feed_rows_dialog_title internal fun getFeedCategoryItems(context: AppContext): List { return listOf( ToggleSettingsItem( - context.settings.feed.SHOW_ARTISTS_ROW + context.settings.Feed.SHOW_ARTISTS_ROW ), ToggleSettingsItem( - context.settings.feed.SHOW_SONG_DOWNLOAD_INDICATORS + context.settings.Feed.SHOW_SONG_DOWNLOAD_INDICATORS ), AppSliderItem( - context.settings.feed.INITIAL_ROWS, + context.settings.Feed.INITIAL_ROWS, "1".toCustomResource(), "10".toCustomResource(), range = 1f..10f, @@ -42,46 +40,46 @@ internal fun getFeedCategoryItems(context: AppContext): List { ), AppSliderItem( - context.settings.feed.SQUARE_PREVIEW_TEXT_LINES, + context.settings.Feed.SQUARE_PREVIEW_TEXT_LINES, "1".toCustomResource(), "5".toCustomResource(), range = 1f..5f ), AppSliderItem( - context.settings.feed.GRID_ROW_COUNT, + context.settings.Feed.GRID_ROW_COUNT, "1".toCustomResource(), "10".toCustomResource(), range = 1f..10f ), AppSliderItem( - context.settings.feed.GRID_ROW_COUNT_EXPANDED, + context.settings.Feed.GRID_ROW_COUNT_EXPANDED, "1".toCustomResource(), "10".toCustomResource(), range = 1f..10f ), AppSliderItem( - context.settings.feed.LANDSCAPE_GRID_ROW_COUNT, + context.settings.Feed.LANDSCAPE_GRID_ROW_COUNT, "1".toCustomResource(), "10".toCustomResource(), range = 1f..10f ), AppSliderItem( - context.settings.feed.LANDSCAPE_GRID_ROW_COUNT_EXPANDED, + context.settings.Feed.LANDSCAPE_GRID_ROW_COUNT_EXPANDED, "1".toCustomResource(), "10".toCustomResource(), range = 1f..10f ), ToggleSettingsItem( - context.settings.feed.SHOW_RADIOS + context.settings.Feed.SHOW_RADIOS ), AppStringSetItem( - context.settings.feed.HIDDEN_ROWS, + context.settings.Feed.HIDDEN_ROWS, Res.string.s_hidden_feed_rows_dialog_title, itemToText = { val player: PlayerState = LocalPlayerState.current diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/FilterCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/FilterCategory.kt index de05f1fa2..4490be9d6 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/FilterCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/FilterCategory.kt @@ -1,34 +1,32 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage.category -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem -import dev.toastbits.composekit.platform.PreferencesProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem import com.toasterofbread.spmp.ui.layout.apppage.settingspage.AppStringSetItem import com.toasterofbread.spmp.platform.AppContext -import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_filter_title_keywords_dialog_title internal fun getFilterCategoryItems(context: AppContext): List { return listOf( ToggleSettingsItem( - context.settings.filter.ENABLE + context.settings.Filter.ENABLE ), ToggleSettingsItem( - context.settings.filter.APPLY_TO_PLAYLIST_ITEMS + context.settings.Filter.APPLY_TO_PLAYLIST_ITEMS ), ToggleSettingsItem( - context.settings.filter.APPLY_TO_ARTISTS + context.settings.Filter.APPLY_TO_ARTISTS ), ToggleSettingsItem( - context.settings.filter.APPLY_TO_ARTIST_ITEMS + context.settings.Filter.APPLY_TO_ARTIST_ITEMS ), AppStringSetItem( - context.settings.filter.TITLE_KEYWORDS, + context.settings.Filter.TITLE_KEYWORDS, Res.string.s_filter_title_keywords_dialog_title ) ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/LayoutCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/LayoutCategory.kt index 9abd1eb66..02ee3131c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/LayoutCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/LayoutCategory.kt @@ -2,6 +2,6 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage.category import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.getLayoutSlotEditorSettingsItems import com.toasterofbread.spmp.platform.AppContext -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem internal fun getLayoutCategoryItems(context: AppContext): List = getLayoutSlotEditorSettingsItems(context) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/LyricsCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/LyricsCategory.kt index af92b8b66..9f12ab9a5 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/LyricsCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/LyricsCategory.kt @@ -1,12 +1,12 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage.category -import dev.toastbits.composekit.settings.ui.component.item.DropdownSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.DropdownSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem import com.toasterofbread.spmp.ui.layout.apppage.settingspage.AppSliderItem import com.toasterofbread.spmp.youtubeapi.lyrics.LyricsSource import com.toasterofbread.spmp.platform.AppContext -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.utils.common.toCustomResource +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.util.toCustomResource import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_option_lyrics_follow_offset_top @@ -18,18 +18,18 @@ import spmp.shared.generated.resources.s_option_lyrics_text_alignment_end internal fun getLyricsCategoryItems(context: AppContext): List { return listOf( DropdownSettingsItem( - context.settings.lyrics.DEFAULT_SOURCE, + context.settings.Lyrics.DEFAULT_SOURCE, LyricsSource.SOURCE_AMOUNT ) { i -> LyricsSource.fromIdx(i).getReadable() }, ToggleSettingsItem( - context.settings.lyrics.FOLLOW_ENABLED + context.settings.Lyrics.FOLLOW_ENABLED ), AppSliderItem( - context.settings.lyrics.FOLLOW_OFFSET, + context.settings.Lyrics.FOLLOW_OFFSET, Res.string.s_option_lyrics_follow_offset_top.toCustomResource(), Res.string.s_option_lyrics_follow_offset_bottom.toCustomResource(), steps = 5, @@ -37,15 +37,15 @@ internal fun getLyricsCategoryItems(context: AppContext): List { ), ToggleSettingsItem( - context.settings.lyrics.ROMANISE_FURIGANA + context.settings.Lyrics.ROMANISE_FURIGANA ), ToggleSettingsItem( - context.settings.lyrics.DEFAULT_FURIGANA + context.settings.Lyrics.DEFAULT_FURIGANA ), DropdownSettingsItem( - context.settings.lyrics.TEXT_ALIGNMENT, + context.settings.Lyrics.TEXT_ALIGNMENT, 3 ) { i -> when (i) { @@ -56,29 +56,29 @@ internal fun getLyricsCategoryItems(context: AppContext): List { }, ToggleSettingsItem( - context.settings.lyrics.EXTRA_PADDING + context.settings.Lyrics.EXTRA_PADDING ), ToggleSettingsItem( - context.settings.lyrics.ENABLE_WORD_SYNC + context.settings.Lyrics.ENABLE_WORD_SYNC ), AppSliderItem( - context.settings.lyrics.FONT_SIZE + context.settings.Lyrics.FONT_SIZE ), AppSliderItem( - context.settings.lyrics.SYNC_DELAY, + context.settings.Lyrics.SYNC_DELAY, range = -5f .. 5f ), AppSliderItem( - context.settings.lyrics.SYNC_DELAY_TOPBAR, + context.settings.Lyrics.SYNC_DELAY_TOPBAR, range = -5f .. 5f ), AppSliderItem( - context.settings.lyrics.SYNC_DELAY_BLUETOOTH, + context.settings.Lyrics.SYNC_DELAY_BLUETOOTH, range = -5f .. 5f ) ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/MiscCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/MiscCategory.kt index 3b89e0189..81c4ce9a9 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/MiscCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/MiscCategory.kt @@ -1,30 +1,146 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage.category +import androidx.compose.animation.Crossfade +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Sync +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier -import dev.toastbits.composekit.settings.ui.component.item.GroupSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.TextFieldSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem +import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.GroupSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.TextFieldSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField import com.toasterofbread.spmp.ui.layout.apppage.settingspage.AppSliderItem import com.toasterofbread.spmp.platform.AppContext -import org.jetbrains.compose.resources.stringResource +import com.toasterofbread.spmp.resources.getStringTODO +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.context.PlatformFile +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.FileSettingsItem +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import org.jetbrains.compose.resources.getString import spmp.shared.generated.resources.Res +import spmp.shared.generated.resources.action_confirm_action +import spmp.shared.generated.resources.action_deny_action import spmp.shared.generated.resources.s_group_caching internal fun getMiscCategoryItems(context: AppContext): List { return listOf( + ToggleSettingsItem( + context.settings.Misc.PERSISTENT_QUEUE + ), + + ToggleSettingsItem( + context.settings.Misc.ADD_SONGS_TO_HISTORY + ), + + FileSettingsItem( + state = context.settings.Misc.LIBRARY_PATH, + getPathLabel = { path -> + if (path.isBlank()) { + return@FileSettingsItem MediaItemLibrary.getDefaultLibraryDir(context)!!.absolute_path + } + else { + return@FileSettingsItem path + // Format Android documents tree URI to standard path +// val split_path: List = URI.create(path).path.split(':') +// if (split_path.size == 1) { +// return@FileSettingsItem split_path.first().removePrefix("/tree/") +// } +// else { +// val storage: String = split_path.first().split('/').last().capitalize(Locale(context.getUiLanguage())) +// return@FileSettingsItem "($storage) ~/${split_path.last()}" +// } + } + }, + extraContent = { + val coroutine_scope: CoroutineScope = rememberCoroutineScope() + + IconButton({ + if (MediaItemLibrary.song_sync_in_progress) { + return@IconButton + } + + coroutine_scope.launch { + MediaItemLibrary.syncLocalSongs(context) + } + }) { + Crossfade(MediaItemLibrary.song_sync_in_progress) { syncing -> + if (syncing) { + SubtleLoadingIndicator() + } + else { + Icon(Icons.Default.Sync, null) + } + } + } + }, + onSelectRequested = { setValue, showDialog -> + val path: String? = context.promptUserForDirectory(true)?.uri + context.coroutineScope.launch { + val old_location: PlatformFile = MediaItemLibrary.getLibraryDir(context, context.settings.Misc.LIBRARY_PATH.get())!! + val new_location: PlatformFile = MediaItemLibrary.getLibraryDir(context, path ?: "")!! + + suspend fun processDialogSelection(accepted: Boolean, is_retry: Boolean = false) { + if (accepted) { + if (old_location.is_directory) { + val result: Result = old_location.moveDirContentTo(new_location) + result.onFailure { error -> + showDialog( + FileSettingsItem.Dialog( + getStringTODO("Transfer failed"), + error.toString(), + getString(Res.string.action_confirm_action), + null + ) {} + ) + return@onFailure + } + } + } else if (is_retry) { + return + } + + setValue(path ?: "") + } + + if (old_location.uri == new_location.uri) { + return@launch + } + + if (!old_location.is_directory) { + processDialogSelection(true) + return@launch + } + + showDialog( + FileSettingsItem.Dialog( + getStringTODO("Transfer existing library"), + getStringTODO("Move the library at ${old_location.path} to ${new_location.path}?"), + getString(Res.string.action_confirm_action), + getString(Res.string.action_deny_action) + ) { accepted -> + processDialogSelection(accepted) + } + ) + } + } + ), + AppSliderItem( - context.settings.misc.NAVBAR_HEIGHT_MULTIPLIER + context.settings.Misc.NAVBAR_HEIGHT_MULTIPLIER ), TextFieldSettingsItem( - context.settings.misc.STATUS_WEBHOOK_URL, + context.settings.Misc.STATUS_WEBHOOK_URL, getFieldModifier = { Modifier.appTextField() } ), TextFieldSettingsItem( - context.settings.misc.STATUS_WEBHOOK_PAYLOAD, + context.settings.Misc.STATUS_WEBHOOK_PAYLOAD, getFieldModifier = { Modifier.appTextField() } ) ) + getCachingGroup(context) @@ -34,7 +150,7 @@ private fun getCachingGroup(context: AppContext): List { return listOf( GroupSettingsItem(Res.string.s_group_caching), ToggleSettingsItem( - context.settings.misc.THUMB_CACHE_ENABLED + context.settings.Misc.THUMB_CACHE_ENABLED ) ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/PlatformCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/PlatformCategory.kt index 8a40f62d0..7246c6afa 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/PlatformCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/PlatformCategory.kt @@ -4,13 +4,12 @@ import LocalPlayerState import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import dev.toastbits.composekit.settings.ui.component.item.GroupSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.InfoTextSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.settings.ui.component.item.TextFieldSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.GroupSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.InfoTextSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.TextFieldSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.playerservice.PlatformInternalPlayerService @@ -22,6 +21,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue +import dev.toastbits.composekit.settingsitem.presentation.util.getConvertedProperty import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_group_desktop_system @@ -49,12 +49,12 @@ private fun getDesktopGroupItems(context: AppContext): List = GroupSettingsItem(Res.string.s_group_desktop_system), TextFieldSettingsItem( - context.settings.platform.STARTUP_COMMAND, + context.settings.Platform.STARTUP_COMMAND, getFieldModifier = { Modifier.appTextField() } ), ToggleSettingsItem( - context.settings.platform.FORCE_SOFTWARE_RENDERER, + context.settings.Platform.FORCE_SOFTWARE_RENDERER, ), GroupSettingsItem(Res.string.s_group_server) @@ -85,7 +85,7 @@ fun getServerGroupItems(context: AppContext): List { InfoTextSettingsItem(Res.string.s_info_server), ToggleSettingsItem( - context.settings.platform.ENABLE_EXTERNAL_SERVER_MODE, + context.settings.Platform.ENABLE_EXTERNAL_SERVER_MODE, getEnabled = { val reason: LocalServerUnavailabilityReason? = getLocalServerUnavailabilityReason() return@ToggleSettingsItem reason != null && reason.reason == null @@ -103,10 +103,10 @@ fun getServerGroupItems(context: AppContext): List { } ).takeIf { !Platform.DESKTOP.isCurrent() }, - ToggleSettingsItem(context.settings.platform.EXTERNAL_SERVER_MODE_UI_ONLY).takeIf { PlatformExternalPlayerService.playsAudio() }, + ToggleSettingsItem(context.settings.Platform.EXTERNAL_SERVER_MODE_UI_ONLY).takeIf { PlatformExternalPlayerService.playsAudio() }, TextFieldSettingsItem( - context.settings.platform.SERVER_IP_ADDRESS, + context.settings.Platform.SERVER_IP_ADDRESS, getStringErrorProvider = { val settings_value_not_ipv4_or_domain: String = stringResource(Res.string.settings_value_not_ipv4_or_domain) return@TextFieldSettingsItem { input -> @@ -118,7 +118,7 @@ fun getServerGroupItems(context: AppContext): List { ), TextFieldSettingsItem( - context.settings.platform.SERVER_PORT.getConvertedProperty( + context.settings.Platform.SERVER_PORT.getConvertedProperty( fromProperty = { it.toString() }, toProperty = { it.toIntOrNull() ?: 0 } ), @@ -133,12 +133,12 @@ fun getServerGroupItems(context: AppContext): List { ), TextFieldSettingsItem( - context.settings.platform.SERVER_LOCAL_COMMAND, + context.settings.Platform.SERVER_LOCAL_COMMAND, getFieldModifier = { Modifier.appTextField() } ).takeIf { Platform.DESKTOP.isCurrent() }, ToggleSettingsItem( - context.settings.platform.SERVER_LOCAL_START_AUTOMATICALLY + context.settings.Platform.SERVER_LOCAL_START_AUTOMATICALLY ).takeIf { Platform.DESKTOP.isCurrent() } ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/PlayerCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/PlayerCategory.kt index 42014c911..332d443e8 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/PlayerCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/PlayerCategory.kt @@ -1,18 +1,13 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage.category -import dev.toastbits.composekit.settings.ui.component.item.GroupSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.MultipleChoiceSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem -import dev.toastbits.composekit.platform.PreferencesProperty -import com.toasterofbread.spmp.model.settings.category.NowPlayingQueueRadioInfoPosition +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.GroupSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.MultipleChoiceSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem import com.toasterofbread.spmp.model.settings.category.NowPlayingQueueWaveBorderMode -import com.toasterofbread.spmp.model.settings.category.OverscrollClearMode import com.toasterofbread.spmp.ui.layout.apppage.settingspage.AppSliderItem -import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.PlayerOverlayMenuAction import com.toasterofbread.spmp.platform.AppContext -import dev.toastbits.composekit.utils.common.toCustomResource -import kotlin.enums.enumEntries +import dev.toastbits.composekit.util.toCustomResource import kotlin.math.roundToInt import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res @@ -25,25 +20,25 @@ import spmp.shared.generated.resources.s_option_wave_border_mode_line internal fun getPlayerCategoryItems(context: AppContext): List { return listOf( AppSliderItem( - context.settings.player.EXPAND_SWIPE_SENSITIVITY, + context.settings.Player.EXPAND_SWIPE_SENSITIVITY, range = 0.1f .. 10f ), ToggleSettingsItem( - context.settings.player.MINI_SHOW_PREV_BUTTON + context.settings.Player.MINI_SHOW_PREV_BUTTON ), ToggleSettingsItem( - context.settings.player.MINI_OVERSCROLL_CLEAR_ENABLED + context.settings.Player.MINI_OVERSCROLL_CLEAR_ENABLED ), AppSliderItem( - context.settings.player.MINI_OVERSCROLL_CLEAR_TIME, + context.settings.Player.MINI_OVERSCROLL_CLEAR_TIME, range = 0f .. 1f ), MultipleChoiceSettingsItem( - context.settings.player.MINI_OVERSCROLL_CLEAR_MODE + context.settings.Player.MINI_OVERSCROLL_CLEAR_MODE ) { mode -> mode.getReadable() }, @@ -51,36 +46,36 @@ internal fun getPlayerCategoryItems(context: AppContext): List { GroupSettingsItem(null), ToggleSettingsItem( - context.settings.player.SHOW_REPEAT_SHUFFLE_BUTTONS + context.settings.Player.SHOW_REPEAT_SHUFFLE_BUTTONS ), ToggleSettingsItem( - context.settings.player.SHOW_SEEK_BAR_GRADIENT + context.settings.Player.SHOW_SEEK_BAR_GRADIENT ), ToggleSettingsItem( - context.settings.player.LANDSCAPE_SWAP_CONTROLS_AND_IMAGE + context.settings.Player.LANDSCAPE_SWAP_CONTROLS_AND_IMAGE ), MultipleChoiceSettingsItem( - context.settings.player.OVERLAY_CUSTOM_ACTION, + context.settings.Player.OVERLAY_CUSTOM_ACTION, ) { action -> action.getReadable() }, ToggleSettingsItem( - context.settings.player.OVERLAY_SWAP_LONG_SHORT_PRESS_ACTIONS + context.settings.Player.OVERLAY_SWAP_LONG_SHORT_PRESS_ACTIONS ), GroupSettingsItem(null), AppSliderItem( - context.settings.player.QUEUE_ITEM_SWIPE_SENSITIVITY, + context.settings.Player.QUEUE_ITEM_SWIPE_SENSITIVITY, range = 0.1f .. 2f ), AppSliderItem( - context.settings.player.QUEUE_EXTRA_SIDE_PADDING, + context.settings.Player.QUEUE_EXTRA_SIDE_PADDING, range = 0f .. 1f, min_label = "0%".toCustomResource(), max_label = "100%".toCustomResource(), @@ -90,7 +85,7 @@ internal fun getPlayerCategoryItems(context: AppContext): List { ), MultipleChoiceSettingsItem( - context.settings.player.QUEUE_WAVE_BORDER_MODE, + context.settings.Player.QUEUE_WAVE_BORDER_MODE, ) { mode -> when (mode) { NowPlayingQueueWaveBorderMode.TIME -> stringResource(Res.string.s_option_wave_border_mode_time) @@ -102,22 +97,22 @@ internal fun getPlayerCategoryItems(context: AppContext): List { }, MultipleChoiceSettingsItem( - context.settings.player.QUEUE_RADIO_INFO_POSITION + context.settings.Player.QUEUE_RADIO_INFO_POSITION ) { position -> position.getReadable() }, ToggleSettingsItem( - context.settings.player.PAUSE_ON_BT_DISCONNECT + context.settings.Player.PAUSE_ON_BT_DISCONNECT ), ToggleSettingsItem( - context.settings.player.RESUME_ON_BT_CONNECT + context.settings.Player.RESUME_ON_BT_CONNECT ), ToggleSettingsItem( - context.settings.player.PAUSE_ON_WIRED_DISCONNECT + context.settings.Player.PAUSE_ON_WIRED_DISCONNECT ), ToggleSettingsItem( - context.settings.player.RESUME_ON_WIRED_CONNECT + context.settings.Player.RESUME_ON_WIRED_CONNECT ) ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/SearchCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/SearchCategory.kt index d56f78e96..aea6fa237 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/SearchCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/SearchCategory.kt @@ -1,12 +1,12 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage.category -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import com.toasterofbread.spmp.platform.AppContext internal fun getSearchCategoryItems(context: AppContext): List = listOf( ToggleSettingsItem( - context.settings.search.SEARCH_FOR_NON_MUSIC + context.settings.Search.SEARCH_FOR_NON_MUSIC ) ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ShortcutCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ShortcutCategory.kt index e92586299..976d19812 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ShortcutCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ShortcutCategory.kt @@ -1,7 +1,7 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage.category -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ComposableSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ComposableSettingsItem import com.toasterofbread.spmp.model.appaction.shortcut.ShortcutsEditor import com.toasterofbread.spmp.platform.AppContext @@ -9,9 +9,10 @@ internal fun getShortcutCategoryItems(context: AppContext): List = listOf( ComposableSettingsItem( listOf( - context.settings.shortcut.CONFIGURED_SHORTCUTS, - context.settings.shortcut.NAVIGATE_SONG_WITH_NUMBERS - ) + context.settings.Shortcut.CONFIGURED_SHORTCUTS, + context.settings.Shortcut.NAVIGATE_SONG_WITH_NUMBERS + ), + resetComposeUiState = {} ) { modifier -> ShortcutsEditor(modifier) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/StreamingCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/StreamingCategory.kt index e33e84b08..08036897e 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/StreamingCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/StreamingCategory.kt @@ -5,11 +5,12 @@ import com.toasterofbread.spmp.model.settings.category.VideoFormatsEndpointType import com.toasterofbread.spmp.model.settings.category.isAvailable import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.ui.layout.apppage.settingspage.AppSliderItem -import dev.toastbits.composekit.settings.ui.component.item.DropdownSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.MultipleChoiceSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem -import dev.toastbits.composekit.utils.common.toCustomResource +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.DropdownSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.MultipleChoiceSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.util.getConvertedProperty +import dev.toastbits.composekit.util.toCustomResource import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_option_audio_quality_high @@ -22,35 +23,35 @@ internal fun getStreamingCategoryItems(context: AppContext): List return listOf( DropdownSettingsItem( - context.settings.streaming.VIDEO_FORMATS_METHOD.getConvertedProperty( + context.settings.Streaming.VIDEO_FORMATS_METHOD.getConvertedProperty( fromProperty = { it.ordinal }, toProperty = { available_video_formats[it] } ), - item_count = available_video_formats.size, + itemCount = available_video_formats.size, getItem = { available_video_formats[it].getReadable() } ), ToggleSettingsItem( - context.settings.streaming.ENABLE_VIDEO_FORMAT_FALLBACK + context.settings.Streaming.ENABLE_VIDEO_FORMAT_FALLBACK ), ToggleSettingsItem( - context.settings.streaming.AUTO_DOWNLOAD_ENABLED + context.settings.Streaming.AUTO_DOWNLOAD_ENABLED ), AppSliderItem( - context.settings.streaming.AUTO_DOWNLOAD_THRESHOLD, + context.settings.Streaming.AUTO_DOWNLOAD_THRESHOLD, range = 1f..10f, min_label = "1".toCustomResource(), max_label = "10".toCustomResource() ), ToggleSettingsItem( - context.settings.streaming.AUTO_DOWNLOAD_ON_METERED + context.settings.Streaming.AUTO_DOWNLOAD_ON_METERED ), - DropdownSettingsItem( - context.settings.streaming.STREAM_AUDIO_QUALITY + DropdownSettingsItem.ofEnumState( + context.settings.Streaming.STREAM_AUDIO_QUALITY ) { quality -> when (quality) { SongAudioQuality.HIGH -> stringResource(Res.string.s_option_audio_quality_high) @@ -59,8 +60,8 @@ internal fun getStreamingCategoryItems(context: AppContext): List } }, - DropdownSettingsItem( - context.settings.streaming.DOWNLOAD_AUDIO_QUALITY + DropdownSettingsItem.ofEnumState( + context.settings.Streaming.DOWNLOAD_AUDIO_QUALITY ) { quality -> when (quality) { SongAudioQuality.HIGH -> stringResource(Res.string.s_option_audio_quality_high) @@ -70,21 +71,21 @@ internal fun getStreamingCategoryItems(context: AppContext): List }, ToggleSettingsItem( - context.settings.streaming.ENABLE_AUDIO_NORMALISATION + context.settings.Streaming.ENABLE_AUDIO_NORMALISATION ), ToggleSettingsItem( - context.settings.streaming.ENABLE_SILENCE_SKIPPING + context.settings.Streaming.ENABLE_SILENCE_SKIPPING ), MultipleChoiceSettingsItem( - context.settings.streaming.DOWNLOAD_METHOD + context.settings.Streaming.DOWNLOAD_METHOD ) { method -> method.getTitle() + " - " + method.getDescription() }, ToggleSettingsItem( - context.settings.streaming.SKIP_DOWNLOAD_METHOD_CONFIRMATION + context.settings.Streaming.SKIP_DOWNLOAD_METHOD_CONFIRMATION ) ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/SystemCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/SystemCategory.kt deleted file mode 100644 index 7aad5f178..000000000 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/SystemCategory.kt +++ /dev/null @@ -1,245 +0,0 @@ -package com.toasterofbread.spmp.ui.layout.apppage.settingspage.category - -import LocalPlayerState -import androidx.compose.animation.Crossfade -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Add -import androidx.compose.material.icons.filled.Remove -import androidx.compose.material.icons.filled.Sync -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.Text -import androidx.compose.runtime.getValue -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary -import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.platform.observeUiLanguage -import com.toasterofbread.spmp.resources.Language -import com.toasterofbread.spmp.resources.getStringTODO -import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.platform.PlatformFile -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.ComposableSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.DropdownSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.FileSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem.Companion.ItemTitleText -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem -import dev.toastbits.composekit.utils.composable.ShapedIconButton -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch -import org.jetbrains.compose.resources.getString -import org.jetbrains.compose.resources.stringResource -import spmp.shared.generated.resources.Res -import spmp.shared.generated.resources.action_confirm_action -import spmp.shared.generated.resources.action_deny_action -import spmp.shared.generated.resources.system_language - -// TODO Allow setting to any language -fun getLanguageDropdownItem( - property: PreferencesProperty, - available_languages: List -): SettingsItem { - return DropdownSettingsItem( - property.getConvertedProperty( - fromProperty = { language_code: String -> - if (language_code.isBlank()) { - return@getConvertedProperty 0 - } - - val index = available_languages.indexOfFirst { it.identifier == language_code } - if (index == -1) { - property.reset() - return@getConvertedProperty 0 - } - else { - return@getConvertedProperty index + 1 - } - }, - toProperty = { index: Int -> - if (index == 0) { - "" - } - else { - available_languages[index - 1].identifier - } - } - ), - available_languages.size + 1, - { i -> - if (i == 0) { - stringResource(Res.string.system_language) - } - else { - available_languages[i - 1].readable_name - } - } - ) { i -> - if (i == 0) { - stringResource(Res.string.system_language) - } - else { - val lang = available_languages[i - 1] - "${lang.identifier} / ${lang.readable_name}" - } - } -} - -internal fun getSystemCategoryItems(context: AppContext, available_languages: List): List = - listOf( - getLanguageDropdownItem( - context.settings.system.LANG_UI, - available_languages - ), - - getLanguageDropdownItem( - context.settings.system.LANG_DATA, - available_languages - ), - - DropdownSettingsItem( - context.settings.system.FONT - ) { mode -> - mode.getReadable(context.observeUiLanguage().value) - }, - - ComposableSettingsItem( - listOf(context.settings.system.UI_SCALE), - resetSettingsValues = { - context.settings.system.UI_SCALE.set(1f) - } - ) { - val player: PlayerState = LocalPlayerState.current - - Row(verticalAlignment = Alignment.CenterVertically) { - ItemTitleText(context.settings.system.UI_SCALE.getName(), player.theme, Modifier.weight(1f)) - - Spacer(Modifier.fillMaxWidth().weight(1f)) - - var ui_scale: Float by player.settings.system.UI_SCALE.observe() - - ShapedIconButton({ - ui_scale = (ui_scale - 0.1f).coerceAtLeast(0.1f) - }) { - Icon(Icons.Default.Remove, null) - } - - Text("${(ui_scale * 100).toInt()}%") - - ShapedIconButton({ - ui_scale += 0.1f - }) { - Icon(Icons.Default.Add, null) - } - } - }, - - ToggleSettingsItem( - context.settings.system.PERSISTENT_QUEUE - ), - - ToggleSettingsItem( - context.settings.system.ADD_SONGS_TO_HISTORY - ), - - FileSettingsItem( - state = context.settings.system.LIBRARY_PATH, - getPathLabel = { path -> - if (path.isBlank()) { - return@FileSettingsItem MediaItemLibrary.getDefaultLibraryDir(context)!!.absolute_path - } - else { - return@FileSettingsItem path - // Format Android documents tree URI to standard path -// val split_path: List = URI.create(path).path.split(':') -// if (split_path.size == 1) { -// return@FileSettingsItem split_path.first().removePrefix("/tree/") -// } -// else { -// val storage: String = split_path.first().split('/').last().capitalize(Locale(context.getUiLanguage())) -// return@FileSettingsItem "($storage) ~/${split_path.last()}" -// } - } - }, - extraContent = { - val coroutine_scope: CoroutineScope = rememberCoroutineScope() - - IconButton({ - if (MediaItemLibrary.song_sync_in_progress) { - return@IconButton - } - - coroutine_scope.launch { - MediaItemLibrary.syncLocalSongs(context) - } - }) { - Crossfade(MediaItemLibrary.song_sync_in_progress) { syncing -> - if (syncing) { - SubtleLoadingIndicator() - } - else { - Icon(Icons.Default.Sync, null) - } - } - } - }, - onSelectRequested = { setValue, showDialog -> - context.promptUserForDirectory(true) { path -> - context.coroutine_scope.launch { - val old_location: PlatformFile = MediaItemLibrary.getLibraryDir(context, context.settings.system.LIBRARY_PATH.get())!! - val new_location: PlatformFile = MediaItemLibrary.getLibraryDir(context, path ?: "")!! - - suspend fun processDialogSelection(accepted: Boolean, is_retry: Boolean = false) { - if (accepted) { - if (old_location.is_directory) { - val result: Result = old_location.moveDirContentTo(new_location) - result.onFailure { error -> - showDialog( - FileSettingsItem.Dialog( - getStringTODO("Transfer failed"), - error.toString(), - getString(Res.string.action_confirm_action), - null - ) {} - ) - return@onFailure - } - } - } else if (is_retry) { - return - } - - setValue(path ?: "") - } - - if (old_location.uri == new_location.uri) { - return@launch - } - - if (!old_location.is_directory) { - processDialogSelection(true) - return@launch - } - - showDialog( - FileSettingsItem.Dialog( - getStringTODO("Transfer existing library"), - getStringTODO("Move the library at ${old_location.path} to ${new_location.path}?"), - getString(Res.string.action_confirm_action), - getString(Res.string.action_deny_action) - ) { accepted -> - processDialogSelection(accepted) - } - ) - } - } - } - ) - ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ThemeCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ThemeCategory.kt index b50a0c8d4..ff8758438 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ThemeCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/ThemeCategory.kt @@ -1,70 +1,32 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage.category -import LocalPlayerState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import com.toasterofbread.spmp.model.settings.category.AccentColourSource import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.doesPlatformSupportVideoPlayback -import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField import com.toasterofbread.spmp.ui.layout.apppage.settingspage.AppSliderItem -import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingTopOffsetSection import com.toasterofbread.spmp.ui.layout.nowplaying.ThemeMode -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.platform.PlatformPreferencesListener -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.NamedTheme -import dev.toastbits.composekit.settings.ui.ThemeValues -import dev.toastbits.composekit.settings.ui.ThemeValuesData -import dev.toastbits.composekit.settings.ui.component.item.GroupSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.MultipleChoiceSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ThemeSelectorSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ThemeSelectorThemeProvider -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem -import dev.toastbits.composekit.settings.ui.rememberSystemTheme +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.GroupSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.MultipleChoiceSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem +import dev.toastbits.composekit.util.platform.Platform import isWindowTransparencySupported -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Job -import kotlinx.coroutines.launch -import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.s_group_theming_desktop -import spmp.shared.generated.resources.s_option_accent_theme -import spmp.shared.generated.resources.s_option_accent_thumbnail import spmp.shared.generated.resources.s_option_np_accent_background import spmp.shared.generated.resources.s_option_np_accent_elements import spmp.shared.generated.resources.s_option_np_accent_none -import spmp.shared.generated.resources.s_theme_editor_button_preview -import spmp.shared.generated.resources.s_theme_editor_field_accent -import spmp.shared.generated.resources.s_theme_editor_field_background -import spmp.shared.generated.resources.s_theme_editor_field_card -import spmp.shared.generated.resources.s_theme_editor_field_name -import spmp.shared.generated.resources.s_theme_editor_field_on_background -import spmp.shared.generated.resources.s_theme_editor_title -import spmp.shared.generated.resources.theme_title_new -import spmp.shared.generated.resources.theme_title_system internal fun getThemeCategoryItems(context: AppContext): List = listOfNotNull( - createThemeSelectorSettingsItem( - context, - context.settings.theme.CURRENT_THEME, - getFooterModifier = { - LocalPlayerState.current.nowPlayingTopOffset(Modifier, NowPlayingTopOffsetSection.PAGE_BAR) - } - ), - MultipleChoiceSettingsItem( - context.settings.theme.ACCENT_COLOUR_SOURCE + context.settings.Theme.ACCENT_COLOUR_SOURCE ) { source -> stringResource(source.getNameResource()) }, MultipleChoiceSettingsItem( - context.settings.theme.NOWPLAYING_THEME_MODE + context.settings.Theme.NOWPLAYING_THEME_MODE ) { mode -> when (mode) { ThemeMode.BACKGROUND -> stringResource(Res.string.s_option_np_accent_background) @@ -74,43 +36,43 @@ internal fun getThemeCategoryItems(context: AppContext): List = }, AppSliderItem( - context.settings.theme.NOWPLAYING_DEFAULT_GRADIENT_DEPTH + context.settings.Theme.NOWPLAYING_DEFAULT_GRADIENT_DEPTH ), AppSliderItem( - context.settings.theme.NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY + context.settings.Theme.NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY ), if (doesPlatformSupportVideoPlayback()) MultipleChoiceSettingsItem( - context.settings.theme.NOWPLAYING_DEFAULT_VIDEO_POSITION + context.settings.Theme.NOWPLAYING_DEFAULT_VIDEO_POSITION ) { position -> position.getReadable() } else null, AppSliderItem( - context.settings.theme.NOWPLAYING_DEFAULT_LANDSCAPE_QUEUE_OPACITY + context.settings.Theme.NOWPLAYING_DEFAULT_LANDSCAPE_QUEUE_OPACITY ), AppSliderItem( - context.settings.theme.NOWPLAYING_DEFAULT_SHADOW_RADIUS + context.settings.Theme.NOWPLAYING_DEFAULT_SHADOW_RADIUS ), AppSliderItem( - context.settings.theme.NOWPLAYING_DEFAULT_IMAGE_CORNER_ROUNDING + context.settings.Theme.NOWPLAYING_DEFAULT_IMAGE_CORNER_ROUNDING ), ToggleSettingsItem( - context.settings.theme.SHOW_EXPANDED_PLAYER_WAVE + context.settings.Theme.SHOW_EXPANDED_PLAYER_WAVE ), AppSliderItem( - context.settings.theme.NOWPLAYING_DEFAULT_WAVE_SPEED + context.settings.Theme.NOWPLAYING_DEFAULT_WAVE_SPEED ), AppSliderItem( - context.settings.theme.NOWPLAYING_DEFAULT_WAVE_OPACITY + context.settings.Theme.NOWPLAYING_DEFAULT_WAVE_OPACITY ) ) + when (Platform.current) { Platform.DESKTOP -> getDesktopGroupItems(context) @@ -127,103 +89,11 @@ private fun getDesktopGroupItems(context: AppContext): List = private fun getWindowTransparencyItems(context: AppContext): List = listOf( ToggleSettingsItem( - context.settings.theme.ENABLE_WINDOW_TRANSPARENCY + context.settings.Theme.ENABLE_WINDOW_TRANSPARENCY ), AppSliderItem( - context.settings.theme.WINDOW_BACKGROUND_OPACITY, + context.settings.Theme.WINDOW_BACKGROUND_OPACITY, range = 0f..1f ) ) - -fun createThemeSelectorSettingsItem( - context: AppContext, - state: PreferencesProperty, - getExtraStartThemes: @Composable () -> List = { emptyList() }, - getFooterModifier: @Composable () -> Modifier = { Modifier } -) = - ThemeSelectorSettingsItem( - state, - context.theme.manager, - str_editor_title = Res.string.s_theme_editor_title, - str_field_name = Res.string.s_theme_editor_field_name, - str_field_background = Res.string.s_theme_editor_field_background, - str_field_on_background = Res.string.s_theme_editor_field_on_background, - str_field_card = Res.string.s_theme_editor_field_card, - str_field_accent = Res.string.s_theme_editor_field_accent, - str_button_preview = Res.string.s_theme_editor_button_preview, - getFooterModifier = getFooterModifier, - getThemeProvider = { - val extra_start_themes: List = getExtraStartThemes() - val start_theme_count: Int = 1 + extra_start_themes.size - val system_theme: NamedTheme = rememberSystemTheme(stringResource(Res.string.theme_title_system), context) - - val initial_themes: List by context.settings.theme.THEMES.observe() - - return@ThemeSelectorSettingsItem object : ThemeSelectorThemeProvider { - private var themes: List = initial_themes - - private fun setThemes(new_themes: List) { - themes = new_themes - context.settings.theme.THEMES.set(new_themes) - } - - private val coroutine_scope: CoroutineScope = CoroutineScope(Job()) - private val prefs_listener: PlatformPreferencesListener = PlatformPreferencesListener { key -> - if (key == context.settings.theme.THEMES.key) { - coroutine_scope.launch { - themes = context.settings.theme.THEMES.get() - } - } - } - - init { - context.getPrefs().addListener(prefs_listener) - } - - override fun getTheme(index: Int): NamedTheme? = - if (index >= 0 && index < extra_start_themes.size) extra_start_themes[index] - else if (index <= extra_start_themes.size) system_theme - else themes.getOrNull(index - start_theme_count) - - override fun getThemeCount(): Int = - themes.size + start_theme_count - - override fun isThemeEditable(index: Int): Boolean = - themes.indices.contains(index - start_theme_count) - - override suspend fun createTheme(index: Int): Int { - val new_theme_index: Int = (index - start_theme_count).coerceAtLeast(0) - val new_themes: List = themes.toMutableList().apply { - add( - new_theme_index, - NamedTheme( - getString(Res.string.theme_title_new), - getTheme(index - 1)?.theme ?: ThemeValuesData.of(context.theme.manager.current_theme) - ) - ) - } - setThemes(new_themes) - return new_theme_index + start_theme_count - } - - override suspend fun removeTheme(index: Int) { - val new_themes: List = themes.toMutableList().apply { - removeAt(index - start_theme_count) - } - setThemes(new_themes) - } - - override fun onThemeEdited(index: Int, theme: ThemeValues, theme_name: String) { - val new_themes: List = themes.toMutableList().apply { - set(index - start_theme_count, NamedTheme(theme_name, ThemeValuesData.of(theme))) - } - setThemes(new_themes) - } - } - }, - getFieldModifier = { Modifier.appTextField() }, - resetThemes = { - context.settings.theme.THEMES.reset() - } - ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/WidgetCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/WidgetCategory.kt index 258e7e6a4..461f2b550 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/WidgetCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/WidgetCategory.kt @@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -22,9 +23,10 @@ import com.toasterofbread.spmp.widget.configuration.type.TypeWidgetConfig import com.toasterofbread.spmp.widget.configuration.ui.screen.WidgetConfigurationScreen import dev.toastbits.composekit.navigation.compositionlocal.LocalNavigator import dev.toastbits.composekit.navigation.navigator.Navigator -import dev.toastbits.composekit.platform.composable.ScrollBarLazyColumn -import dev.toastbits.composekit.settings.ui.component.item.ComposableSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyColumn +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ComposableSettingsItem +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.action_cancel @@ -35,10 +37,10 @@ import spmp.shared.generated.resources.s_key_default_widget_configurations internal fun getWidgetCategoryItems(context: AppContext): List = listOf( - ComposableSettingsItem { + ComposableSettingsItem(resetComposeUiState = {}) { val navigator: Navigator = LocalNavigator.current - val base_configuration: BaseWidgetConfig by context.settings.widget.DEFAULT_BASE_WIDGET_CONFIGURATION.observe() - val type_configurations: Map> by context.settings.widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.observe() + val base_configuration: BaseWidgetConfig by context.settings.Widget.DEFAULT_BASE_WIDGET_CONFIGURATION.observe() + val type_configurations: Map> by context.settings.Widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.observe() var show_type_selector: Boolean by remember { mutableStateOf(false) } @@ -64,13 +66,15 @@ internal fun getWidgetCategoryItems(context: AppContext): List = onDone = { new_base, _, new_type, _ -> navigator.navigateBackward() - if (new_base != null) { - context.settings.widget.DEFAULT_BASE_WIDGET_CONFIGURATION.set(new_base) - } - if (new_type != null) { - context.settings.widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.set( - type_configurations.toMutableMap().apply { set(type!!, new_type) } - ) + context.coroutineScope.launch { + if (new_base != null) { + context.settings.Widget.DEFAULT_BASE_WIDGET_CONFIGURATION.set(new_base) + } + if (new_type != null) { + context.settings.Widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.set( + type_configurations.toMutableMap().apply { set(type!!, new_type) } + ) + } } } ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/YoutubeAccountCategory.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/YoutubeAccountCategory.kt index a505e93c8..24be8d558 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/YoutubeAccountCategory.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/settingspage/category/YoutubeAccountCategory.kt @@ -1,13 +1,12 @@ package com.toasterofbread.spmp.ui.layout.apppage.settingspage.category -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem -import dev.toastbits.composekit.platform.PreferencesProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem import com.toasterofbread.spmp.platform.AppContext internal fun getYoutubeAccountCategory(context: AppContext): List = listOf( ToggleSettingsItem( - context.settings.system.ADD_SONGS_TO_HISTORY + context.settings.Misc.ADD_SONGS_TO_HISTORY ) ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/LFFSongFeedAppPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/LFFSongFeedAppPage.kt index 4029f667f..30b4b012c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/LFFSongFeedAppPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/LFFSongFeedAppPage.kt @@ -14,10 +14,10 @@ import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.platform.* import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.composable.* -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.composable.* -import dev.toastbits.composekit.utils.modifier.* +import dev.toastbits.composekit.components.platform.composable.* +import dev.toastbits.composekit.util.* +import dev.toastbits.composekit.components.utils.composable.* +import dev.toastbits.composekit.components.utils.modifier.* import com.toasterofbread.spmp.model.* import com.toasterofbread.spmp.model.mediaitem.* import com.toasterofbread.spmp.model.mediaitem.db.getPinnedItems @@ -29,6 +29,8 @@ import com.toasterofbread.spmp.ui.component.NotImplementedMessage import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import dev.toastbits.ytmkt.model.external.ItemLayoutType import dev.toastbits.ytmkt.uistrings.UiString +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.action_confirm_action @@ -56,26 +58,27 @@ internal fun SongFeedAppPage.LFFSongFeedAppPage( } val player: PlayerState = LocalPlayerState.current + val coroutine_scope: CoroutineScope = rememberCoroutineScope() val form_factor: FormFactor by FormFactor.observe() - val hidden_rows: Set by player.settings.feed.HIDDEN_ROWS.observe() + val hidden_rows: Set by player.settings.Feed.HIDDEN_ROWS.observe() val hidden_row_titles: List = hidden_rows.map { row_title -> UiString.deserialise(row_title).observe() } - val square_item_max_text_rows: Int by player.settings.feed.SQUARE_PREVIEW_TEXT_LINES.observe() - val show_download_indicators: Boolean by player.settings.feed.SHOW_SONG_DOWNLOAD_INDICATORS.observe() + val square_item_max_text_rows: Int by player.settings.Feed.SQUARE_PREVIEW_TEXT_LINES.observe() + val show_download_indicators: Boolean by player.settings.Feed.SHOW_SONG_DOWNLOAD_INDICATORS.observe() val grid_rows: Int by when (form_factor) { - FormFactor.PORTRAIT -> player.settings.feed.GRID_ROW_COUNT - FormFactor.LANDSCAPE -> player.settings.feed.LANDSCAPE_GRID_ROW_COUNT + FormFactor.PORTRAIT -> player.settings.Feed.GRID_ROW_COUNT + FormFactor.LANDSCAPE -> player.settings.Feed.LANDSCAPE_GRID_ROW_COUNT }.observe() val grid_rows_expanded: Int by when (form_factor) { - FormFactor.PORTRAIT -> player.settings.feed.GRID_ROW_COUNT_EXPANDED - FormFactor.LANDSCAPE -> player.settings.feed.LANDSCAPE_GRID_ROW_COUNT_EXPANDED + FormFactor.PORTRAIT -> player.settings.Feed.GRID_ROW_COUNT_EXPANDED + FormFactor.LANDSCAPE -> player.settings.Feed.LANDSCAPE_GRID_ROW_COUNT_EXPANDED }.observe() Column(modifier) { @@ -129,11 +132,13 @@ internal fun SongFeedAppPage.LFFSongFeedAppPage( onDismissRequest = { hiding_layout = null }, confirmButton = { Button({ - player.settings.feed.HIDDEN_ROWS.set( - hidden_rows.plus(title.serialise()) - ) + coroutine_scope.launch { + player.settings.Feed.HIDDEN_ROWS.set( + hidden_rows.plus(title.serialise()) + ) - hiding_layout = null + hiding_layout = null + } }) { Text(stringResource(Res.string.action_confirm_action)) } @@ -239,7 +244,7 @@ internal fun SongFeedAppPage.LFFSongFeedAppPage( } else if (requestContinuation != null) { IconButton({ requestContinuation() }) { - Icon(Icons.Filled.KeyboardDoubleArrowDown, null, tint = player.theme.on_background) + Icon(Icons.Filled.KeyboardDoubleArrowDown, null, tint = player.theme.onBackground) } } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/LFFSongFeedPagePrimaryBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/LFFSongFeedPagePrimaryBar.kt index ac5db21e1..c54469831 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/LFFSongFeedPagePrimaryBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/LFFSongFeedPagePrimaryBar.kt @@ -2,27 +2,44 @@ package com.toasterofbread.spmp.ui.layout.apppage.songfeedpage import LocalPlayerState import androidx.compose.animation.Crossfade -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material.icons.filled.FilterAlt +import androidx.compose.material.icons.filled.Person +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButtonColors +import androidx.compose.material3.IconButtonDefaults +import androidx.compose.material3.LocalContentColor +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalLayoutDirection -import androidx.compose.ui.unit.* -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.composable.* -import dev.toastbits.composekit.utils.modifier.horizontal -import com.toasterofbread.spmp.model.* -import com.toasterofbread.spmp.model.mediaitem.* +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.toasterofbread.spmp.model.getDisplayStringResource +import com.toasterofbread.spmp.model.getIcon +import com.toasterofbread.spmp.model.mediaitem.MediaItem +import com.toasterofbread.spmp.model.mediaitem.rememberFilteredYtmItems import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.LargeFilterList import com.toasterofbread.spmp.ui.component.mediaitempreview.MediaItemPreviewSquare import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.components.utils.composable.RowOrColumn +import dev.toastbits.composekit.components.utils.composable.ScrollableRowOrColumn +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.utils.modifier.horizontal +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.platform.Platform import org.jetbrains.compose.resources.stringResource @Composable @@ -67,8 +84,8 @@ internal fun SongFeedAppPage.LFFSongFeedPagePrimaryBar( ) { val selected_colours: IconButtonColors = IconButtonDefaults.iconButtonColors( - containerColor = player.theme.vibrant_accent.copy(alpha = 0.85f), - contentColor = player.theme.vibrant_accent.getContrasted() + containerColor = player.theme.vibrantAccent.copy(alpha = 0.85f), + contentColor = player.theme.vibrantAccent.getContrasted() ) ShapedIconButton( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SFFSongFeedAppPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SFFSongFeedAppPage.kt index 2d7e58bc8..da90a03d5 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SFFSongFeedAppPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SFFSongFeedAppPage.kt @@ -15,20 +15,18 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.platform.composable.SwipeRefresh -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator -import dev.toastbits.composekit.utils.modifier.horizontal -import dev.toastbits.composekit.utils.modifier.vertical +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.components.platform.composable.SwipeRefresh +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.util.platform.launchSingle +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.utils.modifier.horizontal +import dev.toastbits.composekit.components.utils.modifier.vertical import com.toasterofbread.spmp.model.deserialise import com.toasterofbread.spmp.model.getString -import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.layout.Layout import com.toasterofbread.spmp.model.mediaitem.layout.AppMediaItemLayout import com.toasterofbread.spmp.model.serialise -import dev.toastbits.ytmkt.model.external.mediaitem.MediaItemLayout import com.toasterofbread.spmp.model.MediaItemLayoutParams import com.toasterofbread.spmp.model.MediaItemGridParams import com.toasterofbread.spmp.model.observe @@ -39,8 +37,9 @@ import com.toasterofbread.spmp.service.playercontroller.FeedLoadState import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.NotImplementedMessage import dev.toastbits.ytmkt.model.external.ItemLayoutType -import dev.toastbits.ytmkt.model.external.mediaitem.YtmMediaItem import dev.toastbits.ytmkt.uistrings.UiString +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.action_confirm_action @@ -66,6 +65,7 @@ internal fun SongFeedAppPage.SFFSongFeedAppPage( } val player: PlayerState = LocalPlayerState.current + val coroutine_scope: CoroutineScope = rememberCoroutineScope() val form_factor: FormFactor by FormFactor.observe() var artists_layout: AppMediaItemLayout by remember { @@ -79,24 +79,24 @@ internal fun SongFeedAppPage.SFFSongFeedAppPage( ) } - val hidden_rows: Set by player.settings.feed.HIDDEN_ROWS.observe() + val hidden_rows: Set by player.settings.Feed.HIDDEN_ROWS.observe() val hidden_row_titles: List = hidden_rows.map { row_title -> UiString.deserialise(row_title).observe() } - val square_item_max_text_rows: Int by player.settings.feed.SQUARE_PREVIEW_TEXT_LINES.observe() - val show_download_indicators: Boolean by player.settings.feed.SHOW_SONG_DOWNLOAD_INDICATORS.observe() + val square_item_max_text_rows: Int by player.settings.Feed.SQUARE_PREVIEW_TEXT_LINES.observe() + val show_download_indicators: Boolean by player.settings.Feed.SHOW_SONG_DOWNLOAD_INDICATORS.observe() val grid_rows: Int by when (form_factor) { - FormFactor.PORTRAIT -> player.settings.feed.GRID_ROW_COUNT - FormFactor.LANDSCAPE -> player.settings.feed.LANDSCAPE_GRID_ROW_COUNT + FormFactor.PORTRAIT -> player.settings.Feed.GRID_ROW_COUNT + FormFactor.LANDSCAPE -> player.settings.Feed.LANDSCAPE_GRID_ROW_COUNT }.observe() val grid_rows_expanded: Int by when (form_factor) { - FormFactor.PORTRAIT -> player.settings.feed.GRID_ROW_COUNT_EXPANDED - FormFactor.LANDSCAPE -> player.settings.feed.LANDSCAPE_GRID_ROW_COUNT_EXPANDED + FormFactor.PORTRAIT -> player.settings.Feed.GRID_ROW_COUNT_EXPANDED + FormFactor.LANDSCAPE -> player.settings.Feed.LANDSCAPE_GRID_ROW_COUNT_EXPANDED }.observe() LaunchedEffect(Unit) { @@ -168,11 +168,13 @@ internal fun SongFeedAppPage.SFFSongFeedAppPage( onDismissRequest = { hiding_layout = null }, confirmButton = { Button({ - player.settings.feed.HIDDEN_ROWS.set( - hidden_rows.plus(title.serialise()) - ) + coroutine_scope.launch { + player.settings.Feed.HIDDEN_ROWS.set( + hidden_rows.plus(title.serialise()) + ) - hiding_layout = null + hiding_layout = null + } }) { Text(stringResource(Res.string.action_confirm_action)) } @@ -206,7 +208,7 @@ internal fun SongFeedAppPage.SFFSongFeedAppPage( else null val loading_continuation: Boolean = load_state != FeedLoadState.NONE val horizontal_padding: PaddingValues = content_padding.horizontal - val show_artists_row: Boolean by player.settings.feed.SHOW_ARTISTS_ROW.observe() + val show_artists_row: Boolean by player.settings.Feed.SHOW_ARTISTS_ROW.observe() LazyColumn( Modifier.graphicsLayer { alpha = state_alpha.value }, @@ -288,7 +290,7 @@ internal fun SongFeedAppPage.SFFSongFeedAppPage( } else if (requestContinuation != null) { IconButton({ requestContinuation() }) { - Icon(Icons.Filled.KeyboardDoubleArrowDown, null, tint = player.theme.on_background) + Icon(Icons.Filled.KeyboardDoubleArrowDown, null, tint = player.theme.onBackground) } } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SFFSongFeedPagePrimaryBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SFFSongFeedPagePrimaryBar.kt index f7bf97def..4abaed5b2 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SFFSongFeedPagePrimaryBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SFFSongFeedPagePrimaryBar.kt @@ -20,9 +20,9 @@ import com.toasterofbread.spmp.model.getDisplayStringResource import com.toasterofbread.spmp.model.getId import com.toasterofbread.spmp.model.getString import com.toasterofbread.spmp.model.observe -import dev.toastbits.composekit.platform.composable.ScrollBarLazyRow -import dev.toastbits.composekit.settings.ui.on_accent -import dev.toastbits.composekit.utils.composable.ScrollableRowOrColumn +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyRow +import dev.toastbits.composekit.theme.core.onAccent +import dev.toastbits.composekit.components.utils.composable.ScrollableRowOrColumn import org.jetbrains.compose.resources.stringResource @Composable @@ -58,13 +58,13 @@ internal fun SongFeedAppPage.SFFSongFeedPagePrimaryBar( colors = with(player.theme) { FilterChipDefaults.elevatedFilterChipColors( containerColor = background, - labelColor = on_background, + labelColor = onBackground, selectedContainerColor = accent, - selectedLabelColor = on_accent + selectedLabelColor = onAccent ) }, border = FilterChipDefaults.filterChipBorder( - borderColor = player.theme.on_background, + borderColor = player.theme.onBackground, enabled = true, selected = is_selected ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SongFeedAppPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SongFeedAppPage.kt index 624464a56..93f9cff7c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SongFeedAppPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SongFeedAppPage.kt @@ -10,9 +10,9 @@ import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.* import androidx.compose.ui.unit.* -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.composable.RowOrColumn +import dev.toastbits.composekit.util.* +import dev.toastbits.composekit.util.platform.launchSingle +import dev.toastbits.composekit.components.utils.composable.RowOrColumn import com.toasterofbread.spmp.model.* import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.artist.* @@ -175,7 +175,7 @@ class SongFeedAppPage(override val state: AppPageState): AppPage() { load_state = if (continue_feed) FeedLoadState.CONTINUING else FeedLoadState.LOADING val result: Result = loadFeedLayouts( - if (continue_feed && continuation != null) -1 else state.context.settings.feed.INITIAL_ROWS.get(), + if (continue_feed && continuation != null) -1 else state.context.settings.Feed.INITIAL_ROWS.get(), filter_params, if (continue_feed) continuation else null ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SongFeedPageLoadingView.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SongFeedPageLoadingView.kt index 2d4cab202..1ae57a9d5 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SongFeedPageLoadingView.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/apppage/songfeedpage/SongFeedPageLoadingView.kt @@ -5,7 +5,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.loading_feed @@ -14,6 +14,6 @@ import spmp.shared.generated.resources.loading_feed internal fun SongFeedPageLoadingView(modifier: Modifier = Modifier) { val player = LocalPlayerState.current Box(modifier, contentAlignment = Alignment.Center) { - SubtleLoadingIndicator(message = stringResource(Res.string.loading_feed), getColour = { player.theme.on_background }) + SubtleLoadingIndicator(message = stringResource(Res.string.loading_feed), getColour = { player.theme.onBackground }) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistActionBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistActionBar.kt index bc9abb3bb..3d805382f 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistActionBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistActionBar.kt @@ -41,14 +41,14 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.platform.composable.ScrollabilityIndicatorRow -import dev.toastbits.composekit.utils.composable.ShapedIconButton -import dev.toastbits.composekit.utils.modifier.vertical +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.platform.composable.ScrollabilityIndicatorRow +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.utils.modifier.vertical import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.observeUrl import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.theme.core.vibrantAccent import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.artist_chip_shuffle @@ -97,12 +97,12 @@ fun ArtistActionBar( { Text(text, style = MaterialTheme.typography.labelLarge) }, Modifier.height(height), leadingIcon = { - Icon(icon, null, tint = accent_colour ?: player.theme.vibrant_accent) + Icon(icon, null, tint = accent_colour ?: player.theme.vibrantAccent) }, colors = AssistChipDefaults.assistChipColors( containerColor = player.theme.background, - labelColor = player.theme.on_background, - leadingIconContentColor = accent_colour ?: player.theme.vibrant_accent + labelColor = player.theme.onBackground, + leadingIconContentColor = accent_colour ?: player.theme.vibrantAccent ) ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistAppPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistAppPage.kt index 9ee61db32..27336940a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistAppPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistAppPage.kt @@ -10,7 +10,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.util.platform.launchSingle import com.toasterofbread.spmp.model.mediaitem.MediaItemHolder import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.loader.MediaItemLoader diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistLayout.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistLayout.kt index 7d490fffb..e156cc70b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistLayout.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistLayout.kt @@ -1,13 +1,10 @@ package com.toasterofbread.spmp.ui.layout.artistpage import LocalPlayerState -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -29,30 +26,26 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex -import dev.toastbits.composekit.platform.composable.SwipeRefresh -import dev.toastbits.composekit.utils.common.getThemeColour -import dev.toastbits.composekit.utils.composable.getTop -import dev.toastbits.composekit.utils.modifier.background -import dev.toastbits.composekit.utils.modifier.brushBackground -import dev.toastbits.composekit.utils.modifier.drawScopeBackground -import dev.toastbits.composekit.utils.modifier.horizontal import com.toasterofbread.spmp.model.mediaitem.MediaItem -import dev.toastbits.ytmkt.model.external.ThumbnailProvider import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.loader.MediaItemThumbnailLoader +import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.Thumbnail -import com.toasterofbread.spmp.ui.component.WaveBorder import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import com.toasterofbread.spmp.ui.component.multiselect.MultiSelectItem -import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.settings.ui.makeVibrant +import dev.toastbits.composekit.components.platform.composable.SwipeRefresh +import dev.toastbits.composekit.components.utils.modifier.background +import dev.toastbits.composekit.components.utils.modifier.brushBackground +import dev.toastbits.composekit.components.utils.modifier.horizontal +import dev.toastbits.composekit.theme.core.makeVibrant +import dev.toastbits.composekit.util.getThemeColour +import dev.toastbits.ytmkt.model.external.ThumbnailProvider private const val ARTIST_IMAGE_SCROLL_MODIFIER = 0.25f diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistPageTitleBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistPageTitleBar.kt index ce6ff51dd..50d5c89da 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistPageTitleBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/ArtistPageTitleBar.kt @@ -46,15 +46,15 @@ import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.composable.WidthShrinkText +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.util.composable.WidthShrinkText import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.artist.toReadableSubscriberCount import com.toasterofbread.spmp.model.mediaitem.db.observePinnedToHome import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField -import dev.toastbits.composekit.settings.ui.on_accent +import dev.toastbits.composekit.theme.core.onAccent import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.`edit_$x_title_dialog_title` @@ -89,7 +89,7 @@ fun ArtistPageTitleBar(item: MediaItem, modifier: Modifier = Modifier) { .clickable(onClick = action), contentAlignment = Alignment.Center ) { - Icon(icon, null, tint = player.theme.on_accent) + Icon(icon, null, tint = player.theme.onAccent) } } @@ -103,7 +103,7 @@ fun ArtistPageTitleBar(item: MediaItem, modifier: Modifier = Modifier) { } } - val field_colour: Color = player.theme.on_accent + val field_colour: Color = player.theme.onAccent OutlinedTextField( edited_title, onValueChange = { text -> diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/DescriptionCard.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/DescriptionCard.kt index 38a5ebf13..2fd4fdf9c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/DescriptionCard.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/DescriptionCard.kt @@ -11,8 +11,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.utils.common.blendWith -import dev.toastbits.composekit.utils.composable.LinkifyText +import dev.toastbits.composekit.util.blendWith +import dev.toastbits.composekit.components.utils.composable.LinkifyText @Composable fun DescriptionCard(description_text: String) { @@ -29,9 +29,9 @@ fun DescriptionCard(description_text: String) { LinkifyText( description_text, modifier = Modifier.padding(10.dp), - highlight_colour = player.theme.on_background, + highlight_colour = player.theme.onBackground, style = MaterialTheme.typography.bodyMedium.copy( - color = player.theme.on_background.copy(alpha = 0.8f) + color = player.theme.onBackground.copy(alpha = 0.8f) ) ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/InfoDialog.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/InfoDialog.kt index 9ad8e7aa4..e3a4b0b17 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/InfoDialog.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/InfoDialog.kt @@ -30,7 +30,7 @@ import com.toasterofbread.spmp.model.mediaitem.observeUrl import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylist import com.toasterofbread.spmp.resources.stringResourceTODO import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.utils.composable.Marquee +import dev.toastbits.composekit.components.utils.composable.Marquee import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.action_close diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/LocalArtistPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/LocalArtistPage.kt index c9831192b..241205723 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/LocalArtistPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/LocalArtistPage.kt @@ -14,8 +14,8 @@ import androidx.compose.runtime.setValue import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.modifier.horizontal +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.components.utils.modifier.horizontal import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.artist.ArtistRef diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/SFFArtistPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/SFFArtistPage.kt index 7a60ae2d9..90a4f7274 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/SFFArtistPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/SFFArtistPage.kt @@ -13,17 +13,14 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.* import androidx.compose.ui.text.* import androidx.compose.ui.unit.* -import dev.toastbits.composekit.utils.* -import dev.toastbits.composekit.utils.common.copy -import dev.toastbits.composekit.utils.composable.* -import dev.toastbits.composekit.utils.modifier.horizontal +import dev.toastbits.composekit.components.utils.composable.* +import dev.toastbits.composekit.components.utils.modifier.horizontal import com.toasterofbread.spmp.model.* import com.toasterofbread.spmp.model.mediaitem.* import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.artist.ArtistLayout import com.toasterofbread.spmp.model.mediaitem.layout.Layout import com.toasterofbread.spmp.model.mediaitem.layout.AppMediaItemLayout -import dev.toastbits.ytmkt.model.external.mediaitem.MediaItemLayout import com.toasterofbread.spmp.model.mediaitem.loader.MediaItemLoader import com.toasterofbread.spmp.model.mediaitem.playlist.Playlist import com.toasterofbread.spmp.model.mediaitem.song.Song @@ -36,7 +33,7 @@ import com.toasterofbread.spmp.ui.component.longpressmenu.LongPressMenuData import com.toasterofbread.spmp.ui.component.mediaitemlayout.MediaItemList import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.platform.assert +import dev.toastbits.composekit.util.composable.copy import dev.toastbits.ytmkt.endpoint.ArtistWithParamsRow import dev.toastbits.ytmkt.model.external.ItemLayoutType import dev.toastbits.ytmkt.uistrings.RawUiString @@ -55,7 +52,7 @@ internal fun ArtistAppPage.SFFArtistPage( val click_overrides: PlayerClickOverrides = LocalPlayerClickOverrides.current val own_multiselect_context = remember(multiselect_context) { if (multiselect_context != null) null else MediaItemMultiSelectContext(player.context) {} } - val apply_filter: Boolean by player.settings.filter.APPLY_TO_ARTIST_ITEMS.observe() + val apply_filter: Boolean by player.settings.Filter.APPLY_TO_ARTIST_ITEMS.observe() val item_layouts: List? by artist.Layouts.observe(player.database) var browse_params_rows: List? by remember { mutableStateOf(null) } @@ -152,7 +149,7 @@ internal fun ArtistAppPage.SFFArtistPage( val layout_id: YoutubeUILocalisation.StringID? = (layout.title as? YoutubeUiString)?.getYoutubeStringId() val is_singles: Boolean = - player.settings.behaviour.TREAT_SINGLES_AS_SONG.observe().value + player.settings.Behaviour.TREAT_SINGLES_AS_SONG.observe().value && layout_id == YoutubeUILocalisation.StringID.ARTIST_ROW_SINGLES val is_artist_row: Boolean = diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/SubscribeButton.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/SubscribeButton.kt index 4659cbcfb..539a871be 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/SubscribeButton.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/SubscribeButton.kt @@ -15,14 +15,13 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.ShapedIconButton -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.artist.updateSubscribed import com.toasterofbread.spmp.model.mediaitem.loader.ArtistSubscribedLoader import com.toasterofbread.spmp.resources.getStringTODO -import dev.toastbits.composekit.platform.assert import kotlinx.coroutines.launch @Composable diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LFFArtistPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LFFArtistPage.kt index 8a079742a..5e9fa8dfc 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LFFArtistPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LFFArtistPage.kt @@ -11,30 +11,21 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.getThemeColour -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.composable.OnChangedEffect -import com.toasterofbread.spmp.model.mediaitem.MediaItem +import dev.toastbits.composekit.util.getThemeColour import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.artist.ArtistLayout -import com.toasterofbread.spmp.model.mediaitem.loader.MediaItemLoader import com.toasterofbread.spmp.model.mediaitem.loader.MediaItemThumbnailLoader -import com.toasterofbread.spmp.model.mediaitem.loader.loadDataOnChange import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.artistpage.ArtistAppPage -import dev.toastbits.composekit.platform.assert -import dev.toastbits.composekit.settings.ui.makeVibrant -import dev.toastbits.composekit.settings.ui.vibrant_accent -import dev.toastbits.ytmkt.endpoint.ArtistWithParamsEndpoint +import dev.toastbits.composekit.theme.core.makeVibrant +import dev.toastbits.composekit.theme.core.vibrantAccent import dev.toastbits.ytmkt.endpoint.ArtistWithParamsRow -import kotlinx.coroutines.CoroutineScope @Composable internal fun ArtistAppPage.LFFArtistPage( @@ -46,13 +37,13 @@ internal fun ArtistAppPage.LFFArtistPage( val player: PlayerState = LocalPlayerState.current val own_multiselect_context: MediaItemMultiSelectContext? = remember(multiselect_context) { if (multiselect_context != null) null else MediaItemMultiSelectContext(player.context) {} } - val apply_filter: Boolean by player.settings.filter.APPLY_TO_ARTIST_ITEMS.observe() + val apply_filter: Boolean by player.settings.Filter.APPLY_TO_ARTIST_ITEMS.observe() val item_layouts: List? by artist.Layouts.observe(player.database) var browse_params_rows: List? by remember { mutableStateOf(null) } var accent_colour: Color? by remember { mutableStateOf(null) } - val current_accent_colour: Color = accent_colour ?: player.theme.vibrant_accent + val current_accent_colour: Color = accent_colour ?: player.theme.vibrantAccent val thumbnail_load_state: MediaItemThumbnailLoader.ItemState = MediaItemThumbnailLoader.rememberItemState(artist) val thumbnail: ImageBitmap? = thumbnail_load_state.getHighestQuality() diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LLFArtistPageEndPane.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LLFArtistPageEndPane.kt index eddf14ef9..3ac2ae4a9 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LLFArtistPageEndPane.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LLFArtistPageEndPane.kt @@ -13,15 +13,13 @@ import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex -import dev.toastbits.composekit.platform.composable.ScrollBarLazyColumn -import dev.toastbits.composekit.utils.common.copy -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator -import dev.toastbits.composekit.utils.modifier.vertical -import com.toasterofbread.spmp.model.mediaitem.MediaItemRef +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyColumn +import dev.toastbits.composekit.util.composable.copy +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.utils.modifier.vertical import com.toasterofbread.spmp.model.mediaitem.artist.ArtistLayout import com.toasterofbread.spmp.model.mediaitem.layout.Layout import com.toasterofbread.spmp.model.mediaitem.layout.AppMediaItemLayout -import dev.toastbits.ytmkt.model.external.mediaitem.MediaItemLayout import com.toasterofbread.spmp.model.mediaitem.playlist.Playlist import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.mediaitem.toMediaItemRef @@ -148,7 +146,7 @@ internal fun ArtistAppPage.LFFArtistEndPane( } val is_singles: Boolean = - player.settings.behaviour.TREAT_SINGLES_AS_SONG.observe().value + player.settings.Behaviour.TREAT_SINGLES_AS_SONG.observe().value && layout_id == YoutubeUILocalisation.StringID.ARTIST_ROW_SINGLES val is_artist_row: Boolean = diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LLFArtistPageStartPane.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LLFArtistPageStartPane.kt index edc47890b..cdf1999b0 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LLFArtistPageStartPane.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/artistpage/lff/LLFArtistPageStartPane.kt @@ -31,12 +31,12 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.platform.composable.PlatformTextField -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.utils.common.blendWith -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.LinkifyText -import dev.toastbits.composekit.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.platform.composable.PlatformTextField +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.util.blendWith +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.composable.LinkifyText +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton import dev.toastbits.ytmkt.model.external.ThumbnailProvider import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.artist.ArtistLayout diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBar.kt index 6ad08261f..433e2f291 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBar.kt @@ -15,12 +15,12 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.compositeOver import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.getContrasted +import dev.toastbits.composekit.util.getContrasted import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.contentbar.ContentBarReference import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.* import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.ColourSource -import dev.toastbits.composekit.settings.ui.ThemeValues +import dev.toastbits.composekit.theme.core.ThemeValues import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement import kotlinx.serialization.Serializable @@ -75,7 +75,7 @@ sealed class ContentBar { @Composable abstract fun BarContent( slot: LayoutSlot, - background_colour: ThemeValues.Colour?, + background_colour: ThemeValues.Slot?, content_padding: PaddingValues, distance_to_page: Dp, lazy: Boolean, @@ -95,10 +95,16 @@ sealed class ContentBar { } companion object { - var _bar_selection_state: BarSelectionState? by mutableStateOf(null) - var bar_selection_state: BarSelectionState? - get() = if (disable_bar_selection) null else _bar_selection_state - set(value) { _bar_selection_state = value } + private var _bar_selection_states: MutableList = mutableStateListOf() + val bar_selection_state: BarSelectionState? + get() = _bar_selection_states.lastOrNull() + + fun addBarSelectionState(state: BarSelectionState) { + _bar_selection_states.add(state) + } + fun removeBarSelectionState(state: BarSelectionState) { + _bar_selection_states.remove(state) + } var disable_bar_selection: Boolean by mutableStateOf(false) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBarElementSelector.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBarElementSelector.kt index cf7b57b77..6c3e73fb2 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBarElementSelector.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBarElementSelector.kt @@ -20,7 +20,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.platform.FormFactor import com.toasterofbread.spmp.ui.layout.contentbar.element.ContentBarElement -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.content_bar_editor_add_element @@ -37,23 +37,23 @@ internal fun ContentBarElementSelector( val available_elements: List = ContentBarElement.Type.entries.filter { it.isAvailable() } LargeDropdownMenu( - show_element_selector, - { show_element_selector = false }, - available_elements.size, - null, - { - val element: ContentBarElement.Type = available_elements[it] - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(10.dp) - ) { - Icon(element.getIcon(), null) - Text(element.getName(), softWrap = false) - } + title = stringResource(Res.string.content_bar_editor_add_element), + isOpen = show_element_selector, + onDismissRequest = { show_element_selector = false }, + items = available_elements, + selectedItem = null, + onSelected = { _, item -> + onSelected(item) + show_element_selector = false + } + ) { element -> + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(10.dp) + ) { + Icon(element.getIcon(), null) + Text(element.getName(), softWrap = false) } - ) { - onSelected(available_elements[it]) - show_element_selector = false } if (!show_element_buttons) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBarSelector.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBarSelector.kt index f1d7c1092..9b8ce45af 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBarSelector.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/ContentBarSelector.kt @@ -23,34 +23,30 @@ import androidx.compose.ui.graphics.* import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.* -import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.platform.composable.* -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.modifier.background -import dev.toastbits.composekit.utils.composable.NoRipple +import dev.toastbits.composekit.components.platform.composable.* +import dev.toastbits.composekit.util.* +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.modifier.background +import dev.toastbits.composekit.components.utils.composable.NoRipple import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.* -import com.toasterofbread.spmp.ui.layout.contentbar.ContentBar import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.observeContentBar import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.ColourSource import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.rememberColourSource import com.toasterofbread.spmp.ui.layout.nowplaying.maintab.vertical import com.toasterofbread.spmp.ui.theme.appHover -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.theme.core.readableName +import dev.toastbits.composekit.theme.core.vibrantAccent import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.Json import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.action_close import spmp.shared.generated.resources.content_bar_empty import spmp.shared.generated.resources.action_cancel -import spmp.shared.generated.resources.content_bar_empty import spmp.shared.generated.resources.content_bar_selection import spmp.shared.generated.resources.content_bar_selection_list_built_in import spmp.shared.generated.resources.content_bar_selection_list_custom @@ -90,7 +86,7 @@ internal fun ContentBarSelector( .fillMaxSize() .background(player.theme.background) .padding(content_padding) - .border(1.dp, player.theme.vibrant_accent) + .border(1.dp, player.theme.vibrantAccent) .padding(base_content_padding) ) { CompositionLocalProvider(LocalContentColor provides player.theme.background.getContrasted()) { @@ -128,7 +124,7 @@ internal fun ContentBarSelector( Icon(Icons.Default.Palette, null, rotate_modifier) slot_colour_source.theme_colour?.also { - Text(it.getReadable(), lineHeight = 10.sp) + Text(it.readableName, lineHeight = 10.sp) } } @@ -264,7 +260,7 @@ private fun BarSelectorPopup( onDismissed, colors = ButtonDefaults.buttonColors( containerColor = player.theme.background, - contentColor = player.theme.on_background + contentColor = player.theme.onBackground ), modifier = Modifier.appHover(true) ) { @@ -321,7 +317,7 @@ internal fun CustomBarsContentBarList( stringResource(Res.string.content_bar_selection_list_custom), modifier, topContent = { - val background_colour: Color = player.theme.vibrant_accent + val background_colour: Color = player.theme.vibrantAccent CompositionLocalProvider(LocalContentColor provides background_colour.getContrasted()) { ContentBarPreview( stringResource(Res.string.content_bar_selection_create_new), @@ -380,7 +376,7 @@ internal fun ContentBarList( onSelected: ((Int) -> Unit)? ) { val player: PlayerState = LocalPlayerState.current - val custom_bars: List by player.settings.layout.CUSTOM_BARS.observe() + val custom_bars: List by player.settings.Layout.CUSTOM_BARS.observe() val bars: List = remember(bar_references, custom_bars) { bar_references.mapNotNull { it.getBar(custom_bars) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBar.kt index ae0b9643f..a3328a741 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBar.kt @@ -10,16 +10,15 @@ import androidx.compose.ui.* import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.* -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.composable.* import com.toasterofbread.spmp.service.playercontroller.PlayerState -import com.toasterofbread.spmp.ui.layout.apppage.AppPage import com.toasterofbread.spmp.ui.layout.contentbar.element.* import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot -import dev.toastbits.composekit.settings.ui.ThemeValues -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.components.utils.composable.* +import dev.toastbits.composekit.theme.core.ThemeValues +import dev.toastbits.composekit.theme.core.get +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.* import kotlinx.serialization.* -import kotlinx.serialization.json.Json const val CUSTOM_CONTENT_BAR_DEFAULT_SIZE_DP: Float = 50f @@ -57,7 +56,7 @@ data class CustomContentBar( @Composable override fun BarContent( slot: LayoutSlot, - background_colour: ThemeValues.Colour?, + background_colour: ThemeValues.Slot?, content_padding: PaddingValues, distance_to_page: Dp, lazy: Boolean, @@ -70,7 +69,7 @@ data class CustomContentBar( internal fun CustomBarContent( vertical: Boolean, content_padding: PaddingValues, - background_colour: ThemeValues.Colour? = null, + background_colour: ThemeValues.Slot? = null, modifier: Modifier = Modifier, selected_element_override: Int? = null, apply_size: Boolean = true, @@ -112,7 +111,7 @@ internal fun CustomBarContent( vertical: Boolean, content_padding: PaddingValues, slot: LayoutSlot? = null, - background_colour: ThemeValues.Colour? = null, + background_colour: ThemeValues.Slot? = null, modifier: Modifier = Modifier, selected_element_override: Int? = null, apply_size: Boolean = true, @@ -135,10 +134,10 @@ internal fun CustomBarContent( val content_colour: Color = LocalContentColor.current val indicator_colour: Color = when (background_colour) { - ThemeValues.Colour.BACKGROUND -> player.theme.vibrant_accent - ThemeValues.Colour.CARD -> player.theme.vibrant_accent - ThemeValues.Colour.ACCENT -> player.theme.background - ThemeValues.Colour.VIBRANT_ACCENT -> player.theme.background + ThemeValues.Slot.BuiltIn.BACKGROUND -> player.theme.vibrantAccent + ThemeValues.Slot.BuiltIn.CARD -> player.theme.vibrantAccent + ThemeValues.Slot.BuiltIn.ACCENT -> player.theme.background + ThemeValues.Slot.Extension.VIBRANT_ACCENT -> player.theme.background else -> content_colour } @@ -183,7 +182,7 @@ internal fun CustomBarContent( CompositionLocalProvider( LocalContentColor provides if (index == selected_element) indicator_colour.getContrasted() - else background_colour?.get(player.theme)?.getContrasted() ?: LocalContentColor.current + else background_colour?.let { player.theme[it] }?.getContrasted() ?: LocalContentColor.current ) { buttonContent(index, element, DpSize(this@BoxWithConstraints.maxWidth, this@BoxWithConstraints.maxHeight)) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarCopyPasteButtons.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarCopyPasteButtons.kt index 9b29ba76e..0379de18a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarCopyPasteButtons.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarCopyPasteButtons.kt @@ -8,7 +8,7 @@ import androidx.compose.ui.platform.* import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.Modifier import androidx.compose.runtime.* -import dev.toastbits.composekit.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton import com.toasterofbread.spmp.service.playercontroller.PlayerState import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -25,7 +25,7 @@ internal fun CustomContentBarCopyPasteButtons( val colours: IconButtonColors = IconButtonDefaults.iconButtonColors( containerColor = player.theme.background, - contentColor = player.theme.on_background + contentColor = player.theme.onBackground ) ShapedIconButton( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarEditor.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarEditor.kt index cf5c27876..f308a0fba 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarEditor.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarEditor.kt @@ -14,15 +14,17 @@ import androidx.compose.ui.draw.rotate import androidx.compose.ui.layout.* import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.* -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.composable.* +import dev.toastbits.composekit.util.* +import dev.toastbits.composekit.components.utils.composable.* import com.toasterofbread.spmp.platform.* import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField import com.toasterofbread.spmp.ui.layout.contentbar.element.* import com.toasterofbread.spmp.ui.layout.nowplaying.maintab.vertical -import dev.toastbits.composekit.settings.ui.ThemeValues -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.components.utils.composable.animatedvisibility.NullableValueAnimatedVisibility +import dev.toastbits.composekit.theme.core.ThemeValues +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.composable.WidthShrinkText import kotlin.math.roundToInt import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res @@ -126,11 +128,11 @@ internal abstract class CustomContentBarEditor() { vertical_bar, Modifier .fillMaxWidth() - .background(player.theme.vibrant_accent.copy(alpha = 0.25f), RoundedCornerShape(16.dp)) + .background(player.theme.vibrantAccent.copy(alpha = 0.25f), RoundedCornerShape(16.dp)) .padding(15.dp), alignment = -1 ) { - CompositionLocalProvider(LocalContentColor provides player.theme.on_background) { + CompositionLocalProvider(LocalContentColor provides player.theme.onBackground) { if (vertical_bar) { var column_height: Dp by remember { mutableStateOf(0.dp) } BarPreview( @@ -190,7 +192,7 @@ internal abstract class CustomContentBarEditor() { .background(player.theme.background, RoundedCornerShape(16.dp)) .padding(10.dp) ) { - CompositionLocalProvider(LocalContentColor provides player.theme.on_background) { + CompositionLocalProvider(LocalContentColor provides player.theme.onBackground) { ElementEditor( element, element_index, @@ -219,7 +221,7 @@ internal abstract class CustomContentBarEditor() { val player: PlayerState = LocalPlayerState.current val button_colours: ButtonColors = ButtonDefaults.buttonColors( containerColor = player.theme.background, - contentColor = player.theme.on_background + contentColor = player.theme.onBackground ) FlowRow( @@ -281,7 +283,7 @@ internal abstract class CustomContentBarEditor() { bar.CustomBarContent( scrolling = !vertical_bar, vertical = vertical_bar, - background_colour = ThemeValues.Colour.BACKGROUND, + background_colour = ThemeValues.Slot.BuiltIn.BACKGROUND, content_padding = PaddingValues(), apply_size = false, always_display = true, @@ -295,9 +297,9 @@ internal abstract class CustomContentBarEditor() { getSpacerElementModifier = { index, spacer -> with(spacer) { Modifier .clickable { onElementClicked(index) } - .border(2.dp, player.theme.vibrant_accent) + .border(2.dp, player.theme.vibrantAccent) .thenIf(index == selected_element) { - background(player.theme.vibrant_accent) + background(player.theme.vibrantAccent) } }}, shouldShowButton = { true }, @@ -339,7 +341,7 @@ internal abstract class CustomContentBarEditor() { .thenIf(vertical_bar) { rotate(-90f).vertical().padding(horizontal = 10.dp) }, - color = player.theme.on_background + color = player.theme.onBackground ) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarTemplate.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarTemplate.kt index b18fd007a..2fb5a1672 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarTemplate.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/CustomContentBarTemplate.kt @@ -12,14 +12,14 @@ import androidx.compose.runtime.* import androidx.compose.ui.* import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.* -import dev.toastbits.composekit.platform.composable.platformClickable +import dev.toastbits.composekit.components.platform.composable.platformClickable import com.toasterofbread.spmp.model.appaction.* import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.apppage.AppPage import com.toasterofbread.spmp.ui.layout.contentbar.element.* import com.toasterofbread.spmp.ui.theme.appHover -import dev.toastbits.composekit.settings.ui.ThemeValues -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.theme.core.ThemeValues +import dev.toastbits.composekit.theme.core.vibrantAccent import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.content_bar_template_navigation @@ -153,8 +153,8 @@ enum class CustomContentBarTemplate { } bar.CustomBarContent( - modifier = Modifier.background(player.theme.vibrant_accent, RoundedCornerShape(16.dp)), - background_colour = ThemeValues.Colour.VIBRANT_ACCENT, + modifier = Modifier.background(player.theme.vibrantAccent, RoundedCornerShape(16.dp)), + background_colour = ThemeValues.Slot.Extension.VIBRANT_ACCENT, vertical = false, always_display = true, content_padding = PaddingValues(5.dp), @@ -178,7 +178,7 @@ enum class CustomContentBarTemplate { { onSelected(null) }, colors = ButtonDefaults.buttonColors( containerColor = player.theme.background, - contentColor = player.theme.on_background + contentColor = player.theme.onBackground ), modifier = Modifier.appHover(true) ) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/InternalContentBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/InternalContentBar.kt index ccd024087..d7561ffb9 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/InternalContentBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/InternalContentBar.kt @@ -10,7 +10,7 @@ import androidx.compose.foundation.layout.PaddingValues import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot import com.toasterofbread.spmp.ui.layout.apppage.AppPage import LocalPlayerState -import dev.toastbits.composekit.settings.ui.ThemeValues +import dev.toastbits.composekit.theme.core.ThemeValues import kotlinx.serialization.Serializable import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res @@ -43,7 +43,7 @@ private class PrimaryInternalContentBar(index: Int): InternalContentBar(index) { @Composable override fun BarContent( slot: LayoutSlot, - background_colour: ThemeValues.Colour?, + background_colour: ThemeValues.Slot?, content_padding: PaddingValues, distance_to_page: Dp, lazy: Boolean, @@ -75,7 +75,7 @@ private class SecondaryInternalContentBar(index: Int): InternalContentBar(index) @Composable override fun BarContent( slot: LayoutSlot, - background_colour: ThemeValues.Colour?, + background_colour: ThemeValues.Slot?, content_padding: PaddingValues, distance_to_page: Dp, lazy: Boolean, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/TemplateCustomContentBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/TemplateCustomContentBar.kt index ac885c61b..d9c16009e 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/TemplateCustomContentBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/TemplateCustomContentBar.kt @@ -7,7 +7,7 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.* import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot import com.toasterofbread.spmp.ui.layout.contentbar.element.ContentBarElement -import dev.toastbits.composekit.settings.ui.ThemeValues +import dev.toastbits.composekit.theme.core.ThemeValues data class TemplateCustomContentBar( val template: CustomContentBarTemplate @@ -27,7 +27,7 @@ data class TemplateCustomContentBar( @Composable override fun BarContent( slot: LayoutSlot, - background_colour: ThemeValues.Colour?, + background_colour: ThemeValues.Slot?, content_padding: PaddingValues, distance_to_page: Dp, lazy: Boolean, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElement.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElement.kt index 012b03869..82c6fe8de 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElement.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElement.kt @@ -9,8 +9,8 @@ import androidx.compose.runtime.* import androidx.compose.ui.* import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.* -import dev.toastbits.composekit.utils.common.thenWith -import dev.toastbits.composekit.utils.composable.* +import dev.toastbits.composekit.util.thenWith +import dev.toastbits.composekit.components.utils.composable.* import com.toasterofbread.spmp.platform.visualiser.MusicVisualiser import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot import com.toasterofbread.spmp.ui.layout.contentbar.ContentBarReference @@ -107,22 +107,23 @@ sealed class ContentBarElement { var show_mode_selector: Boolean by remember { mutableStateOf(false) } LargeDropdownMenu( - show_mode_selector, + title = stringResource(Res.string.content_bar_element_builtin_config_size_mode), + isOpen = show_mode_selector, onDismissRequest = { show_mode_selector = false }, - SizeMode.entries.size, - config.size_mode.ordinal, - { - Text(SizeMode.entries[it].getName()) + items = SizeMode.entries, + selectedItem = config.size_mode, + onSelected = { _, mode -> + onModification( + copyWithConfig(config.copy( + size_mode = mode, size = 50 + )) + ) + show_mode_selector = false } - ) { - onModification( - copyWithConfig(config.copy( - size_mode = SizeMode.entries[it], size = 50 - )) - ) - show_mode_selector = false + ) { mode -> + Text(mode.getName()) } FlowRow( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementButton.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementButton.kt index d8f5055ed..984b19b40 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementButton.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementButton.kt @@ -24,9 +24,9 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.* import androidx.compose.ui.unit.dp import androidx.compose.ui.Alignment -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.utils.common.getValue -import dev.toastbits.composekit.utils.composable.* +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.components.utils.composable.* import com.toasterofbread.spmp.model.mediaitem.artist.Artist import com.toasterofbread.spmp.model.mediaitem.artist.ArtistRef import com.toasterofbread.spmp.model.appaction.AppAction @@ -148,15 +148,16 @@ data class ContentBarElementButton( var show_type_selector: Boolean by remember { mutableStateOf(false) } LargeDropdownMenu( - expanded = show_type_selector, + title = stringResource(Res.string.content_bar_element_button_config_type), + isOpen = show_type_selector, onDismissRequest = { show_type_selector = false }, - item_count = AppAction.Type.entries.size, - selected = action.getType().ordinal, - itemContent = { - AppAction.Type.entries[it].Preview() + items = AppAction.Type.entries, + selectedItem = action.getType(), + itemContent = { action -> + action.Preview() }, - onSelected = { - onModification(copy(action = AppAction.Type.entries[it].createAction())) + onSelected = { _, action -> + onModification(copy(action = action.createAction())) show_type_selector = false } ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementContentBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementContentBar.kt index cd94b96ec..856e5af1b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementContentBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementContentBar.kt @@ -2,8 +2,6 @@ package com.toasterofbread.spmp.ui.layout.contentbar.element import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.Box import androidx.compose.material3.* import androidx.compose.material3.Icon @@ -15,11 +13,9 @@ import androidx.compose.ui.unit.DpSize import androidx.compose.ui.Alignment import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.TableRows -import com.toasterofbread.spmp.ui.component.PinnedItemsList import com.toasterofbread.spmp.ui.layout.contentbar.ContentBarReference import com.toasterofbread.spmp.ui.layout.contentbar.InternalContentBar import com.toasterofbread.spmp.ui.layout.contentbar.ContentBar -import com.toasterofbread.spmp.ui.layout.contentbar.CustomContentBarTemplate import com.toasterofbread.spmp.ui.layout.contentbar.ContentBarList import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot import com.toasterofbread.spmp.ui.theme.appHover @@ -51,7 +47,7 @@ data class ContentBarElementContentBar( @Composable override fun isDisplaying(): Boolean { val player: PlayerState = LocalPlayerState.current - val custom_bars: List by player.settings.layout.CUSTOM_BARS.observe() + val custom_bars: List by player.settings.Layout.CUSTOM_BARS.observe() val content_bar: ContentBar? = remember(bar) { bar.getBar(custom_bars) } return content_bar?.isDisplaying() == true } @@ -72,7 +68,7 @@ data class ContentBarElementContentBar( } val player: PlayerState = LocalPlayerState.current - val custom_bars: List by player.settings.layout.CUSTOM_BARS.observe() + val custom_bars: List by player.settings.Layout.CUSTOM_BARS.observe() val content_bar: ContentBar? = remember(bar) { bar.getBar(custom_bars) } content_bar?.BarContent( slot = slot, @@ -87,7 +83,7 @@ data class ContentBarElementContentBar( @Composable override fun SubConfigurationItems(item_modifier: Modifier, onModification: (ContentBarElement) -> Unit) { val player: PlayerState = LocalPlayerState.current - val custom_bars: List by player.settings.layout.CUSTOM_BARS.observe() + val custom_bars: List by player.settings.Layout.CUSTOM_BARS.observe() val content_bar: ContentBar = remember(bar) { bar.getBar(custom_bars)!! } var show_bar_selector: Boolean by remember { mutableStateOf(false) } @@ -105,7 +101,7 @@ data class ContentBarElementContentBar( { show_bar_selector = false }, colors = ButtonDefaults.buttonColors( containerColor = player.theme.background, - contentColor = player.theme.on_background + contentColor = player.theme.onBackground ), modifier = Modifier.appHover(true) ) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementCrossfade.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementCrossfade.kt index 5d9f566d5..a24f3e1ec 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementCrossfade.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementCrossfade.kt @@ -42,9 +42,9 @@ import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot import com.toasterofbread.spmp.ui.layout.contentbar.ContentBarReference import com.toasterofbread.spmp.ui.layout.contentbar.ContentBarElementSelector import com.toasterofbread.spmp.ui.theme.appHover -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.platform.PlatformContext -import dev.toastbits.composekit.utils.composable.AlignableCrossfade +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.context.PlatformContext +import dev.toastbits.composekit.util.composable.AlignableCrossfade import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.content_bar_element_content_bar_config_bar @@ -148,7 +148,7 @@ data class ContentBarElementCrossfade( ContentBarElementSelector( button_colours = ButtonDefaults.buttonColors( - containerColor = player.theme.on_background, + containerColor = player.theme.onBackground, contentColor = player.theme.background ) ) { type -> diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementLyrics.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementLyrics.kt index 5ec82e04d..4e7af99f9 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementLyrics.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementLyrics.kt @@ -16,13 +16,14 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.* import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.DpSize -import dev.toastbits.composekit.utils.common.getValue -import dev.toastbits.composekit.utils.composable.* +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.components.utils.composable.* import com.toasterofbread.spmp.model.mediaitem.loader.SongLyricsLoader import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.* import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot +import dev.toastbits.composekit.util.composable.AlignableCrossfade import kotlin.math.sign import kotlinx.serialization.Serializable import org.jetbrains.compose.resources.stringResource @@ -135,10 +136,11 @@ data class ContentBarElementLyrics( var show_alignment_selector: Boolean by remember { mutableStateOf(false) } LargeDropdownMenu( - expanded = show_alignment_selector, + title = stringResource(Res.string.content_bar_element_lyrics_config_alignment), + isOpen = show_alignment_selector, onDismissRequest = { show_alignment_selector = false }, - item_count = 3, - selected = alignment.sign + 1, + items = (0 until 3).toList(), + selectedItem = alignment.sign + 1, itemContent = { Text( if (it == 0) stringResource(Res.string.s_option_lyrics_text_alignment_start) @@ -146,8 +148,8 @@ data class ContentBarElementLyrics( else stringResource(Res.string.s_option_lyrics_text_alignment_end) ) }, - onSelected = { - onModification(copy(alignment = it - 1)) + onSelected = { _, index -> + onModification(copy(alignment = index - 1)) show_alignment_selector = false } ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementSpacer.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementSpacer.kt index 021a4025b..5b71953c7 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementSpacer.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementSpacer.kt @@ -11,8 +11,8 @@ import androidx.compose.runtime.* import androidx.compose.ui.* import androidx.compose.ui.unit.* import androidx.compose.ui.Alignment -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.composable.RowOrColumnScope +import dev.toastbits.composekit.util.* +import dev.toastbits.composekit.components.utils.composable.RowOrColumnScope import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot import kotlin.math.roundToInt diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementVisualiser.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementVisualiser.kt index 737249142..67903c31f 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementVisualiser.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/element/ContentBarElementVisualiser.kt @@ -16,7 +16,7 @@ import androidx.compose.foundation.layout.padding import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LayoutSlot import LocalPlayerState -import dev.toastbits.composekit.utils.common.thenIf +import dev.toastbits.composekit.util.thenIf @Serializable data class ContentBarElementVisualiser( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/ColourSource.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/ColourSource.kt index 57329a649..5387f73ab 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/ColourSource.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/ColourSource.kt @@ -8,17 +8,18 @@ import androidx.compose.runtime.* import kotlinx.serialization.Serializable import LocalPlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.getNPBackground -import dev.toastbits.composekit.settings.ui.ThemeValues +import dev.toastbits.composekit.theme.core.ThemeValues +import dev.toastbits.composekit.theme.core.get @Serializable sealed interface ColourSource { fun get(player: PlayerState): Color - val theme_colour: ThemeValues.Colour? get() = null + val theme_colour: ThemeValues.Slot? get() = null } @Serializable -internal data class ThemeColourSource(override val theme_colour: ThemeValues.Colour): ColourSource { - override fun get(player: PlayerState): Color = theme_colour.get(player.theme) +internal data class ThemeColourSource(override val theme_colour: ThemeValues.Slot): ColourSource { + override fun get(player: PlayerState): Color = player.theme[theme_colour] } @Serializable @@ -36,7 +37,7 @@ data class CustomColourSource(val colour: Int): ColourSource { @Composable internal fun LayoutSlot.rememberColourSource(): State { val player: PlayerState = LocalPlayerState.current - val colours: Map by player.settings.layout.SLOT_COLOURS.observe() + val colours: Map by player.settings.Layout.SLOT_COLOURS.observe() return remember { derivedStateOf { colours[getKey()] ?: getDefaultBackgroundColour(player.theme) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LandscapeLayoutSlot.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LandscapeLayoutSlot.kt index 7708be8ce..08071c498 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LandscapeLayoutSlot.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LandscapeLayoutSlot.kt @@ -5,8 +5,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.* import com.toasterofbread.spmp.ui.layout.contentbar.* import com.toasterofbread.spmp.platform.AppContext -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.ThemeValues +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.theme.core.ThemeValues import kotlinx.serialization.json.* import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res @@ -56,8 +56,8 @@ enum class LandscapeLayoutSlot: LayoutSlot { PLAYER_BOTTOM_END -> false } - override fun getSlotsProperty(context: AppContext): PreferencesProperty> = - context.settings.layout.LANDSCAPE_SLOTS + override fun getSlotsProperty(context: AppContext): PlatformSettingsProperty> = + context.settings.Layout.LANDSCAPE_SLOTS override fun getKey(): String = name @@ -95,16 +95,16 @@ enum class LandscapeLayoutSlot: LayoutSlot { override fun getDefaultBackgroundColour(theme: ThemeValues): ColourSource = when (this) { - OUTER_SIDE_LEFT -> ThemeColourSource(ThemeValues.Colour.CARD) - INNER_SIDE_LEFT -> ThemeColourSource(ThemeValues.Colour.CARD) - OUTER_SIDE_RIGHT -> ThemeColourSource(ThemeValues.Colour.CARD) - INNER_SIDE_RIGHT -> ThemeColourSource(ThemeValues.Colour.CARD) + OUTER_SIDE_LEFT -> ThemeColourSource(ThemeValues.Slot.BuiltIn.CARD) + INNER_SIDE_LEFT -> ThemeColourSource(ThemeValues.Slot.BuiltIn.CARD) + OUTER_SIDE_RIGHT -> ThemeColourSource(ThemeValues.Slot.BuiltIn.CARD) + INNER_SIDE_RIGHT -> ThemeColourSource(ThemeValues.Slot.BuiltIn.CARD) - UPPER_TOP_BAR -> ThemeColourSource(ThemeValues.Colour.CARD) - LOWER_TOP_BAR -> ThemeColourSource(ThemeValues.Colour.CARD) + UPPER_TOP_BAR -> ThemeColourSource(ThemeValues.Slot.BuiltIn.CARD) + LOWER_TOP_BAR -> ThemeColourSource(ThemeValues.Slot.BuiltIn.CARD) ABOVE_PLAYER -> CustomColourSource(Color.Transparent) - BELOW_PLAYER -> ThemeColourSource(ThemeValues.Colour.CARD) + BELOW_PLAYER -> ThemeColourSource(ThemeValues.Slot.BuiltIn.CARD) PLAYER_BOTTOM_START -> CustomColourSource(Color.Transparent) PLAYER_BOTTOM_END -> CustomColourSource(Color.Transparent) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlot.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlot.kt index 5bb7e23a3..df62687e2 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlot.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlot.kt @@ -11,20 +11,20 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.Alignment import androidx.compose.material3.Text import androidx.compose.material3.Switch -import dev.toastbits.composekit.utils.composable.RowOrColumn +import dev.toastbits.composekit.components.utils.composable.RowOrColumn import com.toasterofbread.spmp.ui.layout.contentbar.ContentBar import com.toasterofbread.spmp.ui.layout.contentbar.ContentBarReference import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.contentbar.CustomContentBar -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.ThemeValues +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.theme.core.ThemeValues import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.decodeFromJsonElement import kotlinx.serialization.json.encodeToJsonElement import kotlinx.serialization.Serializable -import dev.toastbits.composekit.utils.composable.RowOrColumnScope +import dev.toastbits.composekit.components.utils.composable.RowOrColumnScope import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.layout_slot_config_below_player_show_in_player @@ -50,7 +50,7 @@ sealed interface LayoutSlot { val is_vertical: Boolean val is_start: Boolean - fun getSlotsProperty(context: AppContext): PreferencesProperty> + fun getSlotsProperty(context: AppContext): PlatformSettingsProperty> fun getContentBarSelectionState(): ContentBar.BarSelectionState? = ContentBar.bar_selection_state @@ -69,7 +69,7 @@ sealed interface LayoutSlot { fun LayoutSlot.observeContentBar(): State { val player: PlayerState = LocalPlayerState.current val slots: Map by getSlotsProperty(player.context).observe() - val custom_bars: List by player.settings.layout.CUSTOM_BARS.observe() + val custom_bars: List by player.settings.Layout.CUSTOM_BARS.observe() return remember(this) { derivedStateOf { if (!slots.contains(getKey())) { @@ -82,14 +82,14 @@ fun LayoutSlot.observeContentBar(): State { @Composable fun LayoutSlot.observeConfigData(): JsonElement? { val player: PlayerState = LocalPlayerState.current - val slot_configs: Map by player.settings.layout.SLOT_CONFIGS.observe() + val slot_configs: Map by player.settings.Layout.SLOT_CONFIGS.observe() return remember(slot_configs, this) { slot_configs[getKey()] } } @Composable inline fun LayoutSlot.observeConfig(noinline getDefault: @DisallowComposableCalls () -> T): T { val player: PlayerState = LocalPlayerState.current - val slot_configs: Map by player.settings.layout.SLOT_CONFIGS.observe() + val slot_configs: Map by player.settings.Layout.SLOT_CONFIGS.observe() return remember(slot_configs, this) { val config_data: JsonElement = slot_configs[getKey()] ?: return@remember getDefault() return@remember Json.decodeFromJsonElement(config_data) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlotEditor.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlotEditor.kt index eedd651a6..ff885b33f 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlotEditor.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlotEditor.kt @@ -14,9 +14,9 @@ import androidx.compose.runtime.* import androidx.compose.ui.* import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.settings.ui.component.item.* -import dev.toastbits.composekit.utils.composable.NullableValueAnimatedVisibility +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.* +import dev.toastbits.composekit.components.utils.composable.animatedvisibility.NullableValueAnimatedVisibility import com.toasterofbread.spmp.platform.* import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.contentbar.ContentBarReference @@ -31,10 +31,10 @@ import com.toasterofbread.spmp.ui.layout.contentbar.element.ContentBarElementCon import com.toasterofbread.spmp.ui.layout.contentbar.element.ContentBarElement import com.toasterofbread.spmp.ui.layout.contentbar.CircularReferenceWarning import com.toasterofbread.spmp.util.removeLastBuiltIn -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.vibrant_accent +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.SettingsItem +import dev.toastbits.composekit.theme.core.vibrantAccent import kotlinx.serialization.* -import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.stringResource @@ -51,13 +51,14 @@ fun getLayoutSlotEditorSettingsItems(context: AppContext): List { return listOf( ComposableSettingsItem( listOf( - context.settings.layout.PORTRAIT_SLOTS, - context.settings.layout.LANDSCAPE_SLOTS, - context.settings.layout.CUSTOM_BARS - ) + context.settings.Layout.PORTRAIT_SLOTS, + context.settings.Layout.LANDSCAPE_SLOTS, + context.settings.Layout.CUSTOM_BARS + ), + resetComposeUiState = {} ) { modifier -> LayoutSlotEditor(modifier) { - SpMp.player_state.app_page_state.Settings.settings_interface.goBack() + SpMp.player_state.app_page_state.Settings.goBack() } } ) @@ -71,14 +72,14 @@ fun LayoutSlotEditor( val player: PlayerState = LocalPlayerState.current val form_factor: FormFactor by FormFactor.observe() - var custom_bars: List by player.settings.layout.CUSTOM_BARS.observe() - var slot_colours: Map by player.settings.layout.SLOT_COLOURS.observe() - var slot_config: Map by player.settings.layout.SLOT_CONFIGS.observe() + var custom_bars: List by player.settings.Layout.CUSTOM_BARS.observe() + var slot_colours: Map by player.settings.Layout.SLOT_COLOURS.observe() + var slot_config: Map by player.settings.Layout.SLOT_CONFIGS.observe() - val slots_property: PreferencesProperty> = + val slots_property: PlatformSettingsProperty> = when (form_factor) { - FormFactor.PORTRAIT -> player.settings.layout.PORTRAIT_SLOTS - FormFactor.LANDSCAPE -> player.settings.layout.LANDSCAPE_SLOTS + FormFactor.PORTRAIT -> player.settings.Layout.PORTRAIT_SLOTS + FormFactor.LANDSCAPE -> player.settings.Layout.LANDSCAPE_SLOTS } val available_slots: List = when (form_factor) { @@ -267,7 +268,7 @@ fun LayoutSlotEditor( val slots: MutableMap = parseSlots().toMutableMap() for ((key, slot) in slots.entries) { - if (slot?.type != ContentBarReference.Type.CUSTOM) { + if (slot?.type != ContentBarReference.Type.CUSTOM) { continue } @@ -286,9 +287,9 @@ fun LayoutSlotEditor( } DisposableEffect(state) { - ContentBar.bar_selection_state = state + ContentBar.addBarSelectionState(state) onDispose { - ContentBar.bar_selection_state = null + ContentBar.removeBarSelectionState(state) } } @@ -358,7 +359,7 @@ fun LayoutSlotEditor( state, onSelected = null, onDismissed = {}, - bar_background_colour = player.theme.vibrant_accent.copy(alpha = 0.15f) + bar_background_colour = player.theme.vibrantAccent.copy(alpha = 0.15f) ) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlotEditorPreviewOptionsList.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlotEditorPreviewOptionsList.kt index 08a42dab8..ba0a8d874 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlotEditorPreviewOptionsList.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/LayoutSlotEditorPreviewOptionsList.kt @@ -9,7 +9,7 @@ import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.platform.* import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.contentbar.ContentBar -import dev.toastbits.composekit.platform.composable.platformClickable +import dev.toastbits.composekit.components.platform.composable.platformClickable import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.layout_editor_preview_option_show_bar_content diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/PortraitLayoutSlot.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/PortraitLayoutSlot.kt index 8b3cabf22..89a86ca14 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/PortraitLayoutSlot.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/contentbar/layoutslot/PortraitLayoutSlot.kt @@ -13,8 +13,8 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.material3.Text import androidx.compose.material3.Switch import com.toasterofbread.spmp.ui.layout.contentbar.ContentBarReference -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.ThemeValues +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.theme.core.ThemeValues import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.decodeFromJsonElement @@ -46,8 +46,8 @@ enum class PortraitLayoutSlot: LayoutSlot { PLAYER_TOP -> true } - override fun getSlotsProperty(context: AppContext): PreferencesProperty> = - context.settings.layout.PORTRAIT_SLOTS + override fun getSlotsProperty(context: AppContext): PlatformSettingsProperty> = + context.settings.Layout.PORTRAIT_SLOTS override fun getKey(): String = name @@ -72,10 +72,10 @@ enum class PortraitLayoutSlot: LayoutSlot { override fun getDefaultBackgroundColour(theme: ThemeValues): ColourSource = when (this) { - UPPER_TOP_BAR -> ThemeColourSource(ThemeValues.Colour.BACKGROUND) - LOWER_TOP_BAR -> ThemeColourSource(ThemeValues.Colour.BACKGROUND) + UPPER_TOP_BAR -> ThemeColourSource(ThemeValues.Slot.BuiltIn.BACKGROUND) + LOWER_TOP_BAR -> ThemeColourSource(ThemeValues.Slot.BuiltIn.BACKGROUND) ABOVE_PLAYER -> CustomColourSource(Color.Transparent) - BELOW_PLAYER -> ThemeColourSource(ThemeValues.Colour.ACCENT) + BELOW_PLAYER -> ThemeColourSource(ThemeValues.Slot.BuiltIn.ACCENT) PLAYER_TOP -> CustomColourSource(Color.Transparent) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/loadingsplash/ExtraLoadingContent.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/loadingsplash/ExtraLoadingContent.kt index dcc985dc4..b93a075fc 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/loadingsplash/ExtraLoadingContent.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/loadingsplash/ExtraLoadingContent.kt @@ -15,17 +15,17 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton import com.toasterofbread.spmp.model.settings.Settings import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.getServerGroupItems import com.toasterofbread.spmp.ui.component.ErrorInfoDisplay import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.platform.playerservice.LocalServer -import dev.toastbits.composekit.utils.composable.ShapedIconButton -import dev.toastbits.composekit.settings.ui.component.item.SettingsItem +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton +import dev.toastbits.composekit.settingsitem.domain.SettingsItem import LocalProgramArguments import ProgramArguments -import dev.toastbits.composekit.settings.ui.on_accent +import dev.toastbits.composekit.theme.core.onAccent import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.loading_splash_button_configure_connection @@ -43,7 +43,7 @@ fun SplashExtraLoadingContent(item_modifier: Modifier) { val button_colours: ButtonColors = ButtonDefaults.buttonColors( containerColor = player.theme.accent, - contentColor = player.theme.on_accent + contentColor = player.theme.onAccent ) Button( @@ -63,7 +63,7 @@ fun SplashExtraLoadingContent(item_modifier: Modifier) { }, colours = IconButtonDefaults.iconButtonColors( containerColor = player.theme.accent, - contentColor = player.theme.on_accent + contentColor = player.theme.onAccent ), modifier = item_modifier ) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/loadingsplash/LoadingSplash.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/loadingsplash/LoadingSplash.kt index 6fd5fbcc6..07578fe64 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/loadingsplash/LoadingSplash.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/loadingsplash/LoadingSplash.kt @@ -45,17 +45,14 @@ import com.toasterofbread.spmp.platform.playerservice.PlayerServiceLoadState import com.toasterofbread.spmp.platform.playerservice.PlayerServiceCompanion import com.toasterofbread.spmp.ui.component.ErrorInfoDisplay import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.settings.ui.on_accent +import dev.toastbits.composekit.theme.core.onAccent import kotlinx.coroutines.delay import org.jetbrains.compose.resources.* import spmp.shared.generated.resources.* -import dev.toastbits.composekit.utils.common.toFloat -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.common.blockGestures -import dev.toastbits.composekit.utils.composable.wave.OverlappingWaves -import dev.toastbits.composekit.utils.composable.wave.getDefaultOverlappingWavesLayers -import dev.toastbits.composekit.utils.composable.wave.WaveLayer -import dev.toastbits.composekit.utils.composable.NullableValueAnimatedVisibility +import dev.toastbits.composekit.components.utils.composable.wave.OverlappingWaves +import dev.toastbits.composekit.components.utils.composable.wave.getDefaultOverlappingWavesLayers +import dev.toastbits.composekit.components.utils.composable.wave.WaveLayer +import dev.toastbits.composekit.components.utils.composable.animatedvisibility.NullableValueAnimatedVisibility import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.error_player_service_not_connected @@ -171,7 +168,7 @@ fun LoadingSplash( if (message != null) { Text( message, - color = player.theme.on_background, + color = player.theme.onBackground, modifier = Modifier.wrapContentWidth() ) } @@ -214,13 +211,13 @@ fun LoadingSplash( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterVertically) ) { - CompositionLocalProvider(LocalContentColor provides player.theme.on_background) { + CompositionLocalProvider(LocalContentColor provides player.theme.onBackground) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(10.dp) ) { - Icon(Icons.Default.Warning, null, tint = player.theme.on_background) - Text(stringResource(Res.string.error_player_service_not_connected), color = player.theme.on_background) + Icon(Icons.Default.Warning, null, tint = player.theme.onBackground) + Text(stringResource(Res.string.error_player_service_not_connected), color = player.theme.onBackground) } if (player.context.canOpenUrl()) { @@ -232,7 +229,7 @@ fun LoadingSplash( }, colors = ButtonDefaults.buttonColors( containerColor = player.theme.accent, - contentColor = player.theme.on_accent + contentColor = player.theme.onAccent ) ) { Text(stringResource(Res.string.report_error)) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/NowPlaying.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/NowPlaying.kt index c282b97ae..4541eb23d 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/NowPlaying.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/NowPlaying.kt @@ -14,9 +14,9 @@ import androidx.compose.ui.unit.* import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp import androidx.compose.ui.platform.LocalDensity -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.composable.getBottom +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.util.* +import dev.toastbits.composekit.components.utils.composable.getBottom import com.toasterofbread.spmp.platform.* import com.toasterofbread.spmp.platform.FormFactor import com.toasterofbread.spmp.service.playercontroller.PlayerState @@ -127,7 +127,7 @@ fun NowPlaying(modifier: Modifier = Modifier) { if (bounded > 1f) bounded - 1f else 0f - return@DisplayBar player.getNPBackground().blendWith(background_colour, our_ratio = min_background_alpha) + return@DisplayBar player.getNPBackground().blendWith(background_colour, ourRatio = min_background_alpha) } ) @@ -203,18 +203,18 @@ internal fun PlayerState.getNPOnBackground(): Color { // } // // return when (np_theme_mode) { -// ThemeMode.BACKGROUND -> theme.on_accent +// ThemeMode.BACKGROUND -> theme.onAccent // ThemeMode.ELEMENTS -> theme.accent -// ThemeMode.NONE -> theme.on_background +// ThemeMode.NONE -> theme.onBackground // } } internal fun PlayerState.getNPAltBackground(theme_mode: ThemeMode = np_theme_mode): Color { return when (theme_mode) { - ThemeMode.BACKGROUND -> getNPBackground().amplifyPercent(-0.4f, opposite_percent = -0.2f) + ThemeMode.BACKGROUND -> getNPBackground().amplifyPercent(-0.4f, oppositePercent = -0.2f) else -> theme.background } } internal fun PlayerState.getNPAltOnBackground(): Color = - getNPBackground().amplifyPercent(-0.4f, opposite_percent = -0.1f) + getNPBackground().amplifyPercent(-0.4f, oppositePercent = -0.1f) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/NowPlayingPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/NowPlayingPage.kt index 4aba4cf2e..2d36c30cb 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/NowPlayingPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/NowPlayingPage.kt @@ -9,7 +9,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.getTop +import dev.toastbits.composekit.components.utils.composable.getTop import com.toasterofbread.spmp.platform.FormFactor import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.maintab.NowPlayingMainTabPage diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/PlayerExpansionState.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/PlayerExpansionState.kt index ecdd5fc4c..f58e5337a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/PlayerExpansionState.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/PlayerExpansionState.kt @@ -83,7 +83,7 @@ abstract class PlayerExpansionState( val anchor_position: Float = anchors.positionOf(anchor) if (offset < anchor_position) { low_index = (anchor - 1).coerceAtLeast(getPageRange().first) - if (!anchors.hasAnchorFor(low_index)) { + if (!anchors.hasPositionFor(low_index)) { return low_index.toFloat() } low = anchors.positionOf(low_index) @@ -94,7 +94,7 @@ abstract class PlayerExpansionState( if (low_index == null) { low_index = getPageRange().last - if (!anchors.hasAnchorFor(low_index)) { + if (!anchors.hasPositionFor(low_index)) { return low_index.toFloat() } low = anchors.positionOf(low_index) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/MinimisedProgressBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/MinimisedProgressBar.kt index 922bdffee..75d2417d1 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/MinimisedProgressBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/MinimisedProgressBar.kt @@ -10,7 +10,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.Dp import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.layout.fillMaxWidth -import dev.toastbits.composekit.utils.composable.RecomposeOnInterval +import dev.toastbits.composekit.components.utils.composable.RecomposeOnInterval import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.* diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/NowPlayingContainer.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/NowPlayingContainer.kt index f90b8b667..74b169f15 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/NowPlayingContainer.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/NowPlayingContainer.kt @@ -15,13 +15,13 @@ import androidx.compose.ui.unit.* import androidx.compose.ui.layout.onSizeChanged import androidx.compose.material3.LocalContentColor import androidx.compose.runtime.CompositionLocalProvider -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.common.blendWith -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.getTop -import dev.toastbits.composekit.utils.composable.getBottom +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.util.blendWith +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.composable.getTop +import dev.toastbits.composekit.components.utils.composable.getBottom import com.toasterofbread.spmp.platform.* import com.toasterofbread.spmp.platform.FormFactor import com.toasterofbread.spmp.service.playercontroller.PlayerState diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/PlayerBackground.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/PlayerBackground.kt index 80d96bf30..99ff9a35b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/PlayerBackground.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/PlayerBackground.kt @@ -2,21 +2,43 @@ package com.toasterofbread.spmp.ui.layout.nowplaying.container import LocalNowPlayingExpansion import LocalPlayerState -import androidx.compose.foundation.layout.* -import androidx.compose.runtime.* -import androidx.compose.ui.* -import androidx.compose.ui.graphics.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.requiredHeight +import androidx.compose.foundation.layout.requiredSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.graphics.BlendMode +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.* +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.times import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.settings.category.ThemeSettings import com.toasterofbread.spmp.platform.FormFactor import com.toasterofbread.spmp.service.playercontroller.PlayerState -import com.toasterofbread.spmp.ui.layout.nowplaying.* +import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingPage +import com.toasterofbread.spmp.ui.layout.nowplaying.PlayerExpansionState +import com.toasterofbread.spmp.ui.layout.nowplaying.getNPAltBackground +import com.toasterofbread.spmp.ui.layout.nowplaying.getNPBackground import com.toasterofbread.spmp.ui.layout.nowplaying.maintab.NOW_PLAYING_LARGE_BOTTOM_BAR_HEIGHT -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.composable.wave.* -import dev.toastbits.composekit.utils.modifier.brushBackground +import dev.toastbits.composekit.components.utils.composable.wave.OverlappingWaves +import dev.toastbits.composekit.components.utils.composable.wave.WaveLayer +import dev.toastbits.composekit.components.utils.composable.wave.getDefaultOverlappingWavesLayers +import dev.toastbits.composekit.components.utils.modifier.brushBackground +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.util.thenIf import kotlin.math.absoluteValue private const val GRADIENT_BOTTOM_PADDING_DP: Float = 100f @@ -39,11 +61,11 @@ internal fun PlayerBackground( getDefaultOverlappingWavesLayers(7, 0.35f) } - val default_wave_speed: Float by player.settings.theme.NOWPLAYING_DEFAULT_WAVE_SPEED.observe() + val default_wave_speed: Float by player.settings.Theme.NOWPLAYING_DEFAULT_WAVE_SPEED.observe() val song_wave_speed: Float? by current_song?.BackgroundWaveSpeed?.observe(player.database) val background_wave_speed: Float = song_wave_speed ?: default_wave_speed - val default_wave_opacity: Float by player.settings.theme.NOWPLAYING_DEFAULT_WAVE_OPACITY.observe() + val default_wave_opacity: Float by player.settings.Theme.NOWPLAYING_DEFAULT_WAVE_OPACITY.observe() val song_wave_opacity: Float? by current_song?.BackgroundWaveOpacity?.observe(player.database) val background_wave_opacity: Float = song_wave_opacity ?: default_wave_opacity @@ -79,7 +101,7 @@ internal fun PlayerBackground( Modifier.requiredSize(player.screen_size.width, page_height - bottom_spacing) ) - val show_waves: Boolean by player.settings.theme.SHOW_EXPANDED_PLAYER_WAVE.observe() + val show_waves: Boolean by player.settings.Theme.SHOW_EXPANDED_PLAYER_WAVE.observe() if (show_waves) { OverlappingWaves( { player.theme.accent.copy(alpha = wave_alpha * expansion.getAbsolute()) }, @@ -108,13 +130,13 @@ private fun ImageBackground( val player: PlayerState = LocalPlayerState.current val expansion: PlayerExpansionState = LocalNowPlayingExpansion.current - val default_background_opacity: Float by player.settings.theme.NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY.observe() + val default_background_opacity: Float by player.settings.Theme.NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY.observe() val song_background_opacity: Float? by player.status.m_song?.BackgroundImageOpacity?.observe(player.database) val background_content_opacity: Float by remember { derivedStateOf { song_background_opacity ?: default_background_opacity } } val show_background_content: Boolean by remember { derivedStateOf { background_content_opacity > 0f } } - val default_video_position: ThemeSettings.VideoPosition by player.settings.theme.NOWPLAYING_DEFAULT_VIDEO_POSITION.observe() + val default_video_position: ThemeSettings.VideoPosition by player.settings.Theme.NOWPLAYING_DEFAULT_VIDEO_POSITION.observe() val song_video_position: ThemeSettings.VideoPosition? by player.status.m_song?.VideoPosition?.observe(player.database) BoxWithConstraints(modifier) { @@ -152,7 +174,7 @@ private fun Modifier.playerBackground(getPageHeight: () -> Dp): Modifier = compo val expansion: PlayerExpansionState = LocalNowPlayingExpansion.current val density: Density = LocalDensity.current - val default_gradient_depth: Float by player.settings.theme.NOWPLAYING_DEFAULT_GRADIENT_DEPTH.observe() + val default_gradient_depth: Float by player.settings.Theme.NOWPLAYING_DEFAULT_GRADIENT_DEPTH.observe() val song_gradient_depth: Float? by player.status.m_song?.PlayerGradientDepth?.observe(player.database) brushBackground { with (density) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/PlayerOverscroll.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/PlayerOverscroll.kt index 2ab252fe2..504d7fdf4 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/PlayerOverscroll.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/PlayerOverscroll.kt @@ -5,17 +5,15 @@ import androidx.compose.foundation.interaction.* import androidx.compose.foundation.gestures.AnchoredDraggableState import androidx.compose.runtime.* import androidx.compose.ui.* -import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp import androidx.compose.ui.platform.LocalDensity -import dev.toastbits.composekit.platform.vibrateShort +import dev.toastbits.composekit.context.vibrateShort import com.toasterofbread.spmp.model.settings.category.* import com.toasterofbread.spmp.platform.playerservice.PlayerService import com.toasterofbread.spmp.service.playercontroller.PlayerState -import com.toasterofbread.spmp.ui.layout.nowplaying.container.npAnchorToDp import kotlinx.coroutines.delay private const val OVERSCROLL_CLEAR_DISTANCE_THRESHOLD_DP: Float = 5f @@ -46,9 +44,9 @@ internal fun Modifier.playerOverscroll( val density: Density = LocalDensity.current var player_alpha: Float by remember { mutableStateOf(1f) } - val overscroll_clear_enabled: Boolean by player.settings.player.MINI_OVERSCROLL_CLEAR_ENABLED.observe() - val overscroll_clear_time: Float by player.settings.player.MINI_OVERSCROLL_CLEAR_TIME.observe() - val overscroll_clear_mode: OverscrollClearMode by player.settings.player.MINI_OVERSCROLL_CLEAR_MODE.observe() + val overscroll_clear_enabled: Boolean by player.settings.Player.MINI_OVERSCROLL_CLEAR_ENABLED.observe() + val overscroll_clear_time: Float by player.settings.Player.MINI_OVERSCROLL_CLEAR_TIME.observe() + val overscroll_clear_mode: OverscrollClearMode by player.settings.Player.MINI_OVERSCROLL_CLEAR_MODE.observe() LaunchedEffect(controller, swipe_interactions.isNotEmpty(), overscroll_clear_enabled) { if (!overscroll_clear_enabled || controller == null) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/ThumbnailBackground.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/ThumbnailBackground.kt index f6a00b0b8..521f5dfec 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/ThumbnailBackground.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/ThumbnailBackground.kt @@ -22,7 +22,7 @@ fun ThumbnailBackground( val player: PlayerState = LocalPlayerState.current val expansion: PlayerExpansionState = LocalNowPlayingExpansion.current - val default_background_image_opacity: Float by player.settings.theme.NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY.observe() + val default_background_image_opacity: Float by player.settings.Theme.NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY.observe() val current_song: Song? by player.status.song_state current_song?.also { song -> diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/UpdateAnchors.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/UpdateAnchors.kt index a3987eeef..55be23880 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/UpdateAnchors.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/UpdateAnchors.kt @@ -25,7 +25,7 @@ internal fun UpdateAnchors( val density: Density = LocalDensity.current val minimised_now_playing_height: Dp = MINIMISED_NOW_PLAYING_HEIGHT_DP.dp - val swipe_sensitivity: Float by player.settings.player.EXPAND_SWIPE_SENSITIVITY.observe() + val swipe_sensitivity: Float by player.settings.Player.EXPAND_SWIPE_SENSITIVITY.observe() LaunchedEffect(page_height, pages.size, minimised_now_playing_height, swipe_sensitivity) { val sensitivity: Float = processSwipeSensitivity(swipe_sensitivity) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/UpdateBarColours.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/UpdateBarColours.kt index 3374b1ee5..64e999a5c 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/UpdateBarColours.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/container/UpdateBarColours.kt @@ -10,7 +10,7 @@ import com.toasterofbread.spmp.ui.layout.nowplaying.PlayerExpansionState import com.toasterofbread.spmp.ui.layout.nowplaying.getNPBackground import com.toasterofbread.spmp.ui.layout.BarColourState import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.CustomColourSource -import dev.toastbits.composekit.utils.composable.getTop +import dev.toastbits.composekit.components.utils.composable.getTop import LocalPlayerState import LocalNowPlayingExpansion diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/Controls.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/Controls.kt index 192d6ca8f..5c8d38666 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/Controls.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/Controls.kt @@ -24,11 +24,11 @@ import com.toasterofbread.spmp.service.playercontroller.* import com.toasterofbread.spmp.ui.component.MediaItemTitleEditDialog import com.toasterofbread.spmp.ui.component.mediaitempreview.MediaItemPreviewLong import com.toasterofbread.spmp.ui.layout.nowplaying.* -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.common.getValue -import dev.toastbits.composekit.utils.composable.Marquee -import dev.toastbits.composekit.utils.modifier.bounceOnClick +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.components.utils.composable.Marquee +import dev.toastbits.composekit.components.utils.modifier.bounceOnClick import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.action_cancel @@ -60,7 +60,7 @@ fun PlayerButton( ) ) { val painter: VectorPainter = rememberVectorPainter(image) - val np_theme_mode: ThemeMode by player.settings.theme.NOWPLAYING_THEME_MODE.observe() + val np_theme_mode: ThemeMode by player.settings.Theme.NOWPLAYING_THEME_MODE.observe() Canvas( Modifier diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/LargeBottomBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/LargeBottomBar.kt index f7c3d8d87..e61aa8cd8 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/LargeBottomBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/LargeBottomBar.kt @@ -19,9 +19,9 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.draw.alpha -import dev.toastbits.composekit.utils.common.getValue -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.modifier.bounceOnClick +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.components.utils.modifier.bounceOnClick import com.toasterofbread.spmp.model.mediaitem.loader.SongLyricsLoader import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.ui.component.HorizontalLyricsLineDisplay @@ -29,6 +29,7 @@ import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.theme.appHover import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.LandscapeLayoutSlot import com.toasterofbread.spmp.ui.layout.contentbar.DisplayBar +import dev.toastbits.composekit.util.composable.thenIf @Composable internal fun LargeBottomBar( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabActionButtons.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabActionButtons.kt index 8bddb0118..325893bfd 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabActionButtons.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabActionButtons.kt @@ -14,9 +14,9 @@ import androidx.compose.ui.platform.ClipboardManager import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.text.AnnotatedString import com.toasterofbread.spmp.model.mediaitem.observeUrl -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.composable.PlatformClickableIconButton -import dev.toastbits.composekit.utils.modifier.bounceOnClick +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.components.utils.composable.PlatformClickableIconButton +import dev.toastbits.composekit.components.utils.modifier.bounceOnClick import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.ui.component.LikeDislikeButton import com.toasterofbread.spmp.service.playercontroller.PlayerState diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabLarge.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabLarge.kt index 66ee78613..a1aaa535f 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabLarge.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabLarge.kt @@ -6,10 +6,37 @@ import androidx.compose.animation.core.animateDpAsState import androidx.compose.foundation.Canvas import androidx.compose.foundation.border import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.calculateEndPadding +import androidx.compose.foundation.layout.calculateStartPadding +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.requiredHeight +import androidx.compose.foundation.layout.requiredSize +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.LocalContentColor -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.State +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -25,35 +52,47 @@ import androidx.compose.ui.layout.positionInRoot import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.* +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.DpOffset +import androidx.compose.ui.unit.DpSize +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.coerceAtLeast +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.lerp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.unit.times import androidx.compose.ui.zIndex -import dev.toastbits.composekit.platform.composable.composeScope -import dev.toastbits.composekit.utils.common.* -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.getTop -import dev.toastbits.ytmkt.model.external.ThumbnailProvider import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.mediaitem.song.observeThumbnailRounding import com.toasterofbread.spmp.model.settings.category.NowPlayingQueueWaveBorderMode +import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.Thumbnail import com.toasterofbread.spmp.ui.layout.apppage.mainpage.MINIMISED_NOW_PLAYING_HEIGHT_DP import com.toasterofbread.spmp.ui.layout.apppage.mainpage.MINIMISED_NOW_PLAYING_V_PADDING_DP -import com.toasterofbread.spmp.service.playercontroller.PlayerState -import com.toasterofbread.spmp.ui.layout.nowplaying.PlayerExpansionState import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingPage.Companion.bottom_padding import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingPage.Companion.horizontal_padding import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingPage.Companion.horizontal_padding_minimised import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingPage.Companion.top_padding import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingTopBar +import com.toasterofbread.spmp.ui.layout.nowplaying.PlayerExpansionState import com.toasterofbread.spmp.ui.layout.nowplaying.ThemeMode import com.toasterofbread.spmp.ui.layout.nowplaying.getNPAltBackground import com.toasterofbread.spmp.ui.layout.nowplaying.maintab.thumbnailrow.LargeThumbnailRow import com.toasterofbread.spmp.ui.layout.nowplaying.maintab.thumbnailrow.songThumbnailShadow import com.toasterofbread.spmp.ui.layout.nowplaying.queue.QueueTab +import dev.toastbits.composekit.components.platform.composable.composeScope +import dev.toastbits.composekit.components.utils.composable.getTop +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.amplify +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.util.toInt +import dev.toastbits.ytmkt.model.external.ThumbnailProvider import kotlin.math.absoluteValue import kotlin.math.roundToInt -import androidx.compose.runtime.State -import dev.toastbits.composekit.settings.ui.vibrant_accent val NOW_PLAYING_LARGE_BOTTOM_BAR_HEIGHT: Dp @Composable get() = MINIMISED_NOW_PLAYING_HEIGHT_DP.dp @@ -106,7 +145,7 @@ internal fun NowPlayingMainTabPage.NowPlayingMainTabLarge(page_height: Dp, top_b val layout_direction: LayoutDirection = LocalLayoutDirection.current val density: Density = LocalDensity.current - val swap_controls_and_image: Boolean by player.settings.player.LANDSCAPE_SWAP_CONTROLS_AND_IMAGE.observe() + val swap_controls_and_image: Boolean by player.settings.Player.LANDSCAPE_SWAP_CONTROLS_AND_IMAGE.observe() val proportion: Float = WindowInsets.getTop() / page_height val proportion_exp: Float by remember { derivedStateOf { @@ -393,7 +432,7 @@ private fun PlayerQueueTab( val queue_shape: Shape = RoundedCornerShape(10.dp) val width: Dp by width_state - val default_background_opacity: Float by player.settings.theme.NOWPLAYING_DEFAULT_LANDSCAPE_QUEUE_OPACITY.observe() + val default_background_opacity: Float by player.settings.Theme.NOWPLAYING_DEFAULT_LANDSCAPE_QUEUE_OPACITY.observe() val song_background_opacity: Float? by player.status.m_song?.LandscapeQueueOpacity?.observe(player.database) val background_opacity: Float by remember(player.status.m_song) { derivedStateOf { song_background_opacity ?: default_background_opacity } } @@ -418,7 +457,7 @@ private fun PlayerQueueTab( } } ) { - val np_theme_mode: ThemeMode by player.settings.theme.NOWPLAYING_THEME_MODE.observe() + val np_theme_mode: ThemeMode by player.settings.Theme.NOWPLAYING_THEME_MODE.observe() QueueTab( null, @@ -449,9 +488,9 @@ private fun PlayerQueueTab( }, getOnBackgroundColour = { when (np_theme_mode) { - ThemeMode.BACKGROUND -> theme.vibrant_accent + ThemeMode.BACKGROUND -> theme.vibrantAccent ThemeMode.ELEMENTS -> theme.accent - ThemeMode.NONE -> theme.on_background + ThemeMode.NONE -> theme.onBackground } } ) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabNarrow.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabNarrow.kt index bd753297c..e6581b290 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabNarrow.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabNarrow.kt @@ -26,13 +26,13 @@ import androidx.compose.ui.layout.layout import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.getValue -import dev.toastbits.composekit.utils.common.isJa -import dev.toastbits.composekit.utils.common.thenIf +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.util.isJa +import dev.toastbits.composekit.util.thenIf import dev.toastbits.ytmkt.model.external.ThumbnailProvider import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.platform.playerservice.seekToPreviousOrRepeat -import dev.toastbits.composekit.utils.composable.RowOrColumn +import dev.toastbits.composekit.components.utils.composable.RowOrColumn import com.toasterofbread.spmp.ui.component.Thumbnail import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingPage.Companion.bottom_padding diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabPage.kt index 261c5d65b..8fd5b37d6 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabPage.kt @@ -14,8 +14,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.utils.common.getThemeColour +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.util.getThemeColour import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.platform.FormFactor import com.toasterofbread.spmp.service.playercontroller.PlayerState @@ -52,7 +52,7 @@ class NowPlayingMainTabPage: NowPlayingPage() { fun setThemeColour(value: Color?, custom: Boolean) { theme_colour = value - player.theme.onCurrentThumbnailColourChanged(theme_colour) + player.theme.onContextualColourChanged(theme_colour) if (custom) { player.status.song diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabPortrait.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabPortrait.kt index bd2bd80c6..bf6e357a5 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabPortrait.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/NowPlayingMainTabPortrait.kt @@ -24,8 +24,6 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.KeyboardArrowUp import androidx.compose.material.icons.filled.MoreHoriz import androidx.compose.material.icons.filled.VolumeUp -import androidx.compose.material.icons.rounded.Radio -import androidx.compose.material.icons.rounded.Shuffle import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.runtime.Composable @@ -46,9 +44,9 @@ import androidx.compose.ui.unit.lerp import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.platform.LocalDensity -import dev.toastbits.composekit.platform.composable.composeScope -import dev.toastbits.composekit.utils.modifier.bounceOnClick -import dev.toastbits.composekit.utils.common.copy +import dev.toastbits.composekit.components.platform.composable.composeScope +import dev.toastbits.composekit.components.utils.modifier.bounceOnClick +import dev.toastbits.composekit.util.composable.copy import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.service.playercontroller.LocalPlayerClickOverrides import com.toasterofbread.spmp.service.playercontroller.PlayerClickOverrides @@ -58,16 +56,11 @@ import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.PlayerExpansionState import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingPage.Companion.bottom_padding import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingPage.Companion.horizontal_padding -import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingPage.Companion.top_padding import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingTopBar import com.toasterofbread.spmp.ui.layout.nowplaying.getNPBackground import com.toasterofbread.spmp.ui.layout.nowplaying.getNPOnBackground import com.toasterofbread.spmp.ui.layout.nowplaying.maintab.thumbnailrow.SmallThumbnailRow import com.toasterofbread.spmp.ui.layout.nowplaying.queue.RepeatButton -import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.PortraitLayoutSlot -import com.toasterofbread.spmp.ui.layout.contentbar.layoutslot.observeContentBar -import com.toasterofbread.spmp.ui.layout.contentbar.ContentBar -import com.toasterofbread.spmp.ui.layout.contentbar.DisplayBar import kotlin.math.absoluteValue internal const val MINIMISED_NOW_PLAYING_HORIZ_PADDING: Float = 10f @@ -175,7 +168,7 @@ internal fun NowPlayingMainTabPage.NowPlayingMainTabPortrait( ) { val button_modifier: Modifier = Modifier.alpha(0.5f) val side_button_padding: Dp = 20.dp - val show_shuffle_repeat_buttons: Boolean by player.settings.player.SHOW_REPEAT_SHUFFLE_BUTTONS.observe() + val show_shuffle_repeat_buttons: Boolean by player.settings.Player.SHOW_REPEAT_SHUFFLE_BUTTONS.observe() Controls( current_song, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/SeekBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/SeekBar.kt index c501be942..c84ebbe67 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/SeekBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/SeekBar.kt @@ -33,9 +33,9 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.github.krottv.compose.sliders.DefaultThumb import com.github.krottv.compose.sliders.SliderValueHorizontal -import dev.toastbits.composekit.utils.common.formatElapsedTime -import dev.toastbits.composekit.utils.composable.RecomposeOnInterval -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.util.formatElapsedTime +import dev.toastbits.composekit.components.utils.composable.RecomposeOnInterval +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.POSITION_UPDATE_INTERVAL_MS import com.toasterofbread.spmp.ui.layout.nowplaying.getNPAltOnBackground @@ -131,7 +131,7 @@ private fun SeekTrack( ) { val player: PlayerState = LocalPlayerState.current val visual_progress by animateFloatAsState(progress, spring(stiffness = Spring.StiffnessLow)) - val show_gradient: Boolean by player.settings.player.SHOW_SEEK_BAR_GRADIENT.observe() + val show_gradient: Boolean by player.settings.Player.SHOW_SEEK_BAR_GRADIENT.observe() Canvas( Modifier diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/thumbnailrow/LargeThumbnailRow.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/thumbnailrow/LargeThumbnailRow.kt index 4e23dcf8a..77fae2cb6 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/thumbnailrow/LargeThumbnailRow.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/thumbnailrow/LargeThumbnailRow.kt @@ -73,15 +73,15 @@ import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.PlayerOverlayMenu import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.PlayerOverlayMenuAction import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.RelatedContentPlayerOverlayMenu import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.songtheme.SongThemePlayerOverlayMenu -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.utils.common.getInnerSquareSizeOfCircle -import dev.toastbits.composekit.utils.common.getValue -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.MeasureUnconstrainedView -import dev.toastbits.composekit.utils.composable.OnChangedEffect -import dev.toastbits.composekit.utils.modifier.background -import dev.toastbits.composekit.utils.modifier.disableParentScroll +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.util.getInnerSquareSizeOfCircle +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.components.utils.composable.MeasureUnconstrainedView +import dev.toastbits.composekit.util.composable.OnChangedEffect +import dev.toastbits.composekit.components.utils.modifier.background +import dev.toastbits.composekit.components.utils.modifier.disableParentScroll import dev.toastbits.ytmkt.model.external.ThumbnailProvider import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -240,7 +240,7 @@ fun LargeThumbnailRow( ) } ) { - val default_video_position: ThemeSettings.VideoPosition by player.settings.theme.NOWPLAYING_DEFAULT_VIDEO_POSITION.observe() + val default_video_position: ThemeSettings.VideoPosition by player.settings.Theme.NOWPLAYING_DEFAULT_VIDEO_POSITION.observe() val song_video_position: ThemeSettings.VideoPosition? by song.VideoPosition.observe(player.database) var video_showing: Boolean = false @@ -407,11 +407,11 @@ private suspend fun PlayerState.performPressAction( setOverlayMenu: (PlayerOverlayMenu?) -> Unit ) { val custom_action: Boolean = - if (context.settings.player.OVERLAY_SWAP_LONG_SHORT_PRESS_ACTIONS.get()) !long_press + if (context.settings.Player.OVERLAY_SWAP_LONG_SHORT_PRESS_ACTIONS.get()) !long_press else long_press val action: PlayerOverlayMenuAction = - if (custom_action) context.settings.player.OVERLAY_CUSTOM_ACTION.get() + if (custom_action) context.settings.Player.OVERLAY_CUSTOM_ACTION.get() else PlayerOverlayMenuAction.DEFAULT when (action) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/thumbnailrow/SmallThumbnailRow.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/thumbnailrow/SmallThumbnailRow.kt index 3f6e13ba9..109e0357e 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/thumbnailrow/SmallThumbnailRow.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/maintab/thumbnailrow/SmallThumbnailRow.kt @@ -30,14 +30,14 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import androidx.compose.runtime.getValue -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.utils.common.getInnerSquareSizeOfCircle -import dev.toastbits.composekit.utils.common.getValue -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.OnChangedEffect -import dev.toastbits.composekit.utils.modifier.background -import dev.toastbits.composekit.utils.modifier.disableParentScroll +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.util.getInnerSquareSizeOfCircle +import dev.toastbits.composekit.util.composable.getValue +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.util.composable.OnChangedEffect +import dev.toastbits.composekit.components.utils.modifier.background +import dev.toastbits.composekit.components.utils.modifier.disableParentScroll import dev.toastbits.ytmkt.model.external.ThumbnailProvider import com.toasterofbread.spmp.model.mediaitem.db.observePropertyActiveTitles import com.toasterofbread.spmp.model.mediaitem.song.Song @@ -130,8 +130,8 @@ fun SmallThumbnailRow( // Keep thumbnail centered Spacer(Modifier) - val overlay_swap_long_short_press_actions: Boolean by player.settings.player.OVERLAY_SWAP_LONG_SHORT_PRESS_ACTIONS.observe() - val overlay_custom_action: PlayerOverlayMenuAction by player.settings.player.OVERLAY_CUSTOM_ACTION.observe() + val overlay_swap_long_short_press_actions: Boolean by player.settings.Player.OVERLAY_SWAP_LONG_SHORT_PRESS_ACTIONS.observe() + val overlay_custom_action: PlayerOverlayMenuAction by player.settings.Player.OVERLAY_CUSTOM_ACTION.observe() Box(Modifier.aspectRatio(1f)) { fun performPressAction(long_press: Boolean) { @@ -205,7 +205,7 @@ fun SmallThumbnailRow( } ) - val default_video_position: ThemeSettings.VideoPosition by player.settings.theme.NOWPLAYING_DEFAULT_VIDEO_POSITION.observe() + val default_video_position: ThemeSettings.VideoPosition by player.settings.Theme.NOWPLAYING_DEFAULT_VIDEO_POSITION.observe() val song_video_position: ThemeSettings.VideoPosition? by song.VideoPosition.observe(player.database) var video_showing: Boolean = false @@ -330,7 +330,7 @@ fun SmallThumbnailRow( ) } - val show_prev_button: Boolean by player.settings.player.MINI_SHOW_PREV_BUTTON.observe() + val show_prev_button: Boolean by player.settings.Player.MINI_SHOW_PREV_BUTTON.observe() ThumbnailRowControlButtons(Modifier.size(40.dp), show_prev_button = show_prev_button) } } @@ -344,7 +344,7 @@ internal fun Modifier.songThumbnailShadow( inGraphicsLayer: GraphicsLayerScope.() -> Unit = {} ): Modifier { val player: PlayerState = LocalPlayerState.current - val default_shadow_radius: Float by player.settings.theme.NOWPLAYING_DEFAULT_SHADOW_RADIUS.observe() + val default_shadow_radius: Float by player.settings.Theme.NOWPLAYING_DEFAULT_SHADOW_RADIUS.observe() val shadow_radius: Float? by song?.ShadowRadius?.observe(player.database) return graphicsLayer { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/MainOverlayMenu.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/MainOverlayMenu.kt index d0dac593a..a7dc60d06 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/MainOverlayMenu.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/MainOverlayMenu.kt @@ -63,8 +63,8 @@ import com.toasterofbread.spmp.ui.component.mediaitempreview.MediaItemPreviewLon import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField import com.toasterofbread.spmp.ui.layout.nowplaying.maintab.thumbnailrow.ColourpickCallback import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.songtheme.SongThemePlayerOverlayMenu -import dev.toastbits.composekit.settings.ui.on_accent -import dev.toastbits.composekit.utils.composable.OnChangedEffect +import dev.toastbits.composekit.theme.core.onAccent +import dev.toastbits.composekit.util.composable.OnChangedEffect import dev.toastbits.ytmkt.model.implementedOrNull import kotlinx.coroutines.delay import org.jetbrains.compose.resources.stringResource @@ -145,7 +145,7 @@ class MainPlayerOverlayMenu( verticalArrangement = Arrangement.spacedBy(10.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - val button_colour: Color = player.theme.on_accent + val button_colour: Color = player.theme.onAccent val button_size: Dp = 42.dp val button_modifier: Modifier = Modifier .background( @@ -231,7 +231,7 @@ class MainPlayerOverlayMenu( ) { val player: PlayerState = LocalPlayerState.current - val button_content_colour: Color = player.theme.on_accent + val button_content_colour: Color = player.theme.onAccent Row( modifier.fillMaxWidth(), diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/SongThemeOverlayMenu.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/SongThemeOverlayMenu.kt index 63c048bc7..51f37f7d7 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/SongThemeOverlayMenu.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/SongThemeOverlayMenu.kt @@ -26,9 +26,9 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.platform.composable.ScrollBarLazyColumn -import dev.toastbits.composekit.utils.composable.OnChangedEffect -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyColumn +import dev.toastbits.composekit.util.composable.OnChangedEffect +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.settings.category.ThemeSettings import com.toasterofbread.spmp.platform.FormFactor @@ -149,44 +149,45 @@ class SongThemePlayerOverlayMenu( ) { ValueSlider( song.ThumbnailRounding.observe(player.database), - player.settings.theme.NOWPLAYING_DEFAULT_IMAGE_CORNER_ROUNDING.getDefaultValueComposable(), + player.settings.Theme.NOWPLAYING_DEFAULT_IMAGE_CORNER_ROUNDING.getDefaultValue(), stringResource(Res.string.song_theme_menu_corner_radius) ) ValueSlider( song.PlayerGradientDepth.observe(player.database), - player.settings.theme.NOWPLAYING_DEFAULT_GRADIENT_DEPTH.getDefaultValueComposable(), + player.settings.Theme.NOWPLAYING_DEFAULT_GRADIENT_DEPTH.getDefaultValue(), stringResource(Res.string.song_theme_menu_gradient_depth) ) ValueSlider( song.BackgroundWaveSpeed.observe(player.database), - player.settings.theme.NOWPLAYING_DEFAULT_WAVE_SPEED.getDefaultValueComposable(), + player.settings.Theme.NOWPLAYING_DEFAULT_WAVE_SPEED.getDefaultValue(), stringResource(Res.string.song_theme_menu_wave_speed) ) ValueSlider( song.BackgroundWaveOpacity.observe(player.database), - player.settings.theme.NOWPLAYING_DEFAULT_WAVE_OPACITY.getDefaultValueComposable(), + player.settings.Theme.NOWPLAYING_DEFAULT_WAVE_OPACITY.getDefaultValue(), stringResource(Res.string.song_theme_menu_wave_opacity) ) if (true) { // isVideoPlaybackSupported() - val default_video_position: ThemeSettings.VideoPosition by player.settings.theme.NOWPLAYING_DEFAULT_VIDEO_POSITION.observe() + val default_video_position: ThemeSettings.VideoPosition by player.settings.Theme.NOWPLAYING_DEFAULT_VIDEO_POSITION.observe() var song_video_position: ThemeSettings.VideoPosition? by song.VideoPosition.observe(player.database) var show_position_selector: Boolean by remember { mutableStateOf(false) } LargeDropdownMenu( - show_position_selector, - { show_position_selector = false }, - ThemeSettings.VideoPosition.entries.size, - (song_video_position ?: default_video_position).ordinal, - { - Text(ThemeSettings.VideoPosition.entries[it].getReadable()) + title = stringResource(Res.string.song_theme_menu_video_position), + isOpen = show_position_selector, + onDismissRequest = { show_position_selector = false }, + items = ThemeSettings.VideoPosition.entries, + selectedItem = song_video_position ?: default_video_position, + onSelected = { _, position -> + song_video_position = position + show_position_selector = false } - ) { - song_video_position = ThemeSettings.VideoPosition.entries[it] - show_position_selector = false + ) { position -> + Text(position.getReadable()) } FlowRow( @@ -207,21 +208,21 @@ class SongThemePlayerOverlayMenu( ValueSlider( song.BackgroundImageOpacity.observe(player.database), - player.settings.theme.NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY.getDefaultValueComposable(), + player.settings.Theme.NOWPLAYING_DEFAULT_BACKGROUND_IMAGE_OPACITY.getDefaultValue(), stringResource(Res.string.song_theme_menu_background_image_opacity) ) if (player.form_factor == FormFactor.LANDSCAPE) { ValueSlider( song.LandscapeQueueOpacity.observe(player.database), - player.settings.theme.NOWPLAYING_DEFAULT_LANDSCAPE_QUEUE_OPACITY.getDefaultValueComposable(), + player.settings.Theme.NOWPLAYING_DEFAULT_LANDSCAPE_QUEUE_OPACITY.getDefaultValue(), stringResource(Res.string.song_theme_menu_queue_opacity) ) } ValueSlider( song.ShadowRadius.observe(player.database), - player.settings.theme.NOWPLAYING_DEFAULT_SHADOW_RADIUS.getDefaultValueComposable(), + player.settings.Theme.NOWPLAYING_DEFAULT_SHADOW_RADIUS.getDefaultValue(), stringResource(Res.string.song_theme_menu_image_shadow_radius) ) @@ -264,7 +265,7 @@ private fun ValueSlider(value_state: MutableState, default_value: Float, Text((current_value * 100).roundToInt().toString().padStart(3, ' '), fontSize = 15.sp) } - val slider_colour: Color = player.theme.on_background + val slider_colour: Color = player.theme.onBackground Row(horizontalArrangement = Arrangement.spacedBy(5.dp)) { Slider( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/CoreLyricsDisplay.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/CoreLyricsDisplay.kt index dba5f9c99..fb29476b1 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/CoreLyricsDisplay.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/CoreLyricsDisplay.kt @@ -17,10 +17,10 @@ import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.HorizontalFuriganaText import com.toasterofbread.spmp.ui.layout.nowplaying.NOW_PLAYING_MAIN_PADDING_DP import com.toasterofbread.spmp.youtubeapi.lyrics.LyricsFuriganaTokeniser -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.common.thenWith -import dev.toastbits.composekit.utils.composable.workingAnimateScrollToItem +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.util.thenWith +import dev.toastbits.composekit.components.utils.composable.workingAnimateScrollToItem import kotlinx.coroutines.delay @Composable @@ -38,8 +38,8 @@ fun CoreLyricsDisplay( val density: Density = LocalDensity.current val lyrics_sync_offset: Long? by song.getLyricsSyncOffset(player.database, false) - val romanise_furigana: Boolean by player.settings.lyrics.ROMANISE_FURIGANA.observe() - val add_padding: Boolean by player.settings.lyrics.EXTRA_PADDING.observe() + val romanise_furigana: Boolean by player.settings.Lyrics.ROMANISE_FURIGANA.observe() + val add_padding: Boolean by player.settings.Lyrics.EXTRA_PADDING.observe() var area_size: Dp by remember { mutableStateOf(0.dp) } val size_px: Float = with(density) { ((area_size - (NOW_PLAYING_MAIN_PADDING_DP.dp * 2) - (15.dp * getExpansion() * 2)).value * 0.9.dp).toPx() } @@ -55,7 +55,7 @@ fun CoreLyricsDisplay( var tokenised_lines: List>? by remember { mutableStateOf(null) } suspend fun getScrollOffset(follow_offset: Float? = null): Int = - (padding_height - static_scroll_offset - size_px * (follow_offset ?: player.settings.lyrics.FOLLOW_OFFSET.get())).toInt() + (padding_height - static_scroll_offset - size_px * (follow_offset ?: player.settings.Lyrics.FOLLOW_OFFSET.get())).toInt() LaunchedEffect(lyrics, romanise_furigana) { val tokeniser: LyricsFuriganaTokeniser? = LyricsFuriganaTokeniser.getInstance() @@ -86,7 +86,7 @@ fun CoreLyricsDisplay( } } - val font_size_percent: Float by player.settings.lyrics.FONT_SIZE.observe() + val font_size_percent: Float by player.settings.Lyrics.FONT_SIZE.observe() val font_size: TextUnit = (10 + (font_size_percent * 20)).sp val text_style: TextStyle = getLyricsTextStyle(font_size) @@ -111,7 +111,7 @@ fun CoreLyricsDisplay( } } - val text_alignment: Int by player.settings.lyrics.TEXT_ALIGNMENT.observe() + val text_alignment: Int by player.settings.Lyrics.TEXT_ALIGNMENT.observe() LazyColumn( Modifier diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsOverlayMenu.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsOverlayMenu.kt index d1289f8c6..0d7738200 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsOverlayMenu.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsOverlayMenu.kt @@ -12,7 +12,6 @@ import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material.icons.outlined.Info -import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.* @@ -20,9 +19,9 @@ import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.* -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.util.platform.launchSingle +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import com.toasterofbread.spmp.model.lyrics.SongLyrics import com.toasterofbread.spmp.model.mediaitem.loader.SongLyricsLoader import com.toasterofbread.spmp.model.mediaitem.song.Song @@ -64,7 +63,7 @@ class LyricsPlayerOverlayMenu: PlayerOverlayMenu() { val pill_menu: PillMenu = remember { PillMenu(expand_state = mutableStateOf(false)) } val lyrics_state: SongLyricsLoader.ItemState = SongLyricsLoader.rememberItemState(song, player.context) - var show_furigana: Boolean by player.settings.lyrics.DEFAULT_FURIGANA.observe() + var show_furigana: Boolean by player.settings.Lyrics.DEFAULT_FURIGANA.observe() var submenu: Submenu? by remember { mutableStateOf(null) } var lyrics_sync_line_index: Int? by remember { mutableStateOf(null) } @@ -230,7 +229,7 @@ class LyricsPlayerOverlayMenu: PlayerOverlayMenu() { } else if (lyrics != null) { Box(Modifier.fillMaxSize()) { - val lyrics_follow_enabled: Boolean by player.settings.lyrics.FOLLOW_ENABLED.observe() + val lyrics_follow_enabled: Boolean by player.settings.Lyrics.FOLLOW_ENABLED.observe() CoreLyricsDisplay( lyrics, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsSearchMenu.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsSearchMenu.kt index 11c7f5c21..e94f8a424 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsSearchMenu.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsSearchMenu.kt @@ -1,6 +1,7 @@ package com.toasterofbread.spmp.ui.layout.nowplaying.overlay.lyrics import LocalPlayerState +import PlatformIO import SpMp import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.Crossfade @@ -38,8 +39,8 @@ import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextField -import androidx.compose.material3.TextFieldDefaults import androidx.compose.material3.TextFieldColors +import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue @@ -48,43 +49,41 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.getValue -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu -import dev.toastbits.composekit.utils.composable.OnChangedEffect -import com.toasterofbread.spmp.model.mediaitem.song.Song +import com.toasterofbread.spmp.db.Database import com.toasterofbread.spmp.model.mediaitem.artist.Artist +import com.toasterofbread.spmp.model.mediaitem.song.Song +import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.apppage.mainpage.appTextField import com.toasterofbread.spmp.youtubeapi.lyrics.LyricsReference import com.toasterofbread.spmp.youtubeapi.lyrics.LyricsSource -import com.toasterofbread.spmp.service.playercontroller.PlayerState -import com.toasterofbread.spmp.db.Database +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu +import dev.toastbits.composekit.theme.core.onAccent +import dev.toastbits.composekit.util.composable.OnChangedEffect +import dev.toastbits.composekit.util.composable.getValue import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import PlatformIO -import androidx.compose.ui.graphics.Color -import dev.toastbits.composekit.platform.ReentrantLock -import dev.toastbits.composekit.platform.synchronized -import dev.toastbits.composekit.settings.ui.on_accent -import dev.toastbits.composekit.settings.ui.vibrant_accent import kotlinx.io.IOException import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res +import spmp.shared.generated.resources.action_cancel +import spmp.shared.generated.resources.action_close +import spmp.shared.generated.resources.action_confirm_action +import spmp.shared.generated.resources.artist +import spmp.shared.generated.resources.lyrics_no_lyrics_set_confirmation_title import spmp.shared.generated.resources.lyrics_none_found import spmp.shared.generated.resources.`lyrics_search_on_$source` -import spmp.shared.generated.resources.action_confirm_action -import spmp.shared.generated.resources.action_cancel +import spmp.shared.generated.resources.lyrics_source_cannot_search +import spmp.shared.generated.resources.lyrics_source_dialog_title import spmp.shared.generated.resources.prompt_confirm_action -import spmp.shared.generated.resources.lyrics_no_lyrics_set_confirmation_title import spmp.shared.generated.resources.song_name -import spmp.shared.generated.resources.artist -import spmp.shared.generated.resources.lyrics_source_cannot_search -import spmp.shared.generated.resources.action_close +import java.util.concurrent.locks.ReentrantLock import kotlin.time.Duration.Companion.milliseconds private const val LYRICS_SEARCH_RETRY_COUNT = 3 @@ -102,7 +101,7 @@ fun LyricsSearchMenu( val song_artists: List? by song.Artists.observe(db) val song_artist_title: String? by song_artists?.firstOrNull()?.observeActiveTitle() - val on_accent: Color = player.theme.on_accent + val onAccent: Color = player.theme.onAccent val accent: Color = player.theme.accent val load_lock: ReentrantLock = remember { ReentrantLock() } @@ -112,13 +111,13 @@ fun LyricsSearchMenu( TextFieldDefaults.colors( focusedContainerColor = accent.copy(alpha = 0.75f), unfocusedContainerColor = accent.copy(alpha = 0.75f), - focusedTextColor = on_accent, - unfocusedTextColor = on_accent, - focusedLabelColor = on_accent, - unfocusedLabelColor = on_accent, - focusedTrailingIconColor = on_accent, - unfocusedTrailingIconColor = on_accent, - cursorColor = on_accent, + focusedTextColor = onAccent, + unfocusedTextColor = onAccent, + focusedLabelColor = onAccent, + unfocusedLabelColor = onAccent, + focusedTrailingIconColor = onAccent, + unfocusedTrailingIconColor = onAccent, + cursorColor = onAccent, focusedIndicatorColor = accent, unfocusedIndicatorColor = accent.copy(alpha = 0.5f) ) @@ -130,7 +129,7 @@ fun LyricsSearchMenu( val artist = remember (song_artist_title) { mutableStateOf(TextFieldValue(song_artist_title ?: "")) } var search_state: Boolean by remember { mutableStateOf(false) } - val default_source: Int by player.settings.lyrics.DEFAULT_SOURCE.observe() + val default_source: Int by player.settings.Lyrics.DEFAULT_SOURCE.observe() var selected_source: LyricsSource by remember { mutableStateOf(LyricsSource.fromIdx(default_source)) } var search_results: Pair, Int>? by remember { mutableStateOf(null) } @@ -225,26 +224,26 @@ fun LyricsSearchMenu( .clickable { source_selector_open = !source_selector_open }, verticalAlignment = Alignment.CenterVertically ) { - Icon(Icons.Default.ArrowDropDown, null, tint = on_accent) + Icon(Icons.Default.ArrowDropDown, null, tint = onAccent) Text( stringResource(Res.string.`lyrics_search_on_$source`) .replace("\$source", selected_source.getReadable()), - color = on_accent + color = onAccent ) LargeDropdownMenu( - source_selector_open, - { source_selector_open = false }, - LyricsSource.SOURCE_AMOUNT, - selected_source.source_index, - { source_idx -> - Text(LyricsSource.fromIdx(source_idx).getReadable()) - }, - selected_border_colour = player.theme.vibrant_accent + title = stringResource(Res.string.lyrics_source_dialog_title), + isOpen = source_selector_open, + onDismissRequest = { source_selector_open = false }, + items = (0 until LyricsSource.SOURCE_AMOUNT).toList(), + selectedItem = selected_source.source_index, + onSelected = { _, source_idx -> + selected_source = LyricsSource.fromIdx(source_idx) + source_selector_open = false + } ) { source_idx -> - selected_source = LyricsSource.fromIdx(source_idx) - source_selector_open = false + Text(LyricsSource.fromIdx(source_idx).getReadable()) } } @@ -258,7 +257,7 @@ fun LyricsSearchMenu( Icon( Icons.Default.CommentsDisabled, null, - tint = on_accent + tint = onAccent ) } @@ -373,7 +372,7 @@ fun LyricsSearchMenu( .weight(1f), colors = ButtonDefaults.buttonColors( containerColor = player.theme.accent, - contentColor = on_accent + contentColor = onAccent ) ) { Text(stringResource(Res.string.action_close)) @@ -405,7 +404,7 @@ fun LyricsSearchMenu( else 3 ) { icon -> when (icon) { - 0 -> CircularProgressIndicator(Modifier.requiredSize(22.dp), color = on_accent, strokeWidth = 3.dp) + 0 -> CircularProgressIndicator(Modifier.requiredSize(22.dp), color = onAccent, strokeWidth = 3.dp) else -> { Icon( when (icon) { @@ -414,7 +413,7 @@ fun LyricsSearchMenu( else -> Icons.Default.Edit }, null, - tint = on_accent + tint = onAccent ) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsSearchResults.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsSearchResults.kt index 3a0375fa3..8da30ec30 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsSearchResults.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/LyricsSearchResults.kt @@ -25,14 +25,14 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.platform.composable.BackHandler -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.Marquee +import dev.toastbits.composekit.components.platform.composable.BackHandler +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.composable.Marquee import com.toasterofbread.spmp.model.lyrics.SongLyrics import com.toasterofbread.spmp.resources.stringResourceTODO import com.toasterofbread.spmp.youtubeapi.lyrics.LyricsSource import com.toasterofbread.spmp.youtubeapi.lyrics.LyricsSource.SearchResult -import dev.toastbits.composekit.settings.ui.on_accent +import dev.toastbits.composekit.theme.core.onAccent import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.lyrics_no_more_results @@ -85,7 +85,7 @@ internal fun ColumnScope.LyricsSearchResults(results_and_source: Pair { var sync_offset: Long? by song.LyricsSyncOffset.observe(LocalPlayerState.current.database) @@ -105,7 +105,7 @@ internal fun SpecialModeMenu(special_mode: SpecialMode?, song: Song, setMode: (S WidthShrinkText( stringResource(Res.string.lyrics_sync_long_press_line), Modifier.fillMaxWidth().weight(1f), - style = LocalTextStyle.current.copy(color = player.theme.on_accent) + style = LocalTextStyle.current.copy(color = player.theme.onAccent) ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/Terms.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/Terms.kt index 56357f382..c0e660f99 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/Terms.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/lyrics/Terms.kt @@ -1,13 +1,12 @@ package com.toasterofbread.spmp.ui.layout.nowplaying.overlay.lyrics import com.toasterofbread.spmp.model.lyrics.SongLyrics -import com.toasterofbread.spmp.model.settings.Settings import com.toasterofbread.spmp.platform.AppContext internal suspend fun getTermRangeOfTime(context: AppContext, lyrics: SongLyrics, time: Long): Pair { require(lyrics.synced) - val enable_word_sync: Boolean = context.settings.lyrics.ENABLE_WORD_SYNC.get() + val enable_word_sync: Boolean = context.settings.Lyrics.ENABLE_WORD_SYNC.get() var start: Int? = null var end: Int? = null diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/DropdownOption.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/DropdownOption.kt index b844e0463..53eff5bdd 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/DropdownOption.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/DropdownOption.kt @@ -18,16 +18,17 @@ import com.toasterofbread.spmp.model.mediaitem.db.Property import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.settings.Settings import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.utils.composable.LargeDropdownMenu +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.components.utils.composable.LargeDropdownMenu import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.stringResource internal abstract class DropdownOption>( val entries: List, val getEntryText: @Composable (T) -> String, override val titleResource: StringResource, override val icon: ImageVector, - val getProperty: Settings.() -> PreferencesProperty, + val getProperty: Settings.() -> PlatformSettingsProperty, val getSongProperty: Song.() -> Property ): SongThemeOption() { @Composable @@ -39,16 +40,17 @@ internal abstract class DropdownOption>( var show_position_selector: Boolean by remember { mutableStateOf(false) } LargeDropdownMenu( - show_position_selector, - { show_position_selector = false }, - entries.size, - (song_value ?: global_value).ordinal, - { - Text(getEntryText(entries[it])) + title = stringResource(titleResource), + isOpen = show_position_selector, + onDismissRequest = { show_position_selector = false }, + items = entries, + selectedItem = song_value ?: global_value, + onSelected = { _, item -> + song_value = item + show_position_selector = false } - ) { - song_value = entries[it] - show_position_selector = false + ) { item -> + Text(getEntryText(item)) } FlowRow( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SliderOption.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SliderOption.kt index f3abed428..af5036b84 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SliderOption.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SliderOption.kt @@ -33,8 +33,8 @@ import com.toasterofbread.spmp.model.mediaitem.db.Property import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.settings.Settings import com.toasterofbread.spmp.service.playercontroller.PlayerState -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.utils.composable.OnChangedEffect +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.util.composable.OnChangedEffect import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import org.jetbrains.compose.resources.StringResource @@ -43,7 +43,7 @@ import kotlin.math.roundToInt internal abstract class SliderOption( override val titleResource: StringResource, override val icon: ImageVector, - val getProperty: Settings.() -> PreferencesProperty, + val getProperty: Settings.() -> PlatformSettingsProperty, val getSongProperty: Song.() -> Property ): SongThemeOption() { @@ -81,7 +81,7 @@ internal abstract class SliderOption( ) } - val slider_colour: Color = player.theme.on_background + val slider_colour: Color = player.theme.onBackground Row(horizontalArrangement = Arrangement.spacedBy(5.dp)) { Slider( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SongThemeOption.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SongThemeOption.kt index 5732823ba..8adfd151b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SongThemeOption.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SongThemeOption.kt @@ -91,49 +91,49 @@ internal abstract class SongThemeOption { private object CornerRadius: SliderOption( Res.string.song_theme_menu_corner_radius, Icons.Default.RoundedCorner, - { theme.NOWPLAYING_DEFAULT_IMAGE_CORNER_ROUNDING }, + { Theme.NOWPLAYING_DEFAULT_IMAGE_CORNER_ROUNDING }, { ThumbnailRounding } ) private object PlayerGradientDepth: SliderOption( Res.string.song_theme_menu_gradient_depth, Icons.Default.Gradient, - { theme.NOWPLAYING_DEFAULT_GRADIENT_DEPTH }, + { Theme.NOWPLAYING_DEFAULT_GRADIENT_DEPTH }, { PlayerGradientDepth } ) private object BackgroundWaveSpeed: SliderOption( Res.string.song_theme_menu_wave_speed, Icons.Default.Speed, - { theme.NOWPLAYING_DEFAULT_WAVE_SPEED }, + { Theme.NOWPLAYING_DEFAULT_WAVE_SPEED }, { BackgroundWaveSpeed } ) private object BackgroundWaveOpacity: SliderOption( Res.string.song_theme_menu_wave_opacity, Icons.Default.Opacity, - { theme.NOWPLAYING_DEFAULT_WAVE_OPACITY }, + { Theme.NOWPLAYING_DEFAULT_WAVE_OPACITY }, { BackgroundWaveOpacity } ) private object BackgroundImageOpacity: SliderOption( Res.string.song_theme_menu_background_image_opacity, Icons.Default.Opacity, - { theme.NOWPLAYING_DEFAULT_LANDSCAPE_QUEUE_OPACITY }, + { Theme.NOWPLAYING_DEFAULT_LANDSCAPE_QUEUE_OPACITY }, { BackgroundImageOpacity } ) private object LandscapeQueueOpacity: SliderOption( Res.string.song_theme_menu_queue_opacity, Icons.Default.Opacity, - { theme.NOWPLAYING_DEFAULT_SHADOW_RADIUS }, + { Theme.NOWPLAYING_DEFAULT_SHADOW_RADIUS }, { LandscapeQueueOpacity } ) private object ShadowRadius: SliderOption( Res.string.song_theme_menu_image_shadow_radius, Icons.Default.Scale, - { theme.NOWPLAYING_DEFAULT_SHADOW_RADIUS }, + { Theme.NOWPLAYING_DEFAULT_SHADOW_RADIUS }, { ShadowRadius } ) @@ -142,7 +142,7 @@ internal abstract class SongThemeOption { { it.getReadable() }, Res.string.song_theme_menu_video_position, Icons.Default.FitScreen, - { theme.NOWPLAYING_DEFAULT_VIDEO_POSITION }, + { Theme.NOWPLAYING_DEFAULT_VIDEO_POSITION }, { VideoPosition } ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SongThemeOverlayMenu.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SongThemeOverlayMenu.kt index e3f9f67a0..0937ad4ff 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SongThemeOverlayMenu.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/overlay/songtheme/SongThemeOverlayMenu.kt @@ -23,7 +23,7 @@ import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.platform.createImageBitmapUtil -import dev.toastbits.composekit.utils.common.generatePalette +import dev.toastbits.composekit.util.generatePalette import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingPage import com.toasterofbread.spmp.ui.layout.nowplaying.getNPBackground @@ -32,8 +32,8 @@ import com.toasterofbread.spmp.ui.layout.nowplaying.maintab.thumbnailrow.Colourp import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.NotifImagePlayerOverlayMenu import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.PlayerOverlayMenu import com.toasterofbread.spmp.ui.layout.nowplaying.overlay.notifImagePlayerOverlayMenuButtonText -import dev.toastbits.composekit.platform.composable.ScrollBarLazyColumn -import dev.toastbits.composekit.utils.common.thenIf +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyColumn +import dev.toastbits.composekit.util.thenIf import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource @@ -142,7 +142,7 @@ class SongThemePlayerOverlayMenu( .thenIf(index + 1 != sections.size) { padding(bottom = 20.dp) } - .border(1.dp, player.theme.on_background, RoundedCornerShape(5.dp)) + .border(1.dp, player.theme.onBackground, RoundedCornerShape(5.dp)) .padding(5.dp) ) { for (item in items) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/CurrentRadioIndicator.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/CurrentRadioIndicator.kt index 3dd1def1d..26b5e263b 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/CurrentRadioIndicator.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/CurrentRadioIndicator.kt @@ -17,8 +17,8 @@ import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.modifier.background +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.modifier.background import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.enums.MediaItemType import com.toasterofbread.spmp.model.mediaitem.fromUid diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueButtonsRow.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueButtonsRow.kt index 13a640ad4..4fbd25362 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueButtonsRow.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueButtonsRow.kt @@ -21,11 +21,11 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.TextOrIconButton -import dev.toastbits.composekit.utils.modifier.bounceOnClick +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.composable.TextOrIconButton +import dev.toastbits.composekit.components.utils.modifier.bounceOnClick import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import com.toasterofbread.spmp.ui.theme.appHover diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueItems.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueItems.kt index 159a07b7c..621c0b74a 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueItems.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueItems.kt @@ -8,7 +8,7 @@ import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.vibrateShort +import dev.toastbits.composekit.context.vibrateShort import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.layout.nowplaying.getNPAltOnBackground diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueTab.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueTab.kt index 8dec8c597..3a2e221ba 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueTab.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueTab.kt @@ -60,13 +60,13 @@ import com.toasterofbread.spmp.ui.layout.apppage.mainpage.MINIMISED_NOW_PLAYING_ import com.toasterofbread.spmp.ui.layout.nowplaying.NowPlayingTopBar import com.toasterofbread.spmp.ui.layout.nowplaying.getNPAltOnBackground import com.toasterofbread.spmp.ui.layout.nowplaying.getNPBackground -import dev.toastbits.composekit.platform.composable.ScrollBarLazyColumn -import dev.toastbits.composekit.platform.composable.composeScope -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.common.launchSingle -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.common.thenWith -import dev.toastbits.composekit.utils.modifier.background +import dev.toastbits.composekit.components.platform.composable.ScrollBarLazyColumn +import dev.toastbits.composekit.components.platform.composable.composeScope +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.platform.launchSingle +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.util.thenWith +import dev.toastbits.composekit.components.utils.modifier.background import kotlinx.coroutines.delay import org.burnoutcrew.reorderable.ReorderableLazyListState import org.burnoutcrew.reorderable.rememberReorderableLazyListState @@ -99,7 +99,7 @@ internal fun QueueTab( val scroll_coroutine_scope = rememberCoroutineScope() var key_inc by remember { mutableStateOf(0) } - val radio_info_position: NowPlayingQueueRadioInfoPosition by player.settings.player.QUEUE_RADIO_INFO_POSITION.observe() + val radio_info_position: NowPlayingQueueRadioInfoPosition by player.settings.Player.QUEUE_RADIO_INFO_POSITION.observe() val multiselect_context: MediaItemMultiSelectContext = remember { MediaItemMultiSelectContext(player.context) } val song_items: SnapshotStateList = remember { mutableStateListOf().also { list -> @@ -266,7 +266,7 @@ internal fun QueueTab( val show_border: Boolean by remember { derivedStateOf { getBackgroundOpacity() >= 1f } } if (show_border) { - val wave_border_mode_state: NowPlayingQueueWaveBorderMode by player.settings.player.QUEUE_WAVE_BORDER_MODE.observe() + val wave_border_mode_state: NowPlayingQueueWaveBorderMode by player.settings.Player.QUEUE_WAVE_BORDER_MODE.observe() wave_border_mode = wave_border_mode_override ?: wave_border_mode_state QueueBorder( @@ -302,7 +302,7 @@ internal fun QueueTab( list_position = with(density) { coords.positionInParent().y.toDp() } } ) { - val extra_side_padding: Float by player.settings.player.QUEUE_EXTRA_SIDE_PADDING.observe() + val extra_side_padding: Float by player.settings.Player.QUEUE_EXTRA_SIDE_PADDING.observe() val side_padding: Dp = maxWidth * extra_side_padding * 0.25f ScrollBarLazyColumn( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueTabItem.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueTabItem.kt index 3660cf297..f06319b53 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueTabItem.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/QueueTabItem.kt @@ -28,10 +28,10 @@ import androidx.compose.animation.core.tween import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.modifier.background +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.thenIf +import dev.toastbits.composekit.components.utils.modifier.background import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.platform.observeUiLanguage import com.toasterofbread.spmp.service.playercontroller.LocalPlayerClickOverrides @@ -40,6 +40,7 @@ import com.toasterofbread.spmp.ui.component.mediaitempreview.MediaItemPreviewLon import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.theme.appHover +import dev.toastbits.composekit.util.model.Locale import dev.toastbits.ytmkt.uistrings.durationToString import org.burnoutcrew.reorderable.ReorderableLazyListState import org.burnoutcrew.reorderable.detectReorder @@ -119,13 +120,13 @@ class QueueTabItem(val song: Song, val key: Int) { val `lpm_song_played_$x_ago`: String = stringResource(Res.string.`lpm_song_played_$x_ago`) val `lpm_song_playing_in_$x`: String = stringResource(Res.string.`lpm_song_playing_in_$x`) - val ui_langauge: String by player.context.observeUiLanguage() + val ui_language: Locale by player.context.observeUiLanguage() - return remember(delta, ui_langauge) { + return remember(delta, ui_language) { ( if (index < playing_index) `lpm_song_played_$x_ago` else `lpm_song_playing_in_$x` - ).replace("\$x", durationToString(delta, ui_langauge, true)) + ).replace("\$x", durationToString(delta, ui_language.toTag(), true)) } } @@ -143,7 +144,7 @@ class QueueTabItem(val song: Song, val key: Int) { val max_offset: Float = with(LocalDensity.current) { player.screen_size.width.toPx() } val swipe_state: AnchoredDraggableState = queueElementSwipeState(requestRemove, max_offset) - val swipe_sensitivity: Float by player.settings.player.QUEUE_ITEM_SWIPE_SENSITIVITY.observe() + val swipe_sensitivity: Float by player.settings.Player.QUEUE_ITEM_SWIPE_SENSITIVITY.observe() TouchSlopScope({ touchSlop * 2f * (2.1f - swipe_sensitivity) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/RepeatButton.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/RepeatButton.kt index 51aaea4fd..24671ac94 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/RepeatButton.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/RepeatButton.kt @@ -17,10 +17,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.common.getInnerSquareSizeOfCircle -import dev.toastbits.composekit.utils.composable.crossOut -import dev.toastbits.composekit.utils.modifier.background +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.util.getInnerSquareSizeOfCircle +import dev.toastbits.composekit.components.utils.composable.crossOut +import dev.toastbits.composekit.components.utils.modifier.background import dev.toastbits.spms.socketapi.shared.SpMsPlayerRepeatMode import com.toasterofbread.spmp.service.playercontroller.PlayerState import kotlin.math.roundToInt diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/StopAfterSongButton.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/StopAfterSongButton.kt index e88264c86..038073574 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/StopAfterSongButton.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/nowplaying/queue/StopAfterSongButton.kt @@ -20,8 +20,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.rotate import androidx.compose.ui.graphics.Color -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.modifier.background +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.modifier.background @Composable fun StopAfterSongButton(getBackgroundColour: () -> Color, modifier: Modifier = Modifier) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistAppPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistAppPage.kt index e8954c965..7622a4627 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistAppPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistAppPage.kt @@ -1,7 +1,5 @@ package com.toasterofbread.spmp.ui.layout.playlistpage -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.animateDpAsState import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Column @@ -29,17 +27,12 @@ import androidx.compose.runtime.setValue import androidx.compose.runtime.State import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.unit.dp -import androidx.compose.ui.zIndex -import dev.toastbits.composekit.platform.composable.ScrollBarLazyColumn -import dev.toastbits.composekit.platform.composable.SwipeRefresh -import dev.toastbits.composekit.utils.common.copy -import dev.toastbits.composekit.utils.common.getThemeColour -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.ScrollBarLazyColumnWithHeader +import dev.toastbits.composekit.components.platform.composable.SwipeRefresh +import dev.toastbits.composekit.util.getThemeColour +import dev.toastbits.composekit.components.utils.composable.ScrollBarLazyColumnWithHeader import com.toasterofbread.spmp.db.Database import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.MediaItemHolder @@ -55,10 +48,7 @@ import com.toasterofbread.spmp.model.mediaitem.playlist.InteractivePlaylistEdito import com.toasterofbread.spmp.model.mediaitem.playlist.InteractivePlaylistEditor.Companion.getEditorOrNull import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylist import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylistData -import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.platform.getOrNotify -import com.toasterofbread.spmp.ui.component.WAVE_BORDER_HEIGHT_DP -import com.toasterofbread.spmp.ui.component.WaveBorder import com.toasterofbread.spmp.ui.component.multiselect.MediaItemMultiSelectContext import com.toasterofbread.spmp.ui.layout.apppage.AppPageState import com.toasterofbread.spmp.ui.layout.apppage.AppPageWithItem @@ -339,7 +329,7 @@ class PlaylistAppPage( playlist_editor = new_editor } - val apply_item_filter: Boolean by player.settings.filter.APPLY_TO_PLAYLIST_ITEMS.observe() + val apply_item_filter: Boolean by player.settings.Filter.APPLY_TO_PLAYLIST_ITEMS.observe() LaunchedEffect(playlist_items, sort_type, current_filter, apply_item_filter) { sorted_items = playlist_items?.let { items -> diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistButtonBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistButtonBar.kt index e9065e35f..72349fe39 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistButtonBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistButtonBar.kt @@ -24,7 +24,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.scale import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.WidthShrinkText +import dev.toastbits.composekit.util.composable.WidthShrinkText import com.toasterofbread.spmp.model.mediaitem.db.observePinnedToHome import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylist import com.toasterofbread.spmp.model.mediaitem.song.Song @@ -34,6 +34,7 @@ import dev.toastbits.ytmkt.uistrings.durationToString import LocalPlayerState import com.toasterofbread.spmp.model.mediaitem.observeUrl import com.toasterofbread.spmp.platform.observeUiLanguage +import dev.toastbits.composekit.util.model.Locale import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.playlist_x_songs @@ -97,7 +98,7 @@ private fun PlaylistAppPage.PlaylistInfoText(items: List?, modifier: Modif val total_duration: Long? by playlist.TotalDuration.observe(db) if (item_count > 0) { - val ui_language: String by player.context.observeUiLanguage() + val ui_language: Locale by player.context.observeUiLanguage() val playlist_x_songs: String = stringResource(Res.string.playlist_x_songs) val text: String = remember(total_duration, item_count, ui_language) { @@ -125,7 +126,7 @@ private fun PlaylistAppPage.PlaylistInfoText(items: List?, modifier: Modif else ( durationToString( duration, - ui_language, + ui_language.toTag(), short = true ) + (if (incomplete_duration) "+" else "") diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistFooter.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistFooter.kt index f78e76996..6fde0db44 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistFooter.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistFooter.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import com.toasterofbread.spmp.model.mediaitem.MediaItem import dev.toastbits.ytmkt.model.external.mediaitem.MediaItemLayout import com.toasterofbread.spmp.model.mediaitem.loader.MediaItemLoader diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistInteractionBar.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistInteractionBar.kt index c33d7f345..1cd18fdff 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistInteractionBar.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistInteractionBar.kt @@ -4,22 +4,27 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.Crossfade import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.text.input.TextFieldLineLimits +import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.ResizableOutlinedTextField -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.MediaItemSortType import com.toasterofbread.spmp.ui.component.WaveBorder +import dev.toastbits.composekit.components.utils.modifier.horizontal +import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch @Composable @@ -142,12 +147,20 @@ internal fun PlaylistAppPage.PlaylistInteractionBar( @Composable private fun InteractionBarFilterBox(filter: String?, setFilter: (String?) -> Unit, modifier: Modifier = Modifier) { + val state: TextFieldState = remember { TextFieldState(filter ?: "") } + LaunchedEffect(state) { + snapshotFlow { state.text } + .collectLatest { + setFilter(it.toString().ifEmpty { null }) + } + } + Row(modifier) { - ResizableOutlinedTextField( - filter ?: "", - { setFilter(it.ifEmpty { null }) }, + OutlinedTextField( + state, Modifier.height(45.dp).fillMaxWidth().weight(1f), - singleLine = true + lineLimits = TextFieldLineLimits.SingleLine, + contentPadding = OutlinedTextFieldDefaults.contentPadding().horizontal ) IconButton( diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistItems.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistItems.kt index 2a62983a3..e467f027f 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistItems.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistItems.kt @@ -24,13 +24,14 @@ import com.toasterofbread.spmp.ui.component.mediaitempreview.getLongPressMenuDat import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.service.playercontroller.LocalPlayerClickOverrides import com.toasterofbread.spmp.service.playercontroller.PlayerClickOverrides -import dev.toastbits.composekit.utils.common.getValue +import dev.toastbits.composekit.util.composable.getValue import dev.toastbits.ytmkt.uistrings.durationToString import org.burnoutcrew.reorderable.ReorderableItem import org.burnoutcrew.reorderable.ReorderableLazyListState import org.burnoutcrew.reorderable.detectReorder import LocalPlayerState import com.toasterofbread.spmp.platform.observeUiLanguage +import dev.toastbits.composekit.util.model.Locale internal fun PlaylistAppPage.PlaylistItems( playlist: Playlist, @@ -74,11 +75,11 @@ internal fun PlaylistAppPage.PlaylistItems( show_type = false, getExtraInfo = { val item_duration: Long? by (item as? Song)?.Duration?.observe(player.database) - val ui_language: String by player.context.observeUiLanguage() + val ui_language: Locale by player.context.observeUiLanguage() remember(item_duration, ui_language) { listOfNotNull( item_duration?.let { duration -> - durationToString(duration, ui_language, true) + durationToString(duration, ui_language.toTag(), true) } ) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistTopInfo.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistTopInfo.kt index 7aa3a80a1..41f8734cc 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistTopInfo.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/PlaylistTopInfo.kt @@ -54,10 +54,10 @@ import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.coerceAtLeast import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.times -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.common.getContrasted -import dev.toastbits.composekit.utils.composable.getStart +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.util.getContrasted +import dev.toastbits.composekit.components.utils.composable.getStart import com.toasterofbread.spmp.model.mediaitem.MediaItem import dev.toastbits.ytmkt.model.external.ThumbnailProvider import com.toasterofbread.spmp.ui.component.Thumbnail diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/TopInfoEditButtons.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/TopInfoEditButtons.kt index bc89fc685..0e419de7d 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/TopInfoEditButtons.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/playlistpage/TopInfoEditButtons.kt @@ -21,8 +21,8 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.utils.composable.AlignableCrossfade -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.util.composable.AlignableCrossfade +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import com.toasterofbread.spmp.model.mediaitem.playlist.LocalPlaylistData import com.toasterofbread.spmp.model.mediaitem.playlist.Playlist import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylist diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/FilterSelectionPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/FilterSelectionPage.kt index 96de6cb06..bee5bc805 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/FilterSelectionPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/FilterSelectionPage.kt @@ -32,10 +32,10 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.platform.composable.platformClickable -import dev.toastbits.composekit.platform.vibrateShort -import dev.toastbits.composekit.utils.composable.ShapedIconButton -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.platform.composable.platformClickable +import dev.toastbits.composekit.context.vibrateShort +import dev.toastbits.composekit.components.utils.composable.ShapedIconButton +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylistData import com.toasterofbread.spmp.model.mediaitem.playlist.toRemotePlaylistData import com.toasterofbread.spmp.service.playercontroller.PlayerState @@ -49,7 +49,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import PlatformIO -import dev.toastbits.composekit.settings.ui.on_accent +import dev.toastbits.composekit.theme.core.onAccent import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res @@ -192,7 +192,7 @@ fun FilterSelectionPage( } else if (loading) { Box(Modifier.fillMaxSize().padding(content_padding), contentAlignment = Alignment.Center) { - SubtleLoadingIndicator { player.theme.on_background } + SubtleLoadingIndicator { player.theme.onBackground } } } else { @@ -234,12 +234,12 @@ fun FilterSelectionPage( Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { val icon_button_colours = IconButtonDefaults.iconButtonColors( containerColor = player.theme.accent, - contentColor = player.theme.on_accent + contentColor = player.theme.onAccent ) ShapedIconButton({ loadRadio(false) }, colours = icon_button_colours) { Crossfade(is_loading) { loading -> if (loading) { - SubtleLoadingIndicator(getColour = { player.theme.on_accent }) + SubtleLoadingIndicator(getColour = { player.theme.onAccent }) } else { Icon(Icons.Filled.PlayArrow, null) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioArtistSelector.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioArtistSelector.kt index 3d449d616..77efabd68 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioArtistSelector.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioArtistSelector.kt @@ -7,15 +7,30 @@ import androidx.compose.animation.core.AnimationVector1D import androidx.compose.foundation.border import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.itemsIndexed import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Refresh -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -24,23 +39,23 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import dev.toastbits.composekit.utils.common.times -import dev.toastbits.composekit.utils.composable.OnChangedEffect -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator -import dev.toastbits.composekit.utils.composable.crossOut import com.toasterofbread.spmp.model.mediaitem.artist.ArtistData +import com.toasterofbread.spmp.platform.FormFactor +import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.PillMenu import com.toasterofbread.spmp.ui.component.Thumbnail import com.toasterofbread.spmp.ui.component.longpressmenu.longPressMenuIcon import com.toasterofbread.spmp.ui.component.mediaitempreview.getArtistThumbShape import com.toasterofbread.spmp.ui.component.mediaitempreview.getLongPressMenuData -import com.toasterofbread.spmp.service.playercontroller.PlayerState -import com.toasterofbread.spmp.platform.FormFactor +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.components.utils.composable.crossOut +import dev.toastbits.composekit.util.composable.OnChangedEffect +import dev.toastbits.composekit.util.composable.times import dev.toastbits.ytmkt.endpoint.RadioBuilderArtist -import dev.toastbits.ytmkt.model.external.ThumbnailProvider as YtmThumbnailProvider import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.radio_builder_next_button +import dev.toastbits.ytmkt.model.external.ThumbnailProvider as YtmThumbnailProvider @Composable internal fun RadioArtistSelector( @@ -91,7 +106,7 @@ internal fun RadioArtistSelector( Crossfade(radio_artists) { artists -> if (artists == null) { Box(modifier, contentAlignment = Alignment.Center) { - SubtleLoadingIndicator(getColour = { player.theme.on_background }) + SubtleLoadingIndicator(getColour = { player.theme.onBackground }) } } else { @@ -150,7 +165,7 @@ internal fun RadioArtistSelector( Box( Modifier .size(thumb_size + selected_border_size * border_expansion.value) - .border(1.dp, player.theme.on_background, getArtistThumbShape()) + .border(1.dp, player.theme.onBackground, getArtistThumbShape()) ) } @@ -167,7 +182,7 @@ internal fun RadioArtistSelector( Text( artist.name ?: "", fontSize = 12.sp, - color = player.theme.on_background, + color = player.theme.onBackground, maxLines = 1, lineHeight = 14.sp, overflow = TextOverflow.Ellipsis diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioBuilderPage.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioBuilderPage.kt index 6532a9d98..1d266ef5f 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioBuilderPage.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioBuilderPage.kt @@ -28,7 +28,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex -import dev.toastbits.composekit.platform.composable.BackHandler +import dev.toastbits.composekit.components.platform.composable.BackHandler import com.toasterofbread.spmp.ui.component.ErrorInfoDisplay import com.toasterofbread.spmp.ui.component.PillMenu import com.toasterofbread.spmp.ui.component.WaveBorder diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioFilters.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioFilters.kt index d9fb95e27..7fb9d8bc5 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioFilters.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/layout/radiobuilder/RadioFilters.kt @@ -24,9 +24,9 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp -import dev.toastbits.composekit.settings.ui.on_accent -import dev.toastbits.composekit.settings.ui.vibrant_accent -import dev.toastbits.composekit.utils.composable.NoRipple +import dev.toastbits.composekit.theme.core.onAccent +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.components.utils.composable.NoRipple import dev.toastbits.ytmkt.endpoint.RadioBuilderModifier import kotlinx.coroutines.launch import kotlin.math.ceil @@ -80,7 +80,7 @@ internal fun SelectionTypeRow(state: MutableState Long ): LyricsLineState? { val player: PlayerState = LocalPlayerState.current - val romanise_furigana: Boolean by player.settings.lyrics.ROMANISE_FURIGANA.observe() + val romanise_furigana: Boolean by player.settings.Lyrics.ROMANISE_FURIGANA.observe() var state: LyricsLineState? by remember { mutableStateOf(null) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/util/WaveShape.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/util/WaveShape.kt new file mode 100644 index 000000000..e49e949da --- /dev/null +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/ui/util/WaveShape.kt @@ -0,0 +1,83 @@ +package com.toasterofbread.spmp.ui.util + +import androidx.compose.ui.geometry.Rect +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Matrix +import androidx.compose.ui.graphics.Outline +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.LayoutDirection +import kotlin.math.ceil + +@Deprecated("Legacy") +data class WaveShape( + val waves: Int, + val offset: Float, + val invert: Boolean = false, + val width_multiplier: Float = 1f +): Shape { + override fun createOutline(size: Size, layoutDirection: LayoutDirection, density: Density): Outline { + val path: Path = Path() + + path.addRect(Rect(0f, 0f, size.width, size.height / 2)) + + wavePath( + path = path, + size = size, + waves = waves, + width_multiplier = width_multiplier, + offset = offset + ) + + if (invert) { + path.transform( + Matrix().apply { + scale(y = -1f) + translate(y = -size.height) + } + ) + } + + return Outline.Generic(path) + } +} + +@Deprecated("Legacy") +fun wavePath( + path: Path, + size: Size, + waves: Int, + width_multiplier: Float, + offset: Float = 0f, + fill_direction: Int = 0 +): Path { + val y_offset: Float = size.height / 2 + val half_period: Float = size.width / waves + val offset_px: Float = (offset % (size.width)) - (if (offset > 0f) size.width else 0f) + + if (fill_direction != 0) { + path.moveTo(x = offset_px, y = if (fill_direction == 1) 0f else size.height) + path.lineTo(x = offset_px, y = y_offset) + } + + path.moveTo(x = offset_px, y = y_offset) + + for (i in 0 until ceil((size.width * width_multiplier) / (half_period + 1)).toInt()) { + for (direction in listOf(-1, 1)) { + path.relativeQuadraticTo( + dx1 = half_period / 2, + dy1 = size.height / 2 * direction, + dx2 = half_period, + dy2 = 0f + ) + } + } + + if (fill_direction != 0) { + path.relativeLineTo(0f, if (fill_direction == 1) -size.height else size.height) + path.lineTo(x = offset_px, y = if (fill_direction == 1) 0f else size.height) + } + + return path +} diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/SpMpWidgetConfiguration.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/SpMpWidgetConfiguration.kt index 6bd247df1..4dc5158a7 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/SpMpWidgetConfiguration.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/SpMpWidgetConfiguration.kt @@ -68,8 +68,8 @@ data class SpMpWidgetConfiguration( ?: type.getDefaultConfiguration(context) private suspend fun SpMpWidgetType.getDefaultConfiguration(context: AppContext): SpMpWidgetConfiguration { - val base: BaseWidgetConfig = context.settings.widget.DEFAULT_BASE_WIDGET_CONFIGURATION.get() - val type: TypeWidgetConfig = context.settings.widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.get()[this] ?: this.default_config + val base: BaseWidgetConfig = context.settings.Widget.DEFAULT_BASE_WIDGET_CONFIGURATION.get() + val type: TypeWidgetConfig = context.settings.Widget.DEFAULT_TYPE_WIDGET_CONFIGURATIONS.get()[this] ?: this.default_config return createDefaultConfig(base, type) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/WidgetConfig.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/WidgetConfig.kt index d0092db6c..832bc73bb 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/WidgetConfig.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/WidgetConfig.kt @@ -18,7 +18,6 @@ import androidx.compose.material3.RadioButton import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -26,25 +25,22 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.unit.dp -import com.toasterofbread.spmp.model.settings.category.AccentColourSource import com.toasterofbread.spmp.ui.layout.apppage.settingspage.AppSliderItem import com.toasterofbread.spmp.widget.configuration.enum.WidgetSectionTheme -import dev.toastbits.composekit.platform.MutableStatePreferencesProperty -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.DropdownSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.SliderSettingsItem -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem -import dev.toastbits.composekit.utils.common.roundTo -import dev.toastbits.composekit.utils.common.thenIf -import dev.toastbits.composekit.utils.composable.OnChangedEffect -import dev.toastbits.composekit.utils.composable.WithStickySize +import dev.toastbits.composekit.components.utils.composable.WithStickySize +import dev.toastbits.composekit.settingsitem.domain.MutableStateSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.DropdownSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.SliderSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ToggleSettingsItem +import dev.toastbits.composekit.util.composable.OnChangedEffect +import dev.toastbits.composekit.util.roundTo +import dev.toastbits.composekit.util.thenIf import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.widget_config_button_use_default_value -import spmp.shared.generated.resources.widget_config_common_key_accent_colour_source import spmp.shared.generated.resources.widget_config_common_key_section_theme_opacity -import spmp.shared.generated.resources.widget_config_common_option_accent_colour_source_app import spmp.shared.generated.resources.widget_config_common_option_section_theme_mode_accent import spmp.shared.generated.resources.widget_config_common_option_section_theme_mode_background import spmp.shared.generated.resources.widget_config_common_option_section_theme_mode_transparent @@ -107,15 +103,15 @@ abstract class WidgetConfig { var show_opacity_slider: Boolean by remember { mutableStateOf(false) } val mode_state: MutableState = remember { mutableStateOf(theme.mode) } - val mode_property: PreferencesProperty = remember { - MutableStatePreferencesProperty( + val mode_property: PlatformSettingsProperty = remember { + MutableStateSettingsProperty( mode_state, { stringResource(title) }, { null } ) } val mode_item: DropdownSettingsItem = remember { - DropdownSettingsItem( + DropdownSettingsItem.ofEnumState( mode_property ) { when (it) { @@ -127,13 +123,12 @@ abstract class WidgetConfig { } val opacity_state: MutableState = remember { mutableStateOf(theme.opacity) } - val opacity_property: PreferencesProperty = remember { - MutableStatePreferencesProperty( + val opacity_property: PlatformSettingsProperty = remember { + MutableStateSettingsProperty( opacity_state, { stringResource(Res.string.widget_config_common_key_section_theme_opacity) }, { null }, - getPropertyDefaultValue = { WidgetSectionTheme.DEFAULT_OPACITY }, - getPropertyDefaultValueComposable = { WidgetSectionTheme.DEFAULT_OPACITY } + getPropertyDefaultValue = { WidgetSectionTheme.DEFAULT_OPACITY } ) } val opacity_item: SliderSettingsItem? = remember(theme.mode) { @@ -189,8 +184,8 @@ abstract class WidgetConfig { val current_state: MutableState = remember { mutableStateOf(state) } - val state_property: PreferencesProperty = remember { - MutableStatePreferencesProperty( + val state_property: PlatformSettingsProperty = remember { + MutableStateSettingsProperty( current_state, { stringResource(title) }, { null } @@ -221,13 +216,12 @@ abstract class WidgetConfig { ) { val value_state: MutableState = remember { mutableStateOf(value) } - val value_property: PreferencesProperty = remember { - MutableStatePreferencesProperty( + val value_property: PlatformSettingsProperty = remember { + MutableStateSettingsProperty( value_state, { stringResource(title) }, { null }, - getPropertyDefaultValue = { default_value }, - getPropertyDefaultValueComposable = { default_value } + getPropertyDefaultValue = { default_value } ) } @@ -244,20 +238,20 @@ abstract class WidgetConfig { }.Item(modifier) } - @Composable - protected inline fun > DropdownItem( - value: T, + protected fun DropdownItem( + value: Int, + value_count: Int, title: StringResource, modifier: Modifier, - noinline getItemName: @Composable (T) -> String, - crossinline onChanged: (T) -> Unit + getItemName: @Composable (Int) -> String, + onChanged: (Int) -> Unit ) { - val value_state: MutableState = + val value_state: MutableState = remember { mutableStateOf(value) } - val value_property: PreferencesProperty = remember { - MutableStatePreferencesProperty( + val value_property: PlatformSettingsProperty = remember { + MutableStateSettingsProperty( value_state, { stringResource(title) }, { null } @@ -267,6 +261,7 @@ abstract class WidgetConfig { remember { DropdownSettingsItem( value_property, + value_count, getItem = getItemName ) }.Item(modifier) @@ -276,6 +271,24 @@ abstract class WidgetConfig { } } + @Composable + protected inline fun > DropdownItem( + value: T, + title: StringResource, + modifier: Modifier, + noinline getItemName: @Composable (T) -> String, + crossinline onChanged: (T) -> Unit + ) { + DropdownItem( + value.ordinal, + enumValues().size, + title, + modifier, + getItemName = { getItemName(enumValues()[it]) }, + onChanged = { onChanged(enumValues()[it]) } + ) + } + @Composable protected inline fun > NullableDropdownItem( value: T?, @@ -284,36 +297,23 @@ abstract class WidgetConfig { crossinline getItemName: @Composable (T?) -> String, crossinline onChanged: (T?) -> Unit ) { - val value_state: MutableState = - remember { mutableIntStateOf(value?.ordinal?.plus(1) ?: 0) } - val value_property: PreferencesProperty = remember { - MutableStatePreferencesProperty( - value_state, - { stringResource(title) }, - { null } - ) - } - - remember { - DropdownSettingsItem( - value_property, - enumEntries().size + 1 - ) { - if (it == 0) { - getItemName(null) - } - else { - getItemName(enumEntries()[it - 1]) - } + DropdownItem( + value?.ordinal?.plus(1) ?: 0, + enumValues().size + 1, + title, + modifier, + getItemName = { + getItemName( + if (it == 0) null + else enumValues()[it - 1] + ) + }, + onChanged = { + onChanged( + if (it == 0) null + else enumEntries()[it - 1] + ) } - }.Item(modifier) - - OnChangedEffect(value_state.value) { - onChanged( - value_state.value.let { - if (it == 0) null else enumEntries()[it - 1] - } - ) - } + ) } } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/base/BaseWidgetConfig.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/base/BaseWidgetConfig.kt index d9428f59c..e9e685863 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/base/BaseWidgetConfig.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/base/BaseWidgetConfig.kt @@ -2,24 +2,35 @@ package com.toasterofbread.spmp.widget.configuration.base import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import com.toasterofbread.spmp.model.settings.category.AccentColourSource -import com.toasterofbread.spmp.model.settings.category.FontMode import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.platform.observeUiLanguage -import com.toasterofbread.spmp.ui.layout.apppage.settingspage.category.createThemeSelectorSettingsItem import com.toasterofbread.spmp.widget.SpMpWidgetType import com.toasterofbread.spmp.widget.configuration.WidgetConfig import com.toasterofbread.spmp.widget.configuration.enum.WidgetStyledBorderMode -import dev.toastbits.composekit.platform.MutableStatePreferencesProperty -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.NamedTheme -import dev.toastbits.composekit.settings.ui.ThemeValuesData -import dev.toastbits.composekit.utils.composable.OnChangedEffect +import dev.toastbits.composekit.navigation.compositionlocal.LocalNavigator +import dev.toastbits.composekit.navigation.navigator.Navigator +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.StateSettingsProperty +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.ThemeSelectorSettingsItem +import dev.toastbits.composekit.settingsitem.presentation.ui.component.theme.provider.ThemeStorageHandlerProvider +import dev.toastbits.composekit.settingsitem.presentation.ui.component.util.ThemeStorageHandlerProviderImpl +import dev.toastbits.composekit.settingsitem.presentation.ui.screen.ThemeConfirmationScreen +import dev.toastbits.composekit.settingsitem.presentation.ui.screen.ThemePickerScreen +import dev.toastbits.composekit.settingsitem.presentation.ui.screen.ThemePickerScreen.ResultHandler +import dev.toastbits.composekit.theme.config.ThemeTypeConfigProviderImpl +import dev.toastbits.composekit.theme.core.ThemeValues +import dev.toastbits.composekit.theme.core.model.ComposeKitFont +import dev.toastbits.composekit.theme.core.model.SerialisableTheme +import dev.toastbits.composekit.theme.core.model.ThemeReference +import dev.toastbits.composekit.theme.core.provider.ThemeProvider +import dev.toastbits.composekit.theme.core.provider.ThemeTypeConfigProvider +import dev.toastbits.composekit.theme.core.type.ThemeType +import dev.toastbits.composekit.theme.core.type.ThemeTypeConfig +import dev.toastbits.composekit.theme.core.ui.LocalThemeProvider +import dev.toastbits.composekit.theme.core.util.rememberAvailableFonts +import dev.toastbits.composekit.util.composable.getValue import kotlinx.serialization.Serializable import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res @@ -34,7 +45,7 @@ import spmp.shared.generated.resources.widget_config_common_key_hide_when_no_con import spmp.shared.generated.resources.widget_config_common_key_show_app_icon import spmp.shared.generated.resources.widget_config_common_key_styled_border_mode import spmp.shared.generated.resources.widget_config_common_key_theme -import spmp.shared.generated.resources.widget_config_common_option_accent_colour_source_app +import spmp.shared.generated.resources.widget_config_common_optionAccent_colour_source_app import spmp.shared.generated.resources.widget_config_common_option_content_colour_dark import spmp.shared.generated.resources.widget_config_common_option_content_colour_light import spmp.shared.generated.resources.widget_config_common_option_content_colour_theme @@ -45,9 +56,9 @@ import kotlin.math.roundToInt @Serializable data class BaseWidgetConfig( - val theme_index: Int? = null, + val theme: ThemeReference? = null, val accent_colour_source: AccentColourSource? = null, - val font: FontMode? = null, + val font: ComposeKitFont? = null, val font_size: Float = 1f, val content_colour: ContentColour = ContentColour.THEME, val background_opacity: Float = 1f, @@ -65,9 +76,9 @@ data class BaseWidgetConfig( onDefaultsMaskChanged: (BaseWidgetConfigDefaultsMask) -> Unit ) { configItem( - defaults_mask?.theme_index, + defaults_mask?.theme, item_modifier, - { onDefaultsMaskChanged(defaults_mask!!.copy(theme_index = it)) } + { onDefaultsMaskChanged(defaults_mask!!.copy(theme = it)) } ) { modifier, onItemChanged -> ThemeIndexItem(context, modifier) { onChanged(it) @@ -84,7 +95,7 @@ data class BaseWidgetConfig( Res.string.widget_config_common_key_accent_colour_source, modifier, getItemName = { - stringResource(it?.getNameResource() ?: Res.string.widget_config_common_option_accent_colour_source_app) + stringResource(it?.getNameResource() ?: Res.string.widget_config_common_optionAccent_colour_source_app) } ) { onChanged(copy(accent_colour_source = it)) @@ -96,16 +107,25 @@ data class BaseWidgetConfig( item_modifier, { onDefaultsMaskChanged(defaults_mask!!.copy(font = it)) } ) { modifier, onItemChanged -> - val ui_language: String by context.observeUiLanguage() - NullableDropdownItem( - font, + val available_fonts: List = ComposeKitFont.rememberAvailableFonts() + + DropdownItem( + if (font == null) 0 else (available_fonts.indexOf(font) + 1), + available_fonts.size + 1, Res.string.widget_config_common_key_font, modifier, getItemName = { - it?.getReadable(ui_language) ?: stringResource(Res.string.widget_config_common_option_font_app) + if (it == 0) stringResource(Res.string.widget_config_common_option_font_app) + else available_fonts[it - 1].getDisplayName() } ) { - onChanged(copy(font = it)) + onChanged( + copy( + font = + if (it == 0) null + else available_fonts[it - 1] + ) + ) onItemChanged() } } @@ -234,42 +254,94 @@ data class BaseWidgetConfig( @Composable private fun ThemeIndexItem(context: AppContext, modifier: Modifier, onChanged: (BaseWidgetConfig) -> Unit) { - val theme_index_state: MutableState = - remember { mutableIntStateOf(theme_index?.plus(1) ?: 0) } - val theme_index_property: PreferencesProperty = remember { - MutableStatePreferencesProperty( - theme_index_state, - { stringResource(Res.string.widget_config_common_key_theme) }, - { null } + val navigator: Navigator = LocalNavigator.current + val themeProvider: ThemeProvider = LocalThemeProvider.current + + val widget_application_theme_label: String = + stringResource(Res.string.widget_application_theme_label) + val application_theme_reference: ThemeReference = + remember { ThemeReference.CustomTheme(-1) } + + val current_application_theme: ThemeReference? by context.settings.Theme.CURRENT_THEME.observe() + + val theme_property: PlatformSettingsProperty = + remember { + StateSettingsProperty( + initialValue = theme ?: application_theme_reference, + onValueSet = { value -> + onChanged( + this.copy( + theme = + if (value == application_theme_reference) null + else value + ) + ) + }, + getPropertyName = { stringResource(Res.string.widget_config_common_key_theme) }, + getPropertyDescription = { null } + ) + } + + fun ThemeType.ThemeAndType.callResultHandler( + resultHandler: ResultHandler, + navigator: Navigator, + storageHandlerProvider: ThemeStorageHandlerProvider, + themeTypeConfigProvider: ThemeTypeConfigProvider + ) { + resultHandler.onResult( + navigator, + theme, + themeTypeConfigProvider.getConfig(type), + storageHandlerProvider ) } - remember { - createThemeSelectorSettingsItem( - context, - theme_index_property, - getExtraStartThemes = { - listOf( - NamedTheme( - stringResource(Res.string.widget_application_theme_label), - ThemeValuesData.of(context.theme) + remember(widget_application_theme_label) { + val storageHandlerProvider: ThemeStorageHandlerProvider = + ThemeStorageHandlerProviderImpl(theme_property, context.settings.Theme.CUSTOM_THEMES) + + val pickerResultProvider: ResultHandler = + object : ThemePickerScreen.ResultHandler { + override fun onResult( + navigator: Navigator, + initialTheme: T, + config: ThemeTypeConfig, + themeStorageHandlerProvider: ThemeStorageHandlerProvider + ) { + navigator.pushScreen( + ThemeConfirmationScreen( + initialTheme, + config, + themeStorageHandlerProvider(config.type), + onFinished = { + navigator.navigateBackward(2) + } + ) ) - ) + } } - ) - }.Item(modifier) - OnChangedEffect(theme_index_state.value) { - onChanged( - this.copy( - theme_index = - theme_index_state.value.let { index -> - if (index <= 0) null - else index - 1 + ThemeSelectorSettingsItem( + currentThemeProperty = theme_property, + customThemesProperty = context.settings.Theme.CUSTOM_THEMES, + canSelectThemesDirectly = false, + themeStorageHandlerProvider = storageHandlerProvider, + extraThemes = + listOf( + application_theme_reference + ), + onExtraThemeEdited = { + if (it != 0) { + return@ThemeSelectorSettingsItem } - ) + + onChanged(this.copy(theme = null)) + navigator.navigateBackward() + }, + themeTypeConfigProvider = ThemeTypeConfigProviderImpl, + pickerResultHandler = pickerResultProvider ) - } + }.Item(modifier) } enum class ContentColour { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/base/BaseWidgetConfigDefaultsMask.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/base/BaseWidgetConfigDefaultsMask.kt index 6b5f1fd11..1f9cf262f 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/base/BaseWidgetConfigDefaultsMask.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/base/BaseWidgetConfigDefaultsMask.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.Serializable @Serializable data class BaseWidgetConfigDefaultsMask( - val theme_index: Boolean = true, + val theme: Boolean = true, val accent_colour_source: Boolean = true, val font: Boolean = true, val font_size: Boolean = true, @@ -17,7 +17,7 @@ data class BaseWidgetConfigDefaultsMask( ) { fun applyTo(config: BaseWidgetConfig, default: BaseWidgetConfig): BaseWidgetConfig = BaseWidgetConfig( - theme_index = if (this.theme_index) default.theme_index else config.theme_index, + theme = if (this.theme) default.theme else config.theme, accent_colour_source = if (this.accent_colour_source) default.accent_colour_source else config.accent_colour_source, font = if (this.font) default.font else config.font, font_size = if (this.font_size) default.font_size else config.font_size, diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/enum/WidgetSectionTheme.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/enum/WidgetSectionTheme.kt index 4491ea00b..f30294489 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/enum/WidgetSectionTheme.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/enum/WidgetSectionTheme.kt @@ -2,10 +2,10 @@ package com.toasterofbread.spmp.widget.configuration.enum import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color -import dev.toastbits.composekit.platform.composable.theme.LocalApplicationTheme -import dev.toastbits.composekit.settings.ui.vibrant_accent -import dev.toastbits.composekit.utils.common.blendWith -import dev.toastbits.composekit.utils.common.thenIf +import dev.toastbits.composekit.theme.core.ui.LocalComposeKitTheme +import dev.toastbits.composekit.theme.core.vibrantAccent +import dev.toastbits.composekit.util.blendWith +import dev.toastbits.composekit.util.thenIf import kotlinx.serialization.Serializable @Serializable @@ -28,7 +28,7 @@ val WidgetSectionTheme.colour: Color val WidgetSectionTheme.Mode.colour: Color @Composable - get() = with (LocalApplicationTheme.current) { + get() = with (LocalComposeKitTheme.current) { when (this@colour) { WidgetSectionTheme.Mode.BACKGROUND -> background WidgetSectionTheme.Mode.ACCENT -> card.blendWith(accent, 0.2f) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/LyricsWidgetConfig.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/LyricsWidgetConfig.kt index 1a8894609..560a4f7c3 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/LyricsWidgetConfig.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/LyricsWidgetConfig.kt @@ -9,10 +9,10 @@ import androidx.compose.ui.Modifier import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.widget.action.LyricsWidgetClickAction import com.toasterofbread.spmp.widget.action.WidgetClickAction -import dev.toastbits.composekit.platform.MutableStatePreferencesProperty -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.DropdownSettingsItem -import dev.toastbits.composekit.utils.composable.OnChangedEffect +import dev.toastbits.composekit.settingsitem.domain.MutableStateSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.DropdownSettingsItem +import dev.toastbits.composekit.util.composable.OnChangedEffect import kotlinx.serialization.Serializable import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource @@ -69,8 +69,8 @@ internal data class LyricsWidgetConfig( private fun FuriganaModeItem(modifier: Modifier, onChanged: (TypeWidgetConfig) -> Unit) { val furigana_mode_state: MutableState = remember { mutableStateOf(furigana_mode) } - val furigana_mode_property: PreferencesProperty = remember { - MutableStatePreferencesProperty( + val furigana_mode_property: PlatformSettingsProperty = remember { + MutableStateSettingsProperty( furigana_mode_state, { stringResource(Res.string.widget_config_lyrics_key_furigana_mode) }, { null } @@ -82,7 +82,7 @@ internal data class LyricsWidgetConfig( } remember { - DropdownSettingsItem(furigana_mode_property) { mode -> + DropdownSettingsItem.ofEnumState(furigana_mode_property) { mode -> when (mode) { FuriganaMode.APP_DEFAULT -> stringResource(Res.string.widget_config_lyrics_option_furigana_mode_app) FuriganaMode.SHOW -> stringResource(Res.string.widget_config_lyrics_option_furigana_mode_show) diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/SongQueueWidgetConfig.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/SongQueueWidgetConfig.kt index 3a43c0ae0..b6dc3b61d 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/SongQueueWidgetConfig.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/SongQueueWidgetConfig.kt @@ -2,19 +2,10 @@ package com.toasterofbread.spmp.widget.configuration.type import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import com.toasterofbread.spmp.platform.AppContext -import com.toasterofbread.spmp.ui.layout.apppage.settingspage.AppSliderItem import com.toasterofbread.spmp.widget.action.SongQueueWidgetClickAction import com.toasterofbread.spmp.widget.action.WidgetClickAction -import dev.toastbits.composekit.platform.MutableStatePreferencesProperty -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.ToggleSettingsItem -import dev.toastbits.composekit.utils.composable.OnChangedEffect import kotlinx.serialization.Serializable import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/TypeWidgetConfig.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/TypeWidgetConfig.kt index 07d00d7a6..3225f7566 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/TypeWidgetConfig.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/type/TypeWidgetConfig.kt @@ -10,10 +10,10 @@ import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.widget.action.TypeWidgetClickAction import com.toasterofbread.spmp.widget.action.WidgetClickAction import com.toasterofbread.spmp.widget.configuration.WidgetConfig -import dev.toastbits.composekit.platform.MutableStatePreferencesProperty -import dev.toastbits.composekit.platform.PreferencesProperty -import dev.toastbits.composekit.settings.ui.component.item.DropdownSettingsItem -import dev.toastbits.composekit.utils.composable.OnChangedEffect +import dev.toastbits.composekit.settingsitem.domain.MutableStateSettingsProperty +import dev.toastbits.composekit.settingsitem.domain.PlatformSettingsProperty +import dev.toastbits.composekit.settingsitem.presentation.ui.component.item.DropdownSettingsItem +import dev.toastbits.composekit.util.composable.OnChangedEffect import kotlinx.serialization.Serializable import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource @@ -84,8 +84,8 @@ sealed class TypeWidgetConfig: WidgetConfig() { val click_action_state: MutableState = remember { mutableIntStateOf(actions.indexOf(action)) } - val click_action_property: PreferencesProperty = remember { - MutableStatePreferencesProperty( + val click_action_property: PlatformSettingsProperty = remember { + MutableStateSettingsProperty( click_action_state, { stringResource(title) }, { null } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/ui/screen/WidgetConfigurationScreen.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/ui/screen/WidgetConfigurationScreen.kt index fea7845db..c90620d90 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/ui/screen/WidgetConfigurationScreen.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/widget/configuration/ui/screen/WidgetConfigurationScreen.kt @@ -31,16 +31,15 @@ import androidx.compose.ui.unit.dp import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.widget.SpMpWidgetType import com.toasterofbread.spmp.widget.action.TypeWidgetClickAction +import com.toasterofbread.spmp.widget.configuration.SpMpWidgetConfiguration import com.toasterofbread.spmp.widget.configuration.base.BaseWidgetConfig import com.toasterofbread.spmp.widget.configuration.base.BaseWidgetConfigDefaultsMask -import com.toasterofbread.spmp.widget.configuration.SpMpWidgetConfiguration import com.toasterofbread.spmp.widget.configuration.type.TypeConfigurationDefaultsMask import com.toasterofbread.spmp.widget.configuration.type.TypeWidgetConfig -import dev.toastbits.composekit.navigation.Screen -import dev.toastbits.composekit.navigation.navigator.Navigator -import dev.toastbits.composekit.platform.composable.theme.LocalApplicationTheme -import dev.toastbits.composekit.utils.common.copy -import dev.toastbits.composekit.utils.common.thenIf +import dev.toastbits.composekit.navigation.screen.Screen +import dev.toastbits.composekit.theme.core.ui.LocalComposeKitTheme +import dev.toastbits.composekit.util.composable.copy +import dev.toastbits.composekit.util.thenIf import org.jetbrains.compose.resources.stringResource import spmp.shared.generated.resources.Res import spmp.shared.generated.resources.widget_config_button_cancel @@ -80,7 +79,7 @@ class WidgetConfigurationScreen( private var type_config: TypeWidgetConfig? by mutableStateOf(initial_type_config) @Composable - override fun Content(navigator: Navigator, modifier: Modifier, contentPadding: PaddingValues) { + override fun Content(modifier: Modifier, contentPadding: PaddingValues) { Column(modifier) { LazyColumn( Modifier.fillMaxHeight().weight(1f), @@ -210,7 +209,7 @@ class WidgetConfigurationScreen( horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically ) { - CompositionLocalProvider(LocalContentColor provides LocalApplicationTheme.current.accent) { + CompositionLocalProvider(LocalContentColor provides LocalComposeKitTheme.current.accent) { Text( name, style = MaterialTheme.typography.labelLarge diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/SpMpYoutubeiApi.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/SpMpYoutubeiApi.kt index bdfbcf5e3..073d95501 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/SpMpYoutubeiApi.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/SpMpYoutubeiApi.kt @@ -19,7 +19,7 @@ import com.toasterofbread.spmp.model.settings.unpackSetData import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.getDataLanguage import com.toasterofbread.spmp.resources.Language -import dev.toastbits.composekit.platform.PlatformPreferencesListener +import dev.toastbits.composekit.settings.PlatformSettingsListener import dev.toastbits.ytmkt.endpoint.ArtistWithParamsRow import dev.toastbits.ytmkt.endpoint.SearchResults import dev.toastbits.ytmkt.endpoint.SongFeedLoadResult @@ -63,13 +63,13 @@ internal class SpMpYoutubeiApi( override var user_auth_state: YoutubeiAuthenticationState? by mutableStateOf(null) - private val prefs_listener: PlatformPreferencesListener = - PlatformPreferencesListener { key -> + private val prefs_listener: PlatformSettingsListener = + PlatformSettingsListener { key -> when (key) { - context.settings.youtube_auth.YTM_AUTH.key -> context.coroutine_scope.launch { user_auth_state = getCurrentUserAuthState() } - context.settings.system.LANG_DATA.key -> context.coroutine_scope.launch { _data_language = context.getDataLanguage() } - context.settings.streaming.VIDEO_FORMATS_METHOD.key -> context.coroutine_scope.launch { - _VideoFormats = context.settings.streaming.VIDEO_FORMATS_METHOD.get().instantiate(this@SpMpYoutubeiApi) + context.settings.YoutubeAuth.YTM_AUTH.key -> context.coroutineScope.launch { user_auth_state = getCurrentUserAuthState() } + context.settings.Interface.DATA_LOCALE.key -> context.coroutineScope.launch { _data_language = context.getDataLanguage().toTag() } + context.settings.Streaming.VIDEO_FORMATS_METHOD.key -> context.coroutineScope.launch { + _VideoFormats = context.settings.Streaming.VIDEO_FORMATS_METHOD.get().instantiate(this@SpMpYoutubeiApi) } } } @@ -77,19 +77,19 @@ internal class SpMpYoutubeiApi( init { context.getPrefs().addListener(prefs_listener) - context.coroutine_scope.launch { + context.coroutineScope.launch { user_auth_state = getCurrentUserAuthState() } - context.coroutine_scope.launch { - _data_language = context.getDataLanguage() + context.coroutineScope.launch { + _data_language = context.getDataLanguage().toTag() } - context.coroutine_scope.launch { - _VideoFormats = context.settings.streaming.VIDEO_FORMATS_METHOD.get().instantiate(this@SpMpYoutubeiApi) + context.coroutineScope.launch { + _VideoFormats = context.settings.Streaming.VIDEO_FORMATS_METHOD.get().instantiate(this@SpMpYoutubeiApi) } } private suspend fun getCurrentUserAuthState(): SpMpYoutubeiAuthenticationState? = - ApiAuthenticationState.unpackSetData(context.settings.youtube_auth.YTM_AUTH.get(), context) + ApiAuthenticationState.unpackSetData(context.settings.YoutubeAuth.YTM_AUTH.get(), context) ?.let { data -> SpMpYoutubeiAuthenticationState(context.database, this, data.first, data.second) } diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Kugou.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Kugou.kt index f4fb1a30f..53113f931 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Kugou.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Kugou.kt @@ -22,7 +22,7 @@ internal class KugouLyricsSource(source_idx: Int): LyricsSource(source_idx) { lyrics_id: String, context: AppContext ): Result = runCatching { - val lines: List> = loadKugouLyrics(lyrics_id, context.getUiLanguage()).getOrThrow() + val lines: List> = loadKugouLyrics(lyrics_id, context.getUiLanguage().toTag()).getOrThrow() return@runCatching SongLyrics( LyricsReference(source_index, lyrics_id), diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Lyrics.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Lyrics.kt index a075a6e91..75d0c5288 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Lyrics.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Lyrics.kt @@ -2,7 +2,7 @@ package com.toasterofbread.spmp.youtubeapi.lyrics import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.db.Database import com.toasterofbread.spmp.db.mediaitem.LyricsById import com.toasterofbread.spmp.model.lyrics.SongLyrics @@ -94,7 +94,7 @@ sealed class LyricsSource(val source_index: Int) { val duration_ms: Long? = song.Duration.get(db) var fail_exception: Throwable? = null - iterateByPriority(default ?: context.settings.lyrics.DEFAULT_SOURCE.get()) { source -> + iterateByPriority(default ?: context.settings.Lyrics.DEFAULT_SOURCE.get()) { source -> var lyrics_reference: LyricsReference? = null if (source.supportsLyricsBySong()) { diff --git a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Petit.kt b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Petit.kt index e5bb1c1d3..38d0b76fe 100644 --- a/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Petit.kt +++ b/shared/src/commonMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Petit.kt @@ -6,7 +6,7 @@ import com.toasterofbread.spmp.model.lyrics.SongLyrics import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.youtubeapi.lyrics.petit.parseTimedLyrics import com.toasterofbread.spmp.youtubeapi.lyrics.petit.searchPetitLyrics -import dev.toastbits.composekit.utils.common.substringBetween +import dev.toastbits.composekit.util.substringBetween import io.ktor.client.HttpClient import io.ktor.client.plugins.expectSuccess import io.ktor.client.request.post diff --git a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/AppContext.desktop.kt b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/AppContext.desktop.kt index e0c11f321..159f813fb 100644 --- a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/AppContext.desktop.kt +++ b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/AppContext.desktop.kt @@ -7,10 +7,11 @@ import com.toasterofbread.spmp.platform.download.PlayerDownloadManager import com.toasterofbread.spmp.resources.Language import com.toasterofbread.spmp.resources.getAvailableLanguages import com.toasterofbread.spmp.youtubeapi.YtmApiType -import dev.toastbits.composekit.platform.PlatformContextImpl -import dev.toastbits.composekit.platform.PlatformPreferences -import dev.toastbits.composekit.platform.PlatformPreferencesImpl -import dev.toastbits.composekit.platform.getDesktopFilesDir +import dev.toastbits.composekit.context.PlatformContext +import dev.toastbits.composekit.context.getDesktopFilesDir +import dev.toastbits.composekit.settings.PlatformSettings +import dev.toastbits.composekit.settings.PlatformSettingsImpl +import dev.toastbits.composekit.theme.core.ThemeManager import dev.toastbits.ytmkt.model.YtmApi import kotlinx.coroutines.CoroutineScope import org.jetbrains.compose.resources.getString @@ -20,16 +21,16 @@ import spmp.shared.generated.resources.app_name actual class AppContext private constructor( app_name: String, coroutine_scope: CoroutineScope, - prefs: PlatformPreferences, + prefs: PlatformSettings, api_type: YtmApiType, api_url: String, data_language: Language, available_languages: List -): PlatformContextImpl(app_name, coroutine_scope) { +): PlatformContext(app_name, coroutine_scope) { companion object { suspend fun create(coroutine_scope: CoroutineScope): AppContext { val app_name: String = getString(Res.string.app_name) - val prefs: PlatformPreferences = PlatformPreferencesImpl.getInstance(getDesktopFilesDir(app_name).resolve("preferences.json"), ProjectJson.instance) + val prefs: PlatformSettings = PlatformSettingsImpl.getInstance(getDesktopFilesDir(app_name).resolve("preferences.json"), ProjectJson.instance) val settings: YTApiSettings = YTApiSettings(prefs) return AppContext( @@ -47,12 +48,12 @@ actual class AppContext private constructor( override suspend fun getIconImageData(): ByteArray? = Res.readBytes("drawable/ic_spmp.png") - private val _prefs: PlatformPreferences = prefs - actual fun getPrefs(): PlatformPreferences = _prefs + private val _prefs: PlatformSettings = prefs + actual fun getPrefs(): PlatformSettings = _prefs actual val database: Database = createDatabase() actual val settings: Settings = Settings(this, available_languages) actual val download_manager: PlayerDownloadManager = PlayerDownloadManager(this) actual val ytapi: YtmApi = api_type.instantiate(this, api_url, data_language) - actual val theme: AppThemeManager = AppThemeManager(this@AppContext) + actual val theme: ThemeManager = AppThemeManager(this@AppContext) } diff --git a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/ImageBitmap.desktop.kt b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/ImageBitmap.desktop.kt index 1f3df09d3..52f61544f 100644 --- a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/ImageBitmap.desktop.kt +++ b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/ImageBitmap.desktop.kt @@ -10,7 +10,7 @@ import java.awt.image.BufferedImage import java.io.ByteArrayOutputStream import java.io.IOException import javax.imageio.ImageIO -import dev.toastbits.composekit.utils.common.sortedByHue +import dev.toastbits.composekit.util.sortedByHue actual fun createImageBitmapUtil(): ImageBitmapUtil? = DesktopImageBitmapUtil() diff --git a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.desktop.kt b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.desktop.kt index f7e0b4788..038758017 100644 --- a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.desktop.kt +++ b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/download/PlayerDownloadManager.desktop.kt @@ -1,6 +1,6 @@ package com.toasterofbread.spmp.platform.download -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.platform.AppContext @@ -74,10 +74,10 @@ actual class PlayerDownloadManager actual constructor(private val context: AppCo direct: Boolean, callback: DownloadRequestCallback?, ) { - context.coroutine_scope.launch { + context.coroutineScope.launch { getDownloader().startDownload(song, silent, custom_uri, download_lyrics, direct) { download, result -> val status: DownloadStatus = download.getStatusObject() - context.coroutine_scope.launch { + context.coroutineScope.launch { if (custom_uri == null) { MediaItemLibrary.onSongFileAdded(status) } diff --git a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/ffmpeg/VideoPlayerFFmpeg.kt b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/ffmpeg/VideoPlayerFFmpeg.kt index 1704155de..ebf095fa6 100644 --- a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/ffmpeg/VideoPlayerFFmpeg.kt +++ b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/ffmpeg/VideoPlayerFFmpeg.kt @@ -16,7 +16,7 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.CancellationException -import dev.toastbits.composekit.utils.common.launchSingle +import dev.toastbits.composekit.util.platform.launchSingle @Composable fun VideoPlayerFFmpeg( diff --git a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/playerservice/LocalServer.desktop.kt b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/playerservice/LocalServer.desktop.kt index 20a1e5f39..7b10b137e 100644 --- a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/playerservice/LocalServer.desktop.kt +++ b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/playerservice/LocalServer.desktop.kt @@ -92,7 +92,7 @@ actual object LocalServer { server.bind(port) - return@runCatching context.coroutine_scope.launch(Dispatchers.IO) { + return@runCatching context.coroutineScope.launch(Dispatchers.IO) { try { while (true) { server.poll(CLIENT_REPLY_ATTEMPTS) diff --git a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMs.desktop.kt b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMs.desktop.kt index a7a17a109..d7673bbf5 100644 --- a/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMs.desktop.kt +++ b/shared/src/desktopMain/kotlin/com/toasterofbread/spmp/platform/playerservice/SpMs.desktop.kt @@ -5,8 +5,8 @@ import org.jetbrains.skiko.hostOs import java.io.File import java.lang.System.getenv import com.toasterofbread.spmp.platform.AppContext -import dev.toastbits.composekit.platform.PlatformFile -import dev.toastbits.composekit.platform.fromFile +import dev.toastbits.composekit.context.PlatformFile +import dev.toastbits.composekit.context.fromFile actual fun getSpMsMachineId(context: AppContext): String { val id_file: File = diff --git a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/LocalSongSyncLoader.jvm.kt b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/LocalSongSyncLoader.jvm.kt index 9c231a282..626496476 100644 --- a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/LocalSongSyncLoader.jvm.kt +++ b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/model/mediaitem/library/LocalSongSyncLoader.jvm.kt @@ -8,7 +8,7 @@ import com.toasterofbread.spmp.platform.playerservice.ClientServerPlayerService import com.toasterofbread.spmp.platform.AppContext import com.toasterofbread.spmp.platform.download.LocalSongMetadataProcessor import com.toasterofbread.spmp.platform.download.SongDownloader -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch diff --git a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/WebViewLogin.jvm.kt b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/WebViewLogin.jvm.kt index 40b85c798..1cda8cd96 100644 --- a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/WebViewLogin.jvm.kt +++ b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/WebViewLogin.jvm.kt @@ -37,9 +37,9 @@ import com.multiplatform.webview.web.WebViewState import com.toasterofbread.spmp.service.playercontroller.PlayerState import com.toasterofbread.spmp.ui.component.ErrorInfoDisplay import com.toasterofbread.spmp.ui.layout.apppage.mainpage.MINIMISED_NOW_PLAYING_HEIGHT_DP -import dev.toastbits.composekit.platform.Platform -import dev.toastbits.composekit.utils.composable.NullableValueAnimatedVisibility -import dev.toastbits.composekit.utils.composable.SubtleLoadingIndicator +import dev.toastbits.composekit.util.platform.Platform +import dev.toastbits.composekit.components.utils.composable.animatedvisibility.NullableValueAnimatedVisibility +import dev.toastbits.composekit.components.utils.composable.SubtleLoadingIndicator import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource diff --git a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/JAudioTaggerMetadataProcessor.kt b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/JAudioTaggerMetadataProcessor.kt index eda514b49..d5e7362d5 100644 --- a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/JAudioTaggerMetadataProcessor.kt +++ b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/JAudioTaggerMetadataProcessor.kt @@ -3,7 +3,7 @@ package com.toasterofbread.spmp.platform.download import com.toasterofbread.spmp.model.mediaitem.MediaItem import com.toasterofbread.spmp.model.mediaitem.MediaItemData import com.toasterofbread.spmp.model.mediaitem.artist.Artist -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.model.mediaitem.artist.ArtistData import com.toasterofbread.spmp.model.mediaitem.artist.ArtistRef import com.toasterofbread.spmp.model.mediaitem.playlist.RemotePlaylist diff --git a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/LocalSongMetadataProcessor.kt b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/LocalSongMetadataProcessor.kt index bfc138a7a..615c919da 100644 --- a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/LocalSongMetadataProcessor.kt +++ b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/LocalSongMetadataProcessor.kt @@ -2,7 +2,7 @@ package com.toasterofbread.spmp.platform.download import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.mediaitem.song.SongData -import dev.toastbits.composekit.platform.PlatformFile +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.platform.AppContext expect val LocalSongMetadataProcessor: MetadataProcessor diff --git a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/SongDownloader.kt b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/SongDownloader.kt index 27de123d3..6b6f11da1 100644 --- a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/SongDownloader.kt +++ b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/platform/download/SongDownloader.kt @@ -1,7 +1,6 @@ package com.toasterofbread.spmp.platform.download -import dev.toastbits.composekit.platform.PlatformFile -import dev.toastbits.composekit.platform.getPlatformForbiddenFilenameCharacters +import dev.toastbits.composekit.context.PlatformFile import com.toasterofbread.spmp.model.lyrics.LyricsFileConverter import com.toasterofbread.spmp.model.mediaitem.library.MediaItemLibrary import com.toasterofbread.spmp.model.mediaitem.loader.SongLyricsLoader @@ -9,6 +8,7 @@ import com.toasterofbread.spmp.model.mediaitem.song.Song import com.toasterofbread.spmp.model.mediaitem.song.SongAudioQuality import com.toasterofbread.spmp.model.mediaitem.song.getSongAudioFormatByQuality import com.toasterofbread.spmp.platform.AppContext +import dev.toastbits.composekit.util.platform.getPlatformForbiddenFilenameCharacters import dev.toastbits.ytmkt.model.external.YoutubeVideoFormat import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -108,8 +108,7 @@ abstract class SongDownloader( } suspend fun getDestinationFile(extension: String): PlatformFile = - custom_uri?.let { context.getUserDirectoryFile(it) } - ?: getSongStorageDir().resolve(generatePath(extension, false)) + custom_uri?.let { context.getUserDirectoryFile(it) } ?: getSongStorageDir().resolve(generatePath(extension, false)) override fun toString(): String = "Download(id=${song.id}, quality=$quality, silent=$silent, instance=$instance, file=$song_file)" @@ -121,7 +120,7 @@ abstract class SongDownloader( private var download_inc: Int = 0 private suspend fun getOrCreateDownload(song: Song, silent: Boolean, custom_uri: String?, download_lyrics: Boolean, direct: Boolean): Download { - val audio_quality = context.settings.streaming.DOWNLOAD_AUDIO_QUALITY.get() + val audio_quality = context.settings.Streaming.DOWNLOAD_AUDIO_QUALITY.get() synchronized(downloads) { for (download in downloads) { if (download.song.id == song.id) { diff --git a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Furigana.jvm.kt b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Furigana.jvm.kt index 5916b5cf2..ea0bd5b56 100644 --- a/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Furigana.jvm.kt +++ b/shared/src/jvmMain/kotlin/com/toasterofbread/spmp/youtubeapi/lyrics/Furigana.jvm.kt @@ -2,15 +2,15 @@ package com.toasterofbread.spmp.youtubeapi.lyrics import com.atilika.kuromoji.ipadic.Token import com.atilika.kuromoji.ipadic.Tokenizer -import dev.toastbits.composekit.utils.common.hasKanjiAndHiraganaOrKatakana -import dev.toastbits.composekit.utils.common.isHiragana -import dev.toastbits.composekit.utils.common.isKanji -import dev.toastbits.composekit.utils.common.isKatakana -import dev.toastbits.composekit.utils.common.toHiragana +import dev.toastbits.composekit.util.hasKanjiAndHiraganaOrKatakana +import dev.toastbits.composekit.util.isHiragana +import dev.toastbits.composekit.util.isKanji +import dev.toastbits.composekit.util.isKatakana +import dev.toastbits.composekit.util.toHiragana import com.toasterofbread.spmp.model.lyrics.SongLyrics import java.nio.channels.ClosedByInterruptException import com.moji4j.MojiConverter -import dev.toastbits.composekit.utils.common.isJa +import dev.toastbits.composekit.util.isJa private val tokeniser_impl: Tokenizer by lazy { Tokenizer() } diff --git a/shared/src/notAndroidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/DesktopMediaSession.kt b/shared/src/notAndroidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/DesktopMediaSession.kt index cafd2f10f..2d551c9a3 100644 --- a/shared/src/notAndroidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/DesktopMediaSession.kt +++ b/shared/src/notAndroidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/DesktopMediaSession.kt @@ -116,7 +116,7 @@ private fun MediaSession.onSongChanged(song: Song?, service: PlayerService) { val album: Playlist? = song?.Album?.get(db) val album_items: List? = album?.Items?.get(db) - service.context.coroutine_scope.launch { + service.context.coroutineScope.launch { setMetadata( MediaSessionMetadata( length_ms = service.duration_ms, diff --git a/shared/src/notAndroidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlatformInternalPlayerService.notAndroid.kt b/shared/src/notAndroidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlatformInternalPlayerService.notAndroid.kt index 0735d2082..0e6b36f0a 100644 --- a/shared/src/notAndroidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlatformInternalPlayerService.notAndroid.kt +++ b/shared/src/notAndroidMain/kotlin/com/toasterofbread/spmp/platform/playerservice/PlatformInternalPlayerService.notAndroid.kt @@ -18,14 +18,14 @@ actual class PlatformInternalPlayerService: ExternalPlayerService(plays_audio = } private suspend fun autoLaunchLocalServer() { - if (!context.settings.platform.SERVER_LOCAL_START_AUTOMATICALLY.get()) { + if (!context.settings.Platform.SERVER_LOCAL_START_AUTOMATICALLY.get()) { return } try { LocalServer.startLocalServer( context, - context.settings.platform.SERVER_PORT.get() + context.settings.Platform.SERVER_PORT.get() ) } catch (e: Throwable) { diff --git a/shared/src/wasmJsMain/kotlin/PlatformTheme.wasmJs.kt b/shared/src/wasmJsMain/kotlin/PlatformTheme.wasmJs.kt index 18e1ecf74..472a086eb 100644 --- a/shared/src/wasmJsMain/kotlin/PlatformTheme.wasmJs.kt +++ b/shared/src/wasmJsMain/kotlin/PlatformTheme.wasmJs.kt @@ -1,5 +1,5 @@ import androidx.compose.runtime.Composable -import dev.toastbits.composekit.settings.ui.ThemeValues +import dev.toastbits.composekit.theme.core.ThemeValues @Composable internal actual fun PlatformTheme(theme: ThemeValues, content: @Composable () -> Unit) { diff --git a/shared/src/wasmJsMain/kotlin/com/toasterofbread/spmp/platform/AppContext.wasmJs.kt b/shared/src/wasmJsMain/kotlin/com/toasterofbread/spmp/platform/AppContext.wasmJs.kt index c1a8e7575..31e0d0fa0 100644 --- a/shared/src/wasmJsMain/kotlin/com/toasterofbread/spmp/platform/AppContext.wasmJs.kt +++ b/shared/src/wasmJsMain/kotlin/com/toasterofbread/spmp/platform/AppContext.wasmJs.kt @@ -1,7 +1,7 @@ package com.toasterofbread.spmp.platform -import dev.toastbits.composekit.platform.PlatformContext -import dev.toastbits.composekit.platform.PlatformPreferences +import dev.toastbits.composekit.context.PlatformContext +import dev.toastbits.composekit.settings.PlatformSettings import com.toasterofbread.spmp.db.Database import com.toasterofbread.spmp.model.settings.Settings import com.toasterofbread.spmp.model.settings.category.YTApiSettings @@ -9,13 +9,13 @@ import com.toasterofbread.spmp.platform.download.PlayerDownloadManager import com.toasterofbread.spmp.resources.Language import com.toasterofbread.spmp.resources.getAvailableLanguages import com.toasterofbread.spmp.youtubeapi.YtmApiType -import dev.toastbits.composekit.platform.InMemoryPlatformPreferences +import dev.toastbits.composekit.context.InMemoryPlatformPreferences import dev.toastbits.ytmkt.model.YtmApi import kotlinx.coroutines.CoroutineScope actual class AppContext private constructor( coroutine_scope: CoroutineScope, - prefs: PlatformPreferences, + prefs: PlatformSettings, api_type: YtmApiType, api_url: String, data_language: Language, @@ -23,7 +23,7 @@ actual class AppContext private constructor( ): PlatformContext(coroutine_scope) { companion object { suspend fun create(coroutine_scope: CoroutineScope): AppContext { - val prefs: PlatformPreferences = InMemoryPlatformPreferences() + val prefs: PlatformSettings = InMemoryPlatformPreferences() val settings: YTApiSettings = YTApiSettings(prefs) return AppContext( @@ -37,8 +37,8 @@ actual class AppContext private constructor( } } - private val _prefs: PlatformPreferences = prefs - actual fun getPrefs(): PlatformPreferences = _prefs + private val _prefs: PlatformSettings = prefs + actual fun getPrefs(): PlatformSettings = _prefs actual val database: Database = createDatabase() actual val settings: Settings = Settings(this, available_languages)