diff --git a/app/src/main/java/com/github/damontecres/wholphin/preferences/DisplaySizeLevels.kt b/app/src/main/java/com/github/damontecres/wholphin/preferences/DisplaySizeLevels.kt index 6d1fdc84..ae53c1f4 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/preferences/DisplaySizeLevels.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/preferences/DisplaySizeLevels.kt @@ -1,5 +1,8 @@ package com.github.damontecres.wholphin.preferences +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.sp + val displaySizeLevelDisplayOrder: List = listOf( DisplaySizeLevel.EXTRA_SMALL, @@ -8,6 +11,70 @@ val displaySizeLevelDisplayOrder: List = DisplaySizeLevel.LARGE, ) +fun DisplaySizeLevel.scaledSp(baseSp: Int): TextUnit { + if (this == DisplaySizeLevel.DEFAULT || this == DisplaySizeLevel.UNRECOGNIZED) { + return baseSp.sp + } + val mapped = + when (this) { + DisplaySizeLevel.EXTRA_SMALL -> { + when (baseSp) { + 10 -> 9 + 12 -> 11 + 13 -> 11 + 14 -> 12 + 16 -> 14 + 18 -> 16 + 20 -> 18 + 24 -> 21 + 28 -> 25 + 56 -> 49 + 64 -> 56 + else -> null + } + } + + DisplaySizeLevel.SMALL -> { + when (baseSp) { + 10 -> 9 + 12 -> 11 + 13 -> 12 + 14 -> 13 + 16 -> 15 + 18 -> 17 + 20 -> 19 + 24 -> 23 + 28 -> 26 + 56 -> 53 + 64 -> 60 + else -> null + } + } + + DisplaySizeLevel.LARGE -> { + when (baseSp) { + 10 -> 11 + 12 -> 13 + 13 -> 14 + 14 -> 15 + 16 -> 17 + 18 -> 19 + 20 -> 22 + 24 -> 26 + 28 -> 30 + 56 -> 60 + 64 -> 69 + else -> null + } + } + + else -> { + null + } + } + return mapped?.sp ?: ((baseSp * textPercent() + 50) / 100).sp +} + fun DisplaySizeLevel.textPercent(): Int = when (this) { DisplaySizeLevel.EXTRA_SMALL -> 88 diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/BannerCard.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/BannerCard.kt index 8d00edfd..bcc9044b 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/BannerCard.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/BannerCard.kt @@ -34,7 +34,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.isSpecified -import androidx.compose.ui.unit.sp import androidx.tv.material3.Card import androidx.tv.material3.CardDefaults import androidx.tv.material3.MaterialTheme @@ -48,6 +47,7 @@ import com.github.damontecres.wholphin.ui.Cards import com.github.damontecres.wholphin.ui.FontAwesome import com.github.damontecres.wholphin.ui.LocalImageUrlService import com.github.damontecres.wholphin.ui.enableMarquee +import com.github.damontecres.wholphin.ui.util.scaledSp import org.jellyfin.sdk.model.api.ImageType /** @@ -179,7 +179,7 @@ fun BannerCard( .padding(8.dp), color = colorResource(android.R.color.holo_red_light), text = stringResource(R.string.fa_heart), - fontSize = 16.sp, + fontSize = scaledSp(16), fontFamily = FontAwesome, ) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/DiscoverItemCard.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/DiscoverItemCard.kt index 3b5fabc2..2fbd1cd5 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/DiscoverItemCard.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/DiscoverItemCard.kt @@ -30,7 +30,6 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.tv.material3.Card import androidx.tv.material3.CardDefaults import androidx.tv.material3.MaterialTheme @@ -46,6 +45,7 @@ import com.github.damontecres.wholphin.ui.PreviewTvSpec import com.github.damontecres.wholphin.ui.enableMarquee import com.github.damontecres.wholphin.ui.theme.WholphinTheme import com.github.damontecres.wholphin.ui.util.LocalInterfaceCustomization +import com.github.damontecres.wholphin.ui.util.scaledSp import kotlinx.coroutines.delay @Composable @@ -157,7 +157,7 @@ fun DiscoverItemCard( Text( text = pluralStringResource(it, 1), style = MaterialTheme.typography.bodySmall, - fontSize = 10.sp, + fontSize = scaledSp(10), modifier = Modifier .align(Alignment.TopStart) @@ -224,7 +224,7 @@ fun PendingIndicator(modifier: Modifier = Modifier) { Text( text = stringResource(R.string.fa_bell), fontFamily = FontAwesome, - fontSize = 10.sp, + fontSize = scaledSp(10), color = AppColors.Discover.Yellow, modifier = Modifier.align(Alignment.Center), ) @@ -249,7 +249,7 @@ fun AvailableIndicator(modifier: Modifier = Modifier) { Text( text = stringResource(R.string.fa_check), fontFamily = FontAwesome, - fontSize = 10.sp, + fontSize = scaledSp(10), color = Color.White, modifier = Modifier.align(Alignment.Center), ) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ItemCardImage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ItemCardImage.kt index 63f6bdd8..0436dcaa 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ItemCardImage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ItemCardImage.kt @@ -29,7 +29,6 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text import coil3.compose.AsyncImage @@ -41,6 +40,7 @@ import com.github.damontecres.wholphin.ui.FontAwesome import com.github.damontecres.wholphin.ui.LocalImageUrlService import com.github.damontecres.wholphin.ui.isNotNullOrBlank import com.github.damontecres.wholphin.ui.logCoilError +import com.github.damontecres.wholphin.ui.util.scaledSp import org.jellyfin.sdk.model.api.ImageType /** @@ -166,7 +166,7 @@ fun BoxScope.ItemCardImageFallback( Text( text = name, color = MaterialTheme.colorScheme.onSurfaceVariant, - fontSize = 14.sp, + fontSize = scaledSp(14), modifier = Modifier .padding(8.dp) @@ -222,7 +222,6 @@ fun ItemCardImageOverlay( text = numberOfVersions.toString(), color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.bodyMedium, -// fontSize = 16.sp, modifier = Modifier.padding(4.dp), ) } @@ -255,7 +254,6 @@ fun ItemCardImageOverlay( text = unwatchedCount.toString(), color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.bodyMedium, -// fontSize = 16.sp, modifier = Modifier.padding(4.dp), ) } @@ -280,7 +278,7 @@ fun ItemCardImageOverlay( @Composable fun FavoriteIndicator( modifier: Modifier = Modifier, - fontSize: TextUnit = 20.sp, + fontSize: TextUnit = scaledSp(20), ) = Text( color = colorResource(android.R.color.holo_red_light), text = stringResource(R.string.fa_heart), diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/PersonCard.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/PersonCard.kt index 4e146134..a737f61f 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/PersonCard.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/PersonCard.kt @@ -32,7 +32,6 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.tv.material3.Border import androidx.tv.material3.Card import androidx.tv.material3.CardDefaults @@ -45,6 +44,7 @@ import com.github.damontecres.wholphin.ui.FontAwesome import com.github.damontecres.wholphin.ui.PreviewTvSpec import com.github.damontecres.wholphin.ui.enableMarquee import com.github.damontecres.wholphin.ui.theme.WholphinTheme +import com.github.damontecres.wholphin.ui.util.scaledSp import kotlinx.coroutines.delay import org.jellyfin.sdk.model.UUID import org.jellyfin.sdk.model.api.PersonKind @@ -153,7 +153,7 @@ fun PersonCard( text = stringResource(R.string.fa_user), fontFamily = FontAwesome, color = MaterialTheme.colorScheme.onSurfaceVariant, - fontSize = 64.sp, + fontSize = scaledSp(64), textAlign = TextAlign.Center, modifier = Modifier diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/FilterByButton.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/FilterByButton.kt index e881bb98..da656735 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/FilterByButton.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/FilterByButton.kt @@ -31,7 +31,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.tv.material3.Icon import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text @@ -54,6 +53,7 @@ import com.github.damontecres.wholphin.ui.FontAwesome import com.github.damontecres.wholphin.ui.PreviewTvSpec import com.github.damontecres.wholphin.ui.theme.WholphinTheme import com.github.damontecres.wholphin.ui.tryRequestFocus +import com.github.damontecres.wholphin.ui.util.scaledSp import java.util.UUID /** @@ -399,7 +399,7 @@ fun ExpandableFilterButton( text = stringResource(R.string.fa_filter), style = MaterialTheme.typography.titleSmall, color = iconColor, - fontSize = 16.sp, + fontSize = scaledSp(16), fontFamily = FontAwesome, textAlign = TextAlign.Center, modifier = Modifier.align(Alignment.Center), diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/PlayButtons.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/PlayButtons.kt index ca4c11b8..6763148b 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/PlayButtons.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/PlayButtons.kt @@ -46,7 +46,6 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.tv.material3.Icon import androidx.tv.material3.LocalContentColor import androidx.tv.material3.MaterialTheme @@ -59,6 +58,7 @@ import com.github.damontecres.wholphin.ui.data.SortAndDirection import com.github.damontecres.wholphin.ui.ifElse import com.github.damontecres.wholphin.ui.theme.PreviewInteractionSource import com.github.damontecres.wholphin.ui.theme.WholphinTheme +import com.github.damontecres.wholphin.ui.util.scaledSp import org.jellyfin.sdk.model.api.ItemSortBy import org.jellyfin.sdk.model.api.SortOrder import kotlin.time.Duration @@ -329,7 +329,7 @@ fun ExpandableFaButton( text = stringResource(iconStringRes), style = MaterialTheme.typography.titleSmall, color = iconColor, - fontSize = 16.sp, + fontSize = scaledSp(16), fontFamily = FontAwesome, textAlign = TextAlign.Center, modifier = Modifier.align(Alignment.Center), diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/SeriesComponents.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/SeriesComponents.kt index 0ea3d74f..1d518734 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/SeriesComponents.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/SeriesComponents.kt @@ -4,9 +4,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.sp import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text +import com.github.damontecres.wholphin.ui.util.scaledSp import org.jellyfin.sdk.model.api.BaseItemDto @Composable @@ -34,7 +34,7 @@ fun EpisodeName( text = episodeName ?: "", color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.headlineSmall, - fontSize = 20.sp, + fontSize = scaledSp(20), maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = modifier, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/TabRow.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/TabRow.kt index f54fda5b..e2283023 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/TabRow.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/TabRow.kt @@ -36,12 +36,12 @@ import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text import com.github.damontecres.wholphin.ui.PreviewTvSpec import com.github.damontecres.wholphin.ui.theme.WholphinTheme import com.github.damontecres.wholphin.ui.tryRequestFocus +import com.github.damontecres.wholphin.ui.util.scaledSp import timber.log.Timber @Composable @@ -147,7 +147,7 @@ fun Tab( ) { Text( text = title, - fontSize = 16.sp, + fontSize = scaledSp(16), color = contentColor, modifier = Modifier.padding(horizontal = 16.dp), ) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/TimeDisplay.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/TimeDisplay.kt index f70a4f6a..0a603bcd 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/TimeDisplay.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/TimeDisplay.kt @@ -7,10 +7,10 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text import com.github.damontecres.wholphin.ui.util.LocalClock +import com.github.damontecres.wholphin.ui.util.scaledSp /** * Displays the [LocalClock] in the upper right corner of the parent [androidx.compose.foundation.layout.Box] @@ -20,7 +20,7 @@ fun BoxScope.TimeDisplay(modifier: Modifier = Modifier) { val timeString by LocalClock.current.timeString Text( text = timeString, - fontSize = 18.sp, + fontSize = scaledSp(18), color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.bodyLarge, modifier = diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/VideoStreamDetails.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/VideoStreamDetails.kt index 083dded6..ae8e4881 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/VideoStreamDetails.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/VideoStreamDetails.kt @@ -23,7 +23,6 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.tv.material3.MaterialTheme import androidx.tv.material3.ProvideTextStyle import androidx.tv.material3.Text @@ -41,6 +40,7 @@ import com.github.damontecres.wholphin.ui.util.StreamFormatting.formatAudioCodec import com.github.damontecres.wholphin.ui.util.StreamFormatting.formatSubtitleCodec import com.github.damontecres.wholphin.ui.util.StreamFormatting.formatVideoRange import com.github.damontecres.wholphin.ui.util.StreamFormatting.resolutionString +import com.github.damontecres.wholphin.ui.util.scaledSp import com.github.damontecres.wholphin.util.languageName import org.jellyfin.sdk.model.api.MediaSourceInfo import org.jellyfin.sdk.model.api.MediaStream @@ -185,7 +185,7 @@ fun StreamLabel( ProvideTextStyle( TextStyle( color = MaterialTheme.colorScheme.onSurface, - fontSize = 12.sp, + fontSize = scaledSp(12), fontWeight = FontWeight.SemiBold, ), ) { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/VoiceSearchButton.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/VoiceSearchButton.kt index 3042ac06..56896a65 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/VoiceSearchButton.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/VoiceSearchButton.kt @@ -43,7 +43,6 @@ import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import androidx.tv.material3.ButtonDefaults @@ -54,13 +53,12 @@ import androidx.tv.material3.Text import androidx.tv.material3.surfaceColorAtElevation import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.ui.FontAwesome +import com.github.damontecres.wholphin.ui.util.scaledSp import kotlinx.coroutines.delay private const val ERROR_AUTO_DISMISS_DELAY_MS = 3000L private const val SOUND_LEVEL_SCALE_FACTOR = 0.15f private val BUBBLE_SIZE = 160.dp -private val MIC_ICON_FONT_SIZE = 56.sp -private val BUTTON_ICON_FONT_SIZE = 20.sp private val CONTENT_SPACING = 48.dp private val HORIZONTAL_PADDING = 64.dp private val DISMISS_HINT_BOTTOM_PADDING = 32.dp @@ -174,7 +172,7 @@ fun VoiceSearchButton( Text( text = stringResource(R.string.fa_microphone), fontFamily = FontAwesome, - fontSize = BUTTON_ICON_FONT_SIZE, + fontSize = scaledSp(20), textAlign = TextAlign.Center, modifier = Modifier.semantics { contentDescription = voiceSearchDesc }, ) @@ -347,7 +345,7 @@ private fun VoiceSearchOverlay( Text( text = stringResource(R.string.fa_microphone), fontFamily = FontAwesome, - fontSize = MIC_ICON_FONT_SIZE, + fontSize = scaledSp(56), color = onPrimaryColor, textAlign = TextAlign.Center, modifier = Modifier.semantics { contentDescription = voiceSearchDesc }, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/livetv/Components.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/livetv/Components.kt index 41d53fd5..b2668ff2 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/livetv/Components.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/livetv/Components.kt @@ -19,7 +19,6 @@ import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.tv.material3.ClickableSurfaceDefaults import androidx.tv.material3.LocalContentColor import androidx.tv.material3.MaterialTheme @@ -29,6 +28,7 @@ import androidx.tv.material3.surfaceColorAtElevation import coil3.compose.AsyncImage import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.ui.FontAwesome +import com.github.damontecres.wholphin.ui.util.scaledSp import java.time.LocalDateTime @Composable @@ -87,7 +87,7 @@ fun Program( text = stringResource(R.string.fa_caret_left), fontFamily = FontAwesome, color = LocalContentColor.current, - fontSize = 16.sp, + fontSize = scaledSp(16), modifier = Modifier .align(Alignment.CenterVertically) @@ -104,7 +104,7 @@ fun Program( Text( text = title, color = LocalContentColor.current, - fontSize = 16.sp, + fontSize = scaledSp(16), maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier, @@ -120,7 +120,7 @@ fun Program( Text( text = it, color = LocalContentColor.current, - fontSize = 14.sp, + fontSize = scaledSp(14), overflow = TextOverflow.Ellipsis, modifier = Modifier, ) @@ -197,7 +197,7 @@ fun Channel( Text( text = it, style = MaterialTheme.typography.bodySmall, - fontSize = if (showImage) 10.sp else 16.sp, + fontSize = if (showImage) scaledSp(10) else scaledSp(16), maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier, @@ -209,7 +209,7 @@ fun Channel( Text( color = colorResource(android.R.color.holo_red_light), text = stringResource(R.string.fa_heart), - fontSize = 16.sp, + fontSize = scaledSp(16), fontFamily = FontAwesome, modifier = Modifier diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingButtons.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingButtons.kt index db5bbf4c..7361d123 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingButtons.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingButtons.kt @@ -24,7 +24,6 @@ import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.media3.common.Player import androidx.media3.common.util.UnstableApi import androidx.media3.ui.compose.state.rememberNextButtonState @@ -48,6 +47,7 @@ import com.github.damontecres.wholphin.ui.playback.overlay.PlaybackFaButton import com.github.damontecres.wholphin.ui.playback.overlay.buttonSpacing import com.github.damontecres.wholphin.ui.theme.PreviewInteractionSource import com.github.damontecres.wholphin.ui.theme.WholphinTheme +import com.github.damontecres.wholphin.ui.util.scaledSp import kotlin.time.Duration.Companion.seconds @OptIn(UnstableApi::class) @@ -176,7 +176,7 @@ fun ShuffleButton( ) { Text( text = stringResource(R.string.fa_shuffle), - fontSize = 18.sp, + fontSize = scaledSp(18), fontFamily = FontAwesome, textAlign = TextAlign.Center, color = @@ -228,7 +228,7 @@ fun RepeatButton( ) { Text( text = stringResource(R.string.fa_repeat), - fontSize = 18.sp, + fontSize = scaledSp(18), fontFamily = FontAwesome, textAlign = TextAlign.Center, color = @@ -253,7 +253,7 @@ fun RepeatButton( if (repeatMode == Player.REPEAT_MODE_ONE) { Text( text = "1", - fontSize = 10.sp, + fontSize = scaledSp(10), color = MaterialTheme.colorScheme.surface, modifier = Modifier diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/nav/NavDrawer.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/nav/NavDrawer.kt index af4ec63f..48016405 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/nav/NavDrawer.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/nav/NavDrawer.kt @@ -53,7 +53,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.ViewModel import androidx.lifecycle.findViewTreeViewModelStoreOwner @@ -89,6 +88,7 @@ import com.github.damontecres.wholphin.ui.spacedByWithFooter import com.github.damontecres.wholphin.ui.theme.LocalTheme import com.github.damontecres.wholphin.ui.toServerString import com.github.damontecres.wholphin.ui.tryRequestFocus +import com.github.damontecres.wholphin.ui.util.scaledSp import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -717,7 +717,7 @@ fun NavigationDrawerScope.NavItem( Text( text = stringResource(icon), textAlign = TextAlign.Center, - fontSize = 16.sp, + fontSize = scaledSp(16), fontFamily = FontAwesome, color = color, modifier = Modifier, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackController.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackController.kt index 528b6546..3d73fd9b 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackController.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackController.kt @@ -26,7 +26,6 @@ import androidx.compose.ui.res.stringResource 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 androidx.media3.common.Player import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text @@ -35,6 +34,7 @@ import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.ui.getTimeFormatter import com.github.damontecres.wholphin.ui.playback.ControllerViewState import com.github.damontecres.wholphin.ui.playback.PlaybackDialogType +import com.github.damontecres.wholphin.ui.util.scaledSp import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import org.jellyfin.sdk.model.api.MediaSegmentDto @@ -121,9 +121,6 @@ fun PlaybackController( } } -internal val titleTextSize = 28.sp -internal val subtitleTextSize = 18.sp - /** * A wrapper for the playback controls to show title and other information, plus the actual controls * @@ -175,7 +172,7 @@ fun Controller( Text( text = it, style = MaterialTheme.typography.titleLarge, - fontSize = titleTextSize, + fontSize = scaledSp(28), maxLines = 1, overflow = TextOverflow.MiddleEllipsis, modifier = Modifier.fillMaxWidth(.75f), @@ -192,7 +189,7 @@ fun Controller( Text( text = it, style = MaterialTheme.typography.titleMedium, - fontSize = subtitleTextSize, + fontSize = scaledSp(18), maxLines = 1, overflow = TextOverflow.MiddleEllipsis, modifier = Modifier.fillMaxWidth(.75f), diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackControls.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackControls.kt index 820e634f..9161fbe7 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackControls.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackControls.kt @@ -49,7 +49,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogWindowProvider @@ -79,6 +78,7 @@ import com.github.damontecres.wholphin.ui.skipStringRes import com.github.damontecres.wholphin.ui.theme.LocalTheme import com.github.damontecres.wholphin.ui.theme.WholphinTheme import com.github.damontecres.wholphin.ui.tryRequestFocus +import com.github.damontecres.wholphin.ui.util.scaledSp import com.github.damontecres.wholphin.util.ExceptionHandler import kotlinx.coroutines.delay import kotlinx.coroutines.isActive @@ -497,7 +497,7 @@ fun PlaybackFaButton( ) { Text( text = stringResource(iconRes), - fontSize = 18.sp, + fontSize = scaledSp(18), fontFamily = FontAwesome, textAlign = TextAlign.Center, color = diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackDebugOverlay.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackDebugOverlay.kt index 1420ffb6..51ded17c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackDebugOverlay.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackDebugOverlay.kt @@ -18,7 +18,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.media3.common.Format import androidx.media3.common.util.UnstableApi import androidx.tv.material3.MaterialTheme @@ -33,6 +32,7 @@ import com.github.damontecres.wholphin.ui.letNotEmpty import com.github.damontecres.wholphin.ui.playback.AnalyticsState import com.github.damontecres.wholphin.ui.playback.CurrentPlayback import com.github.damontecres.wholphin.ui.theme.WholphinTheme +import com.github.damontecres.wholphin.ui.util.scaledSp import com.github.damontecres.wholphin.util.TrackSupport import com.github.damontecres.wholphin.util.TrackSupportReason import com.github.damontecres.wholphin.util.TrackType @@ -85,7 +85,7 @@ fun PlaybackDebugOverlay( } val textStyle = MaterialTheme.typography.bodySmall.copy( - fontSize = 10.sp, + fontSize = scaledSp(10), color = MaterialTheme.colorScheme.onSurface, ) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackOverlay.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackOverlay.kt index 96adc4df..3927dbe5 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackOverlay.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackOverlay.kt @@ -61,6 +61,7 @@ import com.github.damontecres.wholphin.ui.playback.AnalyticsState import com.github.damontecres.wholphin.ui.playback.ControllerViewState import com.github.damontecres.wholphin.ui.playback.CurrentPlayback import com.github.damontecres.wholphin.ui.playback.PlaybackDialogType +import com.github.damontecres.wholphin.ui.util.scaledSp import org.jellyfin.sdk.model.api.ImageType import org.jellyfin.sdk.model.api.MediaSegmentDto import org.jellyfin.sdk.model.api.TrickplayInfo @@ -105,13 +106,15 @@ fun PlaybackOverlay( val density = LocalDensity.current + val titleSp = scaledSp(28) + val subtitleSp = scaledSp(18) val titleHeight = - remember(item?.title) { - if (item?.title.isNotNullOrBlank()) with(density) { titleTextSize.toDp() } else 0.dp + remember(item?.title, titleSp) { + if (item?.title.isNotNullOrBlank()) with(density) { titleSp.toDp() } else 0.dp } val subtitleHeight = - remember(item?.subtitleLong) { - if (item?.subtitleLong.isNotNullOrBlank()) with(density) { subtitleTextSize.toDp() } else 0.dp + remember(item?.subtitleLong, subtitleSp) { + if (item?.subtitleLong.isNotNullOrBlank()) with(density) { subtitleSp.toDp() } else 0.dp } // This will be calculated after composition diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/SkipIndicator.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/SkipIndicator.kt index 3ac39bfa..b5d35de4 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/SkipIndicator.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/SkipIndicator.kt @@ -18,11 +18,11 @@ import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.scale import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.ui.ifElse +import com.github.damontecres.wholphin.ui.util.scaledSp import kotlin.math.abs /** @@ -63,7 +63,7 @@ fun SkipIndicator( Text( modifier = Modifier.align(Alignment.Center), color = MaterialTheme.colorScheme.onBackground, - fontSize = 13.sp, + fontSize = scaledSp(13), style = MaterialTheme.typography.bodySmall, text = abs(durationMs / 1000).toString(), ) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt index e8c768a4..0e2ab226 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt @@ -30,7 +30,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.datastore.core.DataStore import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.ViewModel @@ -59,6 +58,7 @@ import com.github.damontecres.wholphin.ui.launchIO import com.github.damontecres.wholphin.ui.main.settings.MoveDirection import com.github.damontecres.wholphin.ui.nav.NavDrawerItem import com.github.damontecres.wholphin.ui.theme.WholphinTheme +import com.github.damontecres.wholphin.ui.util.scaledSp import com.github.damontecres.wholphin.util.ExceptionHandler import com.github.damontecres.wholphin.util.RememberTabManager import dagger.hilt.android.lifecycle.HiltViewModel @@ -275,7 +275,7 @@ fun MoveButton( ) { Text( text = stringResource(icon), - fontSize = 16.sp, + fontSize = scaledSp(16), fontFamily = FontAwesome, textAlign = TextAlign.Center, modifier = Modifier.fillMaxWidth(), diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/InstallUpdatePage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/InstallUpdatePage.kt index a3bd52e4..533bfba2 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/InstallUpdatePage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/InstallUpdatePage.kt @@ -36,7 +36,6 @@ import androidx.compose.ui.input.key.onKeyEvent import androidx.compose.ui.input.key.type import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -60,6 +59,7 @@ import com.github.damontecres.wholphin.ui.dimAndBlur import com.github.damontecres.wholphin.ui.formatBytes import com.github.damontecres.wholphin.ui.launchIO import com.github.damontecres.wholphin.ui.theme.WholphinTheme +import com.github.damontecres.wholphin.ui.util.scaledSp import com.github.damontecres.wholphin.util.ExceptionHandler import com.github.damontecres.wholphin.util.LoadingState import com.github.damontecres.wholphin.util.Version @@ -369,7 +369,7 @@ fun DownloadDialog( ) { Text( text = stringResource(R.string.downloading), - fontSize = 24.sp, + fontSize = scaledSp(24), color = MaterialTheme.colorScheme.onSurface, ) if (progress != null) { @@ -396,7 +396,7 @@ fun DownloadDialog( val size = formatBytes(contentLength) Text( text = "$bytes / $size", - fontSize = 18.sp, + fontSize = scaledSp(18), color = MaterialTheme.colorScheme.onSurface, ) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/PinEntry.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/PinEntry.kt index f9f22591..b0847b31 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/PinEntry.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/PinEntry.kt @@ -27,7 +27,6 @@ import androidx.compose.ui.input.key.type import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text import com.github.damontecres.wholphin.R @@ -38,6 +37,7 @@ import com.github.damontecres.wholphin.ui.components.Button import com.github.damontecres.wholphin.ui.components.TextButton import com.github.damontecres.wholphin.ui.playback.isEnterKey import com.github.damontecres.wholphin.ui.theme.WholphinTheme +import com.github.damontecres.wholphin.ui.util.scaledSp @Composable fun PinEntry( @@ -101,7 +101,7 @@ fun PinEntry( ) Text( text = stringResource(R.string.will_remove_pin), - fontSize = 10.sp, + fontSize = scaledSp(10), ) } } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/UserList.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/UserList.kt index ddc171c9..2b44f1eb 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/UserList.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/UserList.kt @@ -39,7 +39,6 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.ui.window.DialogProperties import androidx.tv.material3.Border import androidx.tv.material3.Button @@ -60,6 +59,7 @@ import com.github.damontecres.wholphin.ui.isNotNullOrBlank import com.github.damontecres.wholphin.ui.theme.WholphinTheme import com.github.damontecres.wholphin.ui.toServerString import com.github.damontecres.wholphin.ui.tryRequestFocus +import com.github.damontecres.wholphin.ui.util.scaledSp import java.util.UUID /** @@ -333,7 +333,7 @@ fun UserIconCardImage( Text( text = firstLetter, style = MaterialTheme.typography.bodyLarge, - fontSize = 14.sp, + fontSize = scaledSp(14), fontWeight = FontWeight.Normal, color = MaterialTheme.colorScheme.onSurface, textAlign = TextAlign.Center, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/util/InterfaceHelpers.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/util/InterfaceHelpers.kt index 018b9b56..8c06c339 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/util/InterfaceHelpers.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/util/InterfaceHelpers.kt @@ -1,11 +1,13 @@ package com.github.damontecres.wholphin.ui.util import androidx.compose.runtime.Composable -import androidx.compose.ui.unit.Density +import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import com.github.damontecres.wholphin.data.model.HomeRowViewOptions import com.github.damontecres.wholphin.preferences.AppSliderPreference +import com.github.damontecres.wholphin.preferences.scaledSp import com.github.damontecres.wholphin.ui.AspectRatio import com.github.damontecres.wholphin.ui.Cards @@ -26,8 +28,8 @@ internal fun naturalCardBaseDp(aspectRatio: AspectRatio): Int = AspectRatio.TALL, AspectRatio.SQUARE, AspectRatio.FOUR_THREE -> Cards.HEIGHT_2X3_DP } -// The global Card slider, the per-row multiplier, and any preset-set absolute heightDp -// all stack. Preset 148dp + global 150% + per-row 100% = 222dp. The base is the row's +// The global Card size, the per-row multiplier, and any preset-set absolute heightDp +// all stack. Preset 148dp + global 116% + per-row 110% = ~189dp. The base is the row's // preset if present, otherwise the natural height for its aspect. internal fun resolveCardHeight( heightDp: Int, @@ -40,19 +42,9 @@ internal fun resolveCardHeight( return base * globalCardSizePercent / 100 * cardSizeMultiplier / 100 } -// Scales density (and therefore both dp layouts and sp text) linearly by uiScalePercent. -// fontScale is left at the user's system value so Android's accessibility setting still -// applies on top - scaling both would render text at factor^2 instead of factor. -internal fun scaledDensity( - base: Density, - uiScalePercent: Int, -): Density { - val factor = uiScalePercent / 100f - return Density( - density = base.density * factor, - fontScale = base.fontScale, - ) -} +@Composable +@ReadOnlyComposable +internal fun scaledSp(baseSp: Int): TextUnit = LocalInterfaceCustomization.current.textSizeLevel.scaledSp(baseSp) internal fun Int.withinBoundsOrDefault(preference: AppSliderPreference<*>): Int { val min = preference.min.toInt() diff --git a/app/src/test/java/com/github/damontecres/wholphin/ui/util/InterfaceHelpersTest.kt b/app/src/test/java/com/github/damontecres/wholphin/ui/util/InterfaceHelpersTest.kt index 8951e0d9..c4624fd5 100644 --- a/app/src/test/java/com/github/damontecres/wholphin/ui/util/InterfaceHelpersTest.kt +++ b/app/src/test/java/com/github/damontecres/wholphin/ui/util/InterfaceHelpersTest.kt @@ -1,6 +1,5 @@ package com.github.damontecres.wholphin.ui.util -import androidx.compose.ui.unit.Density import com.github.damontecres.wholphin.data.model.HomeRowConfig import com.github.damontecres.wholphin.data.model.HomeRowViewOptions import com.github.damontecres.wholphin.preferences.AppPreference @@ -102,35 +101,6 @@ class InterfaceHelpersTest { assertEquals(Cards.HEIGHT_2X3_DP, naturalCardBaseDp(AspectRatio.FOUR_THREE)) } - @Test - fun `scaledDensity scales density linearly and leaves fontScale alone`() { - val base = Density(density = 2.0f, fontScale = 1.0f) - val scaled = scaledDensity(base, 150) - // density grows by 1.5 - so dp layouts scale 1.5x. - assertEquals(3.0f, scaled.density, 0.001f) - // fontScale stays put - sp text is (density * fontScale) so it also scales linearly. - // Scaling fontScale too would render text at 1.5^2 = 2.25x. - assertEquals(1.0f, scaled.fontScale, 0.001f) - } - - @Test - fun `scaledDensity at 100 percent returns identity`() { - val base = Density(density = 2.0f, fontScale = 1.2f) - val scaled = scaledDensity(base, 100) - assertEquals(base.density, scaled.density, 0.001f) - assertEquals(base.fontScale, scaled.fontScale, 0.001f) - } - - @Test - fun `scaledDensity preserves user accessibility fontScale across UI scale changes`() { - // A user with system fontScale 1.3x (accessibility setting) bumping UI scale to 75% - // should keep fontScale = 1.3 - the UI scale slider is independent of accessibility. - val base = Density(density = 2.0f, fontScale = 1.3f) - val scaled = scaledDensity(base, 75) - assertEquals(1.5f, scaled.density, 0.001f) - assertEquals(1.3f, scaled.fontScale, 0.001f) - } - @Test fun `InterfaceCustomization cardHeightDp at DEFAULT level matches natural base`() { val customization = InterfaceCustomization(prefs = AppPreferences.getDefaultInstance())