git.iko.soy/opencode-android
on d518ef7 help sign in
54 lines 2.5 kB history raw
1package soy.iko.opencode.ui.components
3import androidx.compose.runtime.compositionLocalOf
4import androidx.compose.material3.Typography
6/**
7 * Chat presentation preferences, threaded through the composition so the markdown and
8 * code renderers can honor them without every call site plumbing them explicitly.
9 *
10 * - [LocalChatTextScale]: a multiplier applied to chat/message/code font sizes.
11 * - [LocalCodeWrap]: whether code blocks soft-wrap long lines (vs. horizontal scroll).
12 * - [LocalSearchHighlight]: an in-conversation search query; when non-null, matching
13 * spans in completed (non-streaming) markdown are highlighted in-place.
14 *
15 * Provided once near the app root from the persisted [soy.iko.opencode.data.repo.SettingsStore]
16 * values. Defaults keep the design behavior when no provider is present (e.g. previews/tests).
17 */
18val LocalChatTextScale = compositionLocalOf { 1f }
19val LocalCodeWrap = compositionLocalOf { false }
20val LocalSearchHighlight = compositionLocalOf<String?> { null }
22/**
23 * Return a copy of this [Typography] with every text role's font size and line height
24 * multiplied by [scale]. Used to scale a whole markdown subtree (headings, lists, code,
25 * body) from a single user preference. Returns the receiver unchanged when [scale] is 1.
26 */
27fun Typography.scaledBy(scale: Float): Typography {
28 if (scale == 1f) return this
29 fun androidx.compose.ui.text.TextStyle.scaled() = copy(
30 fontSize = if (fontSize.isSp) fontSize * scale else fontSize,
31 lineHeight = if (lineHeight.isSp) lineHeight * scale else lineHeight,
32 )
33 return copy(
34 displayLarge = displayLarge.scaled(),
35 displayMedium = displayMedium.scaled(),
36 displaySmall = displaySmall.scaled(),
37 headlineLarge = headlineLarge.scaled(),
38 headlineMedium = headlineMedium.scaled(),
39 headlineSmall = headlineSmall.scaled(),
40 titleLarge = titleLarge.scaled(),
41 titleMedium = titleMedium.scaled(),
42 titleSmall = titleSmall.scaled(),
43 bodyLarge = bodyLarge.scaled(),
44 bodyMedium = bodyMedium.scaled(),
45 bodySmall = bodySmall.scaled(),
46 labelLarge = labelLarge.scaled(),
47 labelMedium = labelMedium.scaled(),
48 labelSmall = labelSmall.scaled(),
49 )
52/** True when this [androidx.compose.ui.unit.TextUnit] is expressed in sp (safe to scale). */
53private val androidx.compose.ui.unit.TextUnit.isSp: Boolean
54 get() = type == androidx.compose.ui.unit.TextUnitType.Sp