Compare commits
2
Commits
f79c54fead
...
6846ab1e19
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6846ab1e19 | ||
|
|
abf1374c1e |
No files matched your search
@@ -134,6 +134,10 @@ class AndroidSecureStore(context: Context) : SecureStore {
|
||||
get() = prefs.getString(KEY_BACKGROUND_IMAGE_PATH, "").orEmpty()
|
||||
set(value) = prefs.edit().putString(KEY_BACKGROUND_IMAGE_PATH, value).apply()
|
||||
|
||||
override var fontSizeScale: Float
|
||||
get() = prefs.getFloat(KEY_FONT_SIZE_SCALE, 1.0f)
|
||||
set(value) = prefs.edit().putFloat(KEY_FONT_SIZE_SCALE, value).apply()
|
||||
|
||||
override fun savePairing(url: String, token: String) {
|
||||
serverUrl = url
|
||||
this.token = token
|
||||
@@ -162,5 +166,6 @@ class AndroidSecureStore(context: Context) : SecureStore {
|
||||
const val KEY_BACKGROUND_MODE = "background_mode"
|
||||
const val KEY_BACKGROUND_COLOR = "background_color"
|
||||
const val KEY_BACKGROUND_IMAGE_PATH = "background_image_path"
|
||||
const val KEY_FONT_SIZE_SCALE = "font_size_scale"
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Density
|
||||
import iris.data.SecureStore
|
||||
import iris.net.GatewayClient
|
||||
import iris.platform.setActiveController
|
||||
@@ -55,9 +57,20 @@ fun IrisApp(
|
||||
}
|
||||
val state by controller.client.state.collectAsState()
|
||||
val theme by controller.theme.collectAsState()
|
||||
val fontScale by controller.fontSizeScale.collectAsState()
|
||||
val baseDensity = LocalDensity.current
|
||||
|
||||
IrisTheme {
|
||||
CompositionLocalProvider(LocalUserTheme provides theme) {
|
||||
// Font-size setting (Settings → Appearance): a multiplier on top of the
|
||||
// system font scale. fontScale affects sp text only — dp layout is
|
||||
// untouched, so the UI keeps its proportions at any size.
|
||||
CompositionLocalProvider(
|
||||
LocalUserTheme provides theme,
|
||||
LocalDensity provides Density(
|
||||
density = baseDensity.density,
|
||||
fontScale = baseDensity.fontScale * fontScale,
|
||||
),
|
||||
) {
|
||||
// The color goes through Surface's `color` parameter: a
|
||||
// Modifier.background on the Surface would be painted *under* the
|
||||
// Surface's own colorScheme.surface fill and never show through.
|
||||
|
||||
@@ -57,6 +57,10 @@ interface SecureStore {
|
||||
/** UI setting: background image path (empty when unused). */
|
||||
var backgroundImagePath: String
|
||||
|
||||
/** UI setting: text size multiplier (1.0 = default; applied on top of the
|
||||
* system font scale). */
|
||||
var fontSizeScale: Float
|
||||
|
||||
fun savePairing(url: String, token: String)
|
||||
fun clear()
|
||||
}
|
||||
@@ -204,6 +204,24 @@ class IrisController(
|
||||
store.backgroundImagePath = t.backgroundImagePath.orEmpty()
|
||||
}
|
||||
|
||||
// ── Font size (Settings → Appearance) ─────────────────────────────────
|
||||
// Text-size multiplier applied app-wide via LocalDensity.fontScale (scales
|
||||
// all sp text, not dp layout). Persisted; 1.0 = default.
|
||||
private val _fontSizeScale = MutableStateFlow(store.fontSizeScale.coerceIn(FONT_SCALE_MIN, FONT_SCALE_MAX))
|
||||
val fontSizeScale: StateFlow<Float> = _fontSizeScale.asStateFlow()
|
||||
|
||||
fun setFontSizeScale(scale: Float) {
|
||||
val clamped = scale.coerceIn(FONT_SCALE_MIN, FONT_SCALE_MAX)
|
||||
if (clamped == _fontSizeScale.value) return
|
||||
_fontSizeScale.value = clamped
|
||||
store.fontSizeScale = clamped
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val FONT_SCALE_MIN = 0.8f
|
||||
const val FONT_SCALE_MAX = 1.5f
|
||||
}
|
||||
|
||||
// ── M3: search state ──────────────────────────────────────────────────
|
||||
private val _searchResults = MutableStateFlow<List<SearchHit>>(emptyList())
|
||||
val searchResults: StateFlow<List<SearchHit>> = _searchResults.asStateFlow()
|
||||
|
||||
@@ -65,6 +65,7 @@ fun SettingsScreen(controller: IrisController, onBack: () -> Unit) {
|
||||
val streamingEnabled by controller.streamingEnabled.collectAsState()
|
||||
val reasoningAutoCollapse by controller.reasoningAutoCollapse.collectAsState()
|
||||
val toolDetail by controller.toolDetail.collectAsState()
|
||||
val fontSizeScale by controller.fontSizeScale.collectAsState()
|
||||
val theme = LocalUserTheme.current
|
||||
var pickerTarget by remember { mutableStateOf<PickerTarget?>(null) }
|
||||
|
||||
@@ -74,6 +75,7 @@ fun SettingsScreen(controller: IrisController, onBack: () -> Unit) {
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(12.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
@@ -259,6 +261,46 @@ fun SettingsScreen(controller: IrisController, onBack: () -> Unit) {
|
||||
}
|
||||
}
|
||||
}
|
||||
SettingsCard {
|
||||
Text("🔤 Font size", fontSize = 14.sp)
|
||||
Text(
|
||||
"Scale the text across the app",
|
||||
fontSize = 12.sp,
|
||||
color = IrisColors.textDim,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text("Aa", fontSize = 12.sp, color = IrisColors.textDim)
|
||||
Slider(
|
||||
value = fontSizeScale,
|
||||
onValueChange = { controller.setFontSizeScale(it) },
|
||||
valueRange = IrisController.FONT_SCALE_MIN..IrisController.FONT_SCALE_MAX,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
Text("Aa", fontSize = 18.sp, color = IrisColors.textDim)
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text(
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
fontSize = 13.sp,
|
||||
color = IrisColors.textSecondary,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
Text(
|
||||
"${(fontSizeScale * 100).roundToInt()}%",
|
||||
fontSize = 12.sp,
|
||||
color = IrisColors.textDim,
|
||||
)
|
||||
if (fontSizeScale != 1.0f) {
|
||||
TextButton(onClick = { controller.setFontSizeScale(1.0f) }) {
|
||||
Text("Reset", fontSize = 12.sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
"Tools",
|
||||
|
||||
@@ -44,6 +44,7 @@ class DesktopSecureStore : SecureStore {
|
||||
val backgroundMode: String = "color",
|
||||
val backgroundColor: Int = UserTheme.DEFAULT_BACKGROUND,
|
||||
val backgroundImagePath: String = "",
|
||||
val fontSizeScale: Float = 1.0f,
|
||||
)
|
||||
|
||||
init {
|
||||
@@ -206,6 +207,13 @@ class DesktopSecureStore : SecureStore {
|
||||
save(d.copy(backgroundImagePath = value))
|
||||
}
|
||||
|
||||
override var fontSizeScale: Float
|
||||
get() = load().fontSizeScale
|
||||
set(value) {
|
||||
val d = load()
|
||||
save(d.copy(fontSizeScale = value))
|
||||
}
|
||||
|
||||
override fun savePairing(url: String, token: String) {
|
||||
val d = load()
|
||||
save(d.copy(serverUrl = url.trim()))
|
||||
|
||||
Reference in new issue
Block a user