diff --git a/composeApp/src/androidMain/kotlin/com/lagradost/cloudstream4/ui/theme/ThemePreferenceHelper.android.kt b/composeApp/src/androidMain/kotlin/com/lagradost/cloudstream4/ui/theme/ThemePreferenceHelper.android.kt index 2c59b675a33..52d89a3ec5b 100644 --- a/composeApp/src/androidMain/kotlin/com/lagradost/cloudstream4/ui/theme/ThemePreferenceHelper.android.kt +++ b/composeApp/src/androidMain/kotlin/com/lagradost/cloudstream4/ui/theme/ThemePreferenceHelper.android.kt @@ -13,7 +13,7 @@ fun Context.loadThemeMode(): CloudStreamThemeMode { "Black" -> CloudStreamThemeMode.Dark "Light" -> CloudStreamThemeMode.Light "Amoled" -> CloudStreamThemeMode.Amoled - "AmoledLight" -> CloudStreamThemeMode.Amoled + "AmoledLight" -> CloudStreamThemeMode.AmoledLight "Dracula" -> CloudStreamThemeMode.Dracula "Lavender" -> CloudStreamThemeMode.Lavender "SilentBlue" -> CloudStreamThemeMode.SilentBlue diff --git a/composeApp/src/commonMain/composeResources/font/productsans_black.ttf b/composeApp/src/commonMain/composeResources/font/productsans_black.ttf new file mode 100644 index 00000000000..5864e269083 Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_black.ttf differ diff --git a/composeApp/src/commonMain/composeResources/font/productsans_blackitalic.ttf b/composeApp/src/commonMain/composeResources/font/productsans_blackitalic.ttf new file mode 100644 index 00000000000..869037b785d Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_blackitalic.ttf differ diff --git a/composeApp/src/commonMain/composeResources/font/productsans_bold.ttf b/composeApp/src/commonMain/composeResources/font/productsans_bold.ttf new file mode 100644 index 00000000000..96619df92e3 Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_bold.ttf differ diff --git a/composeApp/src/commonMain/composeResources/font/productsans_bolditalic.ttf b/composeApp/src/commonMain/composeResources/font/productsans_bolditalic.ttf new file mode 100644 index 00000000000..bdd22b046b8 Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_bolditalic.ttf differ diff --git a/composeApp/src/commonMain/composeResources/font/productsans_italic.ttf b/composeApp/src/commonMain/composeResources/font/productsans_italic.ttf new file mode 100644 index 00000000000..5b44037be59 Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_italic.ttf differ diff --git a/composeApp/src/commonMain/composeResources/font/productsans_light.ttf b/composeApp/src/commonMain/composeResources/font/productsans_light.ttf new file mode 100644 index 00000000000..33de1c39f2d Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_light.ttf differ diff --git a/composeApp/src/commonMain/composeResources/font/productsans_lightitalic.ttf b/composeApp/src/commonMain/composeResources/font/productsans_lightitalic.ttf new file mode 100644 index 00000000000..00c76b8ec8b Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_lightitalic.ttf differ diff --git a/composeApp/src/commonMain/composeResources/font/productsans_medium.ttf b/composeApp/src/commonMain/composeResources/font/productsans_medium.ttf new file mode 100644 index 00000000000..fd818d6f5b2 Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_medium.ttf differ diff --git a/composeApp/src/commonMain/composeResources/font/productsans_mediumitalic.ttf b/composeApp/src/commonMain/composeResources/font/productsans_mediumitalic.ttf new file mode 100644 index 00000000000..ec70cd38411 Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_mediumitalic.ttf differ diff --git a/composeApp/src/commonMain/composeResources/font/productsans_regular.ttf b/composeApp/src/commonMain/composeResources/font/productsans_regular.ttf new file mode 100644 index 00000000000..e2c69c3fb94 Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_regular.ttf differ diff --git a/composeApp/src/commonMain/composeResources/font/productsans_thin.ttf b/composeApp/src/commonMain/composeResources/font/productsans_thin.ttf new file mode 100644 index 00000000000..5e046b53295 Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_thin.ttf differ diff --git a/composeApp/src/commonMain/composeResources/font/productsans_thinitalic.ttf b/composeApp/src/commonMain/composeResources/font/productsans_thinitalic.ttf new file mode 100644 index 00000000000..7b049551887 Binary files /dev/null and b/composeApp/src/commonMain/composeResources/font/productsans_thinitalic.ttf differ diff --git a/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamColorScheme.kt b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamColorScheme.kt index 2f67b266069..8647a31dbbb 100644 --- a/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamColorScheme.kt +++ b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamColorScheme.kt @@ -87,6 +87,11 @@ internal fun amoledScheme() = darkScheme().copy( surfaceContainer = CloudStreamPalette.AmoledBlack, ) +internal fun amoledLightScheme() = amoledScheme().copy( + surfaceVariant = CloudStreamPalette.AmoledLightBlackBg, + surfaceContainer = CloudStreamPalette.AmoledLightBlackBg, +) + internal fun lightScheme() = CloudStreamColorScheme( background = CloudStreamPalette.LightBlackBg, surfaceVariant = CloudStreamPalette.LightPrimaryGrayBg, diff --git a/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamDefaultFonts.kt b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamDefaultFonts.kt new file mode 100644 index 00000000000..997e3b60664 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamDefaultFonts.kt @@ -0,0 +1,41 @@ +package com.lagradost.cloudstream4.ui.theme + +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import com.lagradost.cloudstream4.generated.resources.Res +import com.lagradost.cloudstream4.generated.resources.productsans_black +import com.lagradost.cloudstream4.generated.resources.productsans_blackitalic +import com.lagradost.cloudstream4.generated.resources.productsans_bold +import com.lagradost.cloudstream4.generated.resources.productsans_bolditalic +import com.lagradost.cloudstream4.generated.resources.productsans_italic +import com.lagradost.cloudstream4.generated.resources.productsans_light +import com.lagradost.cloudstream4.generated.resources.productsans_lightitalic +import com.lagradost.cloudstream4.generated.resources.productsans_medium +import com.lagradost.cloudstream4.generated.resources.productsans_mediumitalic +import com.lagradost.cloudstream4.generated.resources.productsans_regular +import com.lagradost.cloudstream4.generated.resources.productsans_thin +import com.lagradost.cloudstream4.generated.resources.productsans_thinitalic + +object CloudStreamDefaultFonts { + val GoogleSans: CloudStreamFontSpec.Bundled = CloudStreamFontSpec.Bundled( + listOf( + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_thin, FontWeight.Thin, FontStyle.Normal), + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_thinitalic, FontWeight.Thin, FontStyle.Italic), + + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_light, FontWeight.Light, FontStyle.Normal), + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_lightitalic, FontWeight.Light, FontStyle.Italic), + + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_regular, FontWeight.Normal, FontStyle.Normal), + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_italic, FontWeight.Normal, FontStyle.Italic), + + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_medium, FontWeight.Medium, FontStyle.Normal), + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_mediumitalic, FontWeight.Medium, FontStyle.Italic), + + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_bold, FontWeight.Bold, FontStyle.Normal), + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_bolditalic, FontWeight.Bold, FontStyle.Italic), + + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_black, FontWeight.Black, FontStyle.Normal), + CloudStreamFontSpec.Bundled.Entry(Res.font.productsans_blackitalic, FontWeight.Black, FontStyle.Italic), + ) + ) +} diff --git a/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamFontSpec.kt b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamFontSpec.kt new file mode 100644 index 00000000000..255a0610883 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamFontSpec.kt @@ -0,0 +1,47 @@ +package com.lagradost.cloudstream4.ui.theme + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import org.jetbrains.compose.resources.Font +import org.jetbrains.compose.resources.FontResource + +sealed interface CloudStreamFontSpec { + + data object SystemDefault : CloudStreamFontSpec + + /** A font bundled via composeResources */ + data class Bundled(val entries: List) : CloudStreamFontSpec { + data class Entry( + val resource: FontResource, + val weight: FontWeight, + val style: FontStyle, + ) + } + + /** A user-uploaded font, resolved later from a file path/URI. */ + data class Custom(val path: String) : CloudStreamFontSpec +} + +// Not yet implemented +/** Platform-specific loading of a user-uploaded font from a file path/URI. */ +// expect fun loadCustomFontFamily(path: String): FontFamily? + +@Composable +fun CloudStreamFontSpec.resolve(): FontFamily = when (this) { + is CloudStreamFontSpec.SystemDefault -> FontFamily.Default + + is CloudStreamFontSpec.Bundled -> { + val fonts = entries.map { entry -> + Font(entry.resource, weight = entry.weight, style = entry.style) + } + remember(fonts) { FontFamily(fonts) } + } + + // Not yet implemented + is CloudStreamFontSpec.Custom -> FontFamily.Default /* remember(path) { + loadCustomFontFamily(path) ?: FontFamily.Default + } */ +} diff --git a/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamPalette.kt b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamPalette.kt index fd5bea1ef51..22df7a83483 100644 --- a/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamPalette.kt +++ b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamPalette.kt @@ -20,6 +20,9 @@ internal object CloudStreamPalette { val AmoledBlack = Color(0xFF000000) val AmoledNearBlack = Color(0xFF111111) + // AmoledLight + val AmoledLightBlackBg = Color(0xFF121213) + // Light val LightPrimaryGrayBg = Color(0xFFF1F1F1) val LightBlackBg = Color(0xFFFFFFFF) diff --git a/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamTheme.kt b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamTheme.kt index fdf069d488a..e254a1d794a 100644 --- a/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamTheme.kt +++ b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamTheme.kt @@ -2,6 +2,7 @@ package com.lagradost.cloudstream4.ui.theme import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Typography import androidx.compose.material3.darkColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable @@ -10,6 +11,7 @@ import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.remember import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontFamily val LocalCloudStreamColors = staticCompositionLocalOf { darkScheme() } @@ -46,10 +48,33 @@ private fun CloudStreamColorScheme.toMaterial3ColorScheme() = if (isLight) { ) } +private fun Typography.withFontFamily(fontFamily: FontFamily): Typography = copy( + displayLarge = displayLarge.copy(fontFamily = fontFamily), + displayMedium = displayMedium.copy(fontFamily = fontFamily), + displaySmall = displaySmall.copy(fontFamily = fontFamily), + + headlineLarge = headlineLarge.copy(fontFamily = fontFamily), + headlineMedium = headlineMedium.copy(fontFamily = fontFamily), + headlineSmall = headlineSmall.copy(fontFamily = fontFamily), + + titleLarge = titleLarge.copy(fontFamily = fontFamily), + titleMedium = titleMedium.copy(fontFamily = fontFamily), + titleSmall = titleSmall.copy(fontFamily = fontFamily), + + bodyLarge = bodyLarge.copy(fontFamily = fontFamily), + bodyMedium = bodyMedium.copy(fontFamily = fontFamily), + bodySmall = bodySmall.copy(fontFamily = fontFamily), + + labelLarge = labelLarge.copy(fontFamily = fontFamily), + labelMedium = labelMedium.copy(fontFamily = fontFamily), + labelSmall = labelSmall.copy(fontFamily = fontFamily), +) + @Composable fun CloudStreamTheme( mode: CloudStreamThemeMode = CloudStreamThemeMode.FollowSystem, primaryColor: CloudStreamPrimaryColor = CloudStreamPrimaryColor.NORMAL, + fontSpec: CloudStreamFontSpec = CloudStreamDefaultFonts.GoogleSans, content: @Composable () -> Unit, ) { val systemDark = isSystemInDarkTheme() @@ -62,6 +87,7 @@ fun CloudStreamTheme( val base = when (mode) { CloudStreamThemeMode.Dark -> darkScheme() CloudStreamThemeMode.Amoled -> amoledScheme() + CloudStreamThemeMode.AmoledLight -> amoledLightScheme() CloudStreamThemeMode.Light -> lightScheme() CloudStreamThemeMode.Dracula -> draculaScheme() CloudStreamThemeMode.Lavender -> lavenderScheme() @@ -77,9 +103,16 @@ fun CloudStreamTheme( } } + val resolvedFontFamily = fontSpec.resolve() + val baseTypography = MaterialTheme.typography + val typography = remember(baseTypography, resolvedFontFamily) { + baseTypography.withFontFamily(resolvedFontFamily) + } + CompositionLocalProvider(LocalCloudStreamColors provides csColors) { MaterialTheme( colorScheme = csColors.toMaterial3ColorScheme(), + typography = typography, content = content, ) } diff --git a/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamThemeMode.kt b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamThemeMode.kt index ab15e072206..ddf799b5afc 100644 --- a/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamThemeMode.kt +++ b/composeApp/src/commonMain/kotlin/com/lagradost/cloudstream4/ui/theme/CloudStreamThemeMode.kt @@ -3,8 +3,10 @@ package com.lagradost.cloudstream4.ui.theme enum class CloudStreamThemeMode { /** "Black" standard dark, #111111 backgrounds */ Dark, - /** "Amoled" / "AmoledLight" pure black (#000000) */ + /** "Amoled" pure black (#000000) */ Amoled, + /** "AmoledLight" pure black (#000000) background, lighter (#121213) surfaces */ + AmoledLight, /** "Light" white/gray backgrounds, dark text */ Light, /** "Dracula" */