feat: 增强对话代理和提示生成逻辑

- 在ConversationAgent中添加对话历史和轮数的计算,以支持更智能的对话管理
- 引入同一话题轮数的估算逻辑,优化对话的连贯性
- 更新get_guided_conversation_prompt函数,动态调整对话策略和回应风格
- 在UI组件中优化消息显示,支持流式消息和多部分消息的展示
- 更新应用设置管理,支持持久化存储和Compose状态观察
This commit is contained in:
penghanyuan
2026-01-29 20:09:09 +01:00
parent ce8e849b92
commit 41ceb3dad8
10 changed files with 437 additions and 124 deletions

View File

@@ -64,6 +64,8 @@ class MainActivity : ComponentActivity() {
// 初始化TokenManager
TokenManager.initialize(this)
// 初始化应用设置(从 SharedPreferences 加载)
com.huaga.life_echo.ui.settings.AppSettings.initialize(this)
// 启用边缘到边缘显示
enableEdgeToEdge()
// 设置系统栏透明

View File

@@ -71,15 +71,30 @@ fun MessageList(
}
}
item(key = message.id) {
when (message.senderType) {
"user" -> {
when (message.senderType) {
"user" -> {
item(key = message.id) {
UserMessageBubble(text = message.content)
}
"assistant" -> {
AIMessageBubble(
text = message.content
)
}
"assistant" -> {
// 在 [SPLIT] 处分割消息,显示为多个气泡
val splitParts = message.content.split("[SPLIT]")
.map { it.trim() }
.filter { it.isNotEmpty() }
if (splitParts.size > 1) {
// 多个部分,显示为多个气泡
splitParts.forEachIndexed { partIndex, part ->
item(key = "${message.id}_part_$partIndex") {
AIMessageBubble(text = part)
}
}
} else {
// 单个部分,正常显示
item(key = message.id) {
AIMessageBubble(text = message.content)
}
}
}
}
@@ -88,11 +103,27 @@ fun MessageList(
}
// 流式消息显示 - 使用专门的流式消息气泡组件
// 在 [SPLIT] 处分割流式消息
if (isStreaming) {
item(key = "streaming_message") {
StreamingAIMessageBubble(
text = streamingText
)
val streamingParts = streamingText.split("[SPLIT]")
.map { it.trim() }
.filter { it.isNotEmpty() }
if (streamingParts.size > 1) {
// 已完成的部分显示为普通气泡
streamingParts.dropLast(1).forEachIndexed { partIndex, part ->
item(key = "streaming_complete_$partIndex") {
AIMessageBubble(text = part)
}
}
// 最后一部分显示为流式气泡(可能还在输入)
item(key = "streaming_message") {
StreamingAIMessageBubble(text = streamingParts.last())
}
} else {
item(key = "streaming_message") {
StreamingAIMessageBubble(text = streamingText)
}
}
}

View File

@@ -15,8 +15,6 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.huaga.life_echo.ui.theme.AppDimensions
import com.huaga.life_echo.ui.theme.AppWhite
import com.huaga.life_echo.ui.theme.SlatePurple
/**
* 区块卡片组件
@@ -24,7 +22,8 @@ import com.huaga.life_echo.ui.theme.SlatePurple
*
* 设计规范:
* - 标题12sp, 大写, 灰紫色, 0.5 letter-spacing
* - 卡片:色背景, 16dp 圆角, 轻微阴影
* - 卡片:表面颜色背景, 16dp 圆角, 轻微阴影
* - 支持夜间模式自动适配
*
* @param title 区块标题(会自动转为大写)
* @param modifier 外部修饰符
@@ -49,16 +48,16 @@ fun SectionCard(
.padding(bottom = 10.dp),
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
color = SlatePurple,
color = MaterialTheme.colorScheme.onSurfaceVariant,
letterSpacing = 0.5.sp
)
// 白色卡片容器
// 卡片容器(自动适配夜间模式)
Card(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(AppDimensions.cardRadius),
colors = CardDefaults.cardColors(
containerColor = AppWhite
containerColor = MaterialTheme.colorScheme.surface
),
elevation = CardDefaults.cardElevation(
defaultElevation = AppDimensions.cardElevation
@@ -88,7 +87,7 @@ fun SimpleCard(
modifier = modifier.fillMaxWidth(),
shape = RoundedCornerShape(AppDimensions.cardRadius),
colors = CardDefaults.cardColors(
containerColor = AppWhite
containerColor = MaterialTheme.colorScheme.surface
),
elevation = CardDefaults.cardElevation(
defaultElevation = AppDimensions.cardElevation

View File

@@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Switch
import androidx.compose.material3.SwitchDefaults
import androidx.compose.material3.Text
@@ -21,7 +22,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
@@ -29,11 +29,7 @@ import com.huaga.life_echo.ui.icons.AppIcons
import com.huaga.life_echo.ui.theme.AppDimensions
import com.huaga.life_echo.ui.theme.AppTypography
import com.huaga.life_echo.ui.theme.AppWhite
import com.huaga.life_echo.ui.theme.DeepPurple
import com.huaga.life_echo.ui.theme.DividerColor
import com.huaga.life_echo.ui.theme.Lavender
import com.huaga.life_echo.ui.theme.MediumPurple
import com.huaga.life_echo.ui.theme.SlatePurple
/**
* 设置项类型
@@ -47,11 +43,12 @@ enum class SettingItemType {
* 设置项组件
*
* 设计规范:
* - 图标容器36x36dp, Lavender 背景, 10dp 圆角
* - 图标20dp, DeepPurple 颜色
* - 标题15sp, DeepPurple 颜色
* - 描述12sp, SlatePurple 颜色
* - 箭头18dp, SlatePurple 颜色
* - 图标容器36x36dp, 次要颜色背景, 10dp 圆角
* - 图标20dp, 主要文字颜色
* - 标题15sp, 主要文字颜色
* - 描述12sp, 次要文字颜色
* - 箭头18dp, 次要文字颜色
* - 支持夜间模式自动适配
*
* @param icon 图标
* @param label 标题
@@ -75,6 +72,11 @@ fun SettingItem(
isLast: Boolean = false,
modifier: Modifier = Modifier
) {
val contentColor = MaterialTheme.colorScheme.onSurface
val secondaryColor = MaterialTheme.colorScheme.onSurfaceVariant
val iconContainerColor = MaterialTheme.colorScheme.secondary.copy(alpha = 0.3f)
val dividerColor = MaterialTheme.colorScheme.outline.copy(alpha = 0.1f)
Column(modifier = modifier.fillMaxWidth()) {
Row(
modifier = Modifier
@@ -88,13 +90,13 @@ fun SettingItem(
modifier = Modifier
.size(AppDimensions.iconContainerSize)
.clip(RoundedCornerShape(AppDimensions.iconContainerRadius))
.background(Lavender),
.background(iconContainerColor),
contentAlignment = Alignment.Center
) {
Icon(
imageVector = icon,
contentDescription = label,
tint = DeepPurple,
tint = contentColor,
modifier = Modifier.size(AppDimensions.iconSize)
)
}
@@ -107,14 +109,14 @@ fun SettingItem(
text = label,
fontSize = AppTypography.titleSmall,
fontWeight = FontWeight.Normal,
color = DeepPurple
color = contentColor
)
if (description != null) {
Spacer(modifier = Modifier.height(2.dp))
Text(
text = description,
fontSize = AppTypography.captionMedium,
color = SlatePurple
color = secondaryColor
)
}
}
@@ -125,7 +127,7 @@ fun SettingItem(
Icon(
imageVector = AppIcons.ChevronRight,
contentDescription = "进入",
tint = SlatePurple,
tint = secondaryColor,
modifier = Modifier.size(AppDimensions.iconSizeSmall)
)
}
@@ -137,7 +139,7 @@ fun SettingItem(
checkedThumbColor = AppWhite,
checkedTrackColor = MediumPurple,
uncheckedThumbColor = AppWhite,
uncheckedTrackColor = SlatePurple
uncheckedTrackColor = secondaryColor
)
)
}
@@ -149,7 +151,7 @@ fun SettingItem(
HorizontalDivider(
modifier = Modifier.padding(horizontal = AppDimensions.cardPadding),
thickness = AppDimensions.dividerThickness,
color = DividerColor
color = dividerColor
)
}
}
@@ -176,6 +178,11 @@ fun SettingItemWithTrailing(
modifier: Modifier = Modifier,
trailing: @Composable () -> Unit
) {
val contentColor = MaterialTheme.colorScheme.onSurface
val secondaryColor = MaterialTheme.colorScheme.onSurfaceVariant
val iconContainerColor = MaterialTheme.colorScheme.secondary.copy(alpha = 0.3f)
val dividerColor = MaterialTheme.colorScheme.outline.copy(alpha = 0.1f)
Column(modifier = modifier.fillMaxWidth()) {
Row(
modifier = Modifier
@@ -189,13 +196,13 @@ fun SettingItemWithTrailing(
modifier = Modifier
.size(AppDimensions.iconContainerSize)
.clip(RoundedCornerShape(AppDimensions.iconContainerRadius))
.background(Lavender),
.background(iconContainerColor),
contentAlignment = Alignment.Center
) {
Icon(
imageVector = icon,
contentDescription = label,
tint = DeepPurple,
tint = contentColor,
modifier = Modifier.size(AppDimensions.iconSize)
)
}
@@ -208,14 +215,14 @@ fun SettingItemWithTrailing(
text = label,
fontSize = AppTypography.titleSmall,
fontWeight = FontWeight.Normal,
color = DeepPurple
color = contentColor
)
if (description != null) {
Spacer(modifier = Modifier.height(2.dp))
Text(
text = description,
fontSize = AppTypography.captionMedium,
color = SlatePurple
color = secondaryColor
)
}
}
@@ -229,7 +236,7 @@ fun SettingItemWithTrailing(
HorizontalDivider(
modifier = Modifier.padding(horizontal = AppDimensions.cardPadding),
thickness = AppDimensions.dividerThickness,
color = DividerColor
color = dividerColor
)
}
}

View File

@@ -51,11 +51,7 @@ import com.huaga.life_echo.ui.settings.AppSettings
import com.huaga.life_echo.ui.theme.AppDimensions
import com.huaga.life_echo.ui.theme.AppTypography
import com.huaga.life_echo.ui.theme.AppWhite
import com.huaga.life_echo.ui.theme.Cream
import com.huaga.life_echo.ui.theme.DeepPurple
import com.huaga.life_echo.ui.theme.Lavender
import com.huaga.life_echo.ui.theme.MediumPurple
import com.huaga.life_echo.ui.theme.SlatePurple
import com.huaga.life_echo.ui.viewmodel.AuthViewModel
import com.huaga.life_echo.ui.viewmodel.PaymentViewModel
import com.huaga.life_echo.ui.viewmodel.ProfileViewModel
@@ -157,7 +153,7 @@ fun ProfileScreen(
LazyColumn(
modifier = Modifier
.fillMaxSize()
.background(Cream)
.background(androidx.compose.material3.MaterialTheme.colorScheme.background)
.windowInsetsPadding(WindowInsets.statusBars)
.padding(horizontal = AppDimensions.screenPadding)
) {
@@ -248,7 +244,15 @@ fun ProfileScreen(
label = "夜间模式",
type = SettingItemType.TOGGLE,
value = darkMode,
onToggle = { darkMode = it },
onToggle = { darkMode = it }
)
SettingItem(
icon = AppIcons.FormatSize,
label = "大字模式",
description = "增大字体以便阅读",
type = SettingItemType.TOGGLE,
value = largeFontMode,
onToggle = { largeFontMode = it },
isLast = true
)
}
@@ -285,7 +289,7 @@ fun ProfileScreen(
.fillMaxWidth()
.padding(vertical = AppDimensions.sectionSpacing),
fontSize = AppTypography.captionMedium,
color = SlatePurple,
color = androidx.compose.material3.MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center
)
}
@@ -307,6 +311,10 @@ private fun ProfileHeader(
onLoginClick: () -> Unit,
onProfileClick: () -> Unit
) {
val contentColor = androidx.compose.material3.MaterialTheme.colorScheme.onBackground
val secondaryColor = androidx.compose.material3.MaterialTheme.colorScheme.onSurfaceVariant
val avatarBgColor = androidx.compose.material3.MaterialTheme.colorScheme.secondary.copy(alpha = 0.3f)
Column(
modifier = Modifier
.fillMaxWidth()
@@ -320,13 +328,13 @@ private fun ProfileHeader(
modifier = Modifier
.size(AppDimensions.avatarSizeLarge)
.clip(CircleShape)
.background(Lavender),
.background(avatarBgColor),
contentAlignment = Alignment.Center
) {
Icon(
imageVector = AppIcons.Person,
contentDescription = "用户头像",
tint = DeepPurple,
tint = contentColor,
modifier = Modifier.size(36.dp)
)
}
@@ -338,7 +346,7 @@ private fun ProfileHeader(
text = nickname,
fontSize = AppTypography.titleLarge,
fontWeight = FontWeight.SemiBold,
color = DeepPurple
color = contentColor
)
Spacer(modifier = Modifier.height(AppDimensions.tinySpacing))
@@ -353,13 +361,13 @@ private fun ProfileHeader(
modifier = Modifier
.size(AppDimensions.avatarSizeLarge)
.clip(CircleShape)
.background(Lavender),
.background(avatarBgColor),
contentAlignment = Alignment.Center
) {
Icon(
imageVector = AppIcons.Person,
contentDescription = "用户头像",
tint = DeepPurple,
tint = contentColor,
modifier = Modifier.size(36.dp)
)
}
@@ -370,7 +378,7 @@ private fun ProfileHeader(
text = "未登录",
fontSize = AppTypography.titleLarge,
fontWeight = FontWeight.SemiBold,
color = DeepPurple
color = contentColor
)
Spacer(modifier = Modifier.height(AppDimensions.smallSpacing))
@@ -378,7 +386,7 @@ private fun ProfileHeader(
Text(
text = "登录以同步您的数据",
fontSize = AppTypography.bodySmall,
color = SlatePurple
color = secondaryColor
)
Spacer(modifier = Modifier.height(AppDimensions.sectionSpacing))

View File

@@ -1,15 +1,23 @@
package com.huaga.life_echo.ui.settings
import android.content.Context
import android.content.SharedPreferences
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
/**
* 应用设置管理
* 支持持久化存储和 Compose 状态观察
*/
object AppSettings {
private const val PREFS_NAME = "life_echo_settings"
private const val KEY_DARK_MODE = "dark_mode"
private const val KEY_LARGE_FONT_MODE = "large_font_mode"
private const val KEY_SPEECH_RATE = "speech_rate"
private var prefs: SharedPreferences? = null
// 语速设置:慢速、标准、快速
enum class SpeechRate(val label: String, val multiplier: Float) {
SLOW("慢速", 0.75f),
@@ -17,34 +25,67 @@ object AppSettings {
FAST("快速", 1.5f)
}
// 使用 mutableStateOf 以便 Compose 可以观察变化
private val _speechRate = mutableStateOf(SpeechRate.STANDARD)
private val _largeFontMode = mutableStateOf(false)
private val _darkMode = mutableStateOf(false)
/**
* 初始化设置(从 SharedPreferences 加载)
* 应在 Application 或 MainActivity 中调用
*/
fun initialize(context: Context) {
prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
// 从 SharedPreferences 加载保存的设置
prefs?.let { p ->
_darkMode.value = p.getBoolean(KEY_DARK_MODE, false)
_largeFontMode.value = p.getBoolean(KEY_LARGE_FONT_MODE, false)
val speechRateOrdinal = p.getInt(KEY_SPEECH_RATE, SpeechRate.STANDARD.ordinal)
_speechRate.value = SpeechRate.entries.getOrElse(speechRateOrdinal) { SpeechRate.STANDARD }
}
}
var speechRate: SpeechRate
get() = _speechRate.value
set(value) { _speechRate.value = value }
set(value) {
_speechRate.value = value
prefs?.edit()?.putInt(KEY_SPEECH_RATE, value.ordinal)?.apply()
}
private val _largeFontMode = mutableStateOf(false)
var largeFontMode: Boolean
get() = _largeFontMode.value
set(value) { _largeFontMode.value = value }
set(value) {
_largeFontMode.value = value
prefs?.edit()?.putBoolean(KEY_LARGE_FONT_MODE, value)?.apply()
}
private val _darkMode = mutableStateOf(false)
var darkMode: Boolean
get() = _darkMode.value
set(value) { _darkMode.value = value }
set(value) {
_darkMode.value = value
prefs?.edit()?.putBoolean(KEY_DARK_MODE, value)?.apply()
}
// 用于在Compose中观察设置变化 - 直接返回mutableStateOf的值
// 用于在 Compose 中观察设置变化 - 返回 State 的 value
// 这些函数返回的是 State 内部的值,当 State 变化时会自动触发重组
@Composable
fun rememberDarkMode(): Boolean {
return remember { _darkMode }.value
return _darkMode.value
}
@Composable
fun rememberLargeFontMode(): Boolean {
return remember { _largeFontMode }.value
return _largeFontMode.value
}
@Composable
fun rememberSpeechRate(): SpeechRate {
return remember { _speechRate }.value
return _speechRate.value
}
// 提供直接访问 State 的方式(用于需要 State 对象的场景)
val darkModeState: State<Boolean> get() = _darkMode
val largeFontModeState: State<Boolean> get() = _largeFontMode
val speechRateState: State<SpeechRate> get() = _speechRate
}

View File

@@ -1,7 +1,13 @@
package com.huaga.life_echo.ui.theme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.huaga.life_echo.ui.settings.AppSettings
/**
* 设计系统尺寸常量
@@ -78,38 +84,154 @@ object AppDimensions {
val headerElevation = 0.dp // 头部阴影
}
/**
* 字体大小数据类
* 支持大字模式动态调整
*/
data class AppTypographyData(
// Heading sizes
val headingLarge: TextUnit,
val headingMedium: TextUnit,
val headingSmall: TextUnit,
// Title sizes
val titleLarge: TextUnit,
val titleMedium: TextUnit,
val titleSmall: TextUnit,
// Body sizes
val bodyLarge: TextUnit,
val bodyMedium: TextUnit,
val bodySmall: TextUnit,
// Caption sizes
val captionLarge: TextUnit,
val captionMedium: TextUnit,
val captionSmall: TextUnit,
// Special
val sectionTitle: TextUnit,
val badge: TextUnit,
// Line heights
val lineHeightNormal: TextUnit,
val lineHeightTight: TextUnit,
val lineHeightLoose: TextUnit
)
/**
* 普通字体大小
*/
private val NormalTypography = AppTypographyData(
headingLarge = 32.sp,
headingMedium = 24.sp,
headingSmall = 20.sp,
titleLarge = 18.sp,
titleMedium = 16.sp,
titleSmall = 15.sp,
bodyLarge = 15.sp,
bodyMedium = 14.sp,
bodySmall = 13.sp,
captionLarge = 13.sp,
captionMedium = 12.sp,
captionSmall = 11.sp,
sectionTitle = 12.sp,
badge = 10.sp,
lineHeightNormal = 22.sp,
lineHeightTight = 20.sp,
lineHeightLoose = 24.sp
)
/**
* 大字模式字体大小(增加约 20%
*/
private val LargeTypography = AppTypographyData(
headingLarge = 38.sp,
headingMedium = 29.sp,
headingSmall = 24.sp,
titleLarge = 22.sp,
titleMedium = 19.sp,
titleSmall = 18.sp,
bodyLarge = 18.sp,
bodyMedium = 17.sp,
bodySmall = 16.sp,
captionLarge = 16.sp,
captionMedium = 14.sp,
captionSmall = 13.sp,
sectionTitle = 14.sp,
badge = 12.sp,
lineHeightNormal = 26.sp,
lineHeightTight = 24.sp,
lineHeightLoose = 29.sp
)
/**
* CompositionLocal for AppTypography
*/
val LocalAppTypography = compositionLocalOf { NormalTypography }
/**
* 设计系统字体大小常量
* 根据大字模式设置动态调整
*/
object AppTypography {
// Heading sizes
val headingLarge = 32.sp // 大标题(头部标题)
val headingMedium = 24.sp // 中等标题(书名)
val headingSmall = 20.sp // 小标题
val headingLarge: TextUnit
@Composable get() = LocalAppTypography.current.headingLarge
val headingMedium: TextUnit
@Composable get() = LocalAppTypography.current.headingMedium
val headingSmall: TextUnit
@Composable get() = LocalAppTypography.current.headingSmall
// Title sizes
val titleLarge = 18.sp // 大标题文字
val titleMedium = 16.sp // 中等标题文字
val titleSmall = 15.sp // 小标题文字
val titleLarge: TextUnit
@Composable get() = LocalAppTypography.current.titleLarge
val titleMedium: TextUnit
@Composable get() = LocalAppTypography.current.titleMedium
val titleSmall: TextUnit
@Composable get() = LocalAppTypography.current.titleSmall
// Body sizes
val bodyLarge = 15.sp // 大正文
val bodyMedium = 14.sp // 中等正文
val bodySmall = 13.sp // 小正文
val bodyLarge: TextUnit
@Composable get() = LocalAppTypography.current.bodyLarge
val bodyMedium: TextUnit
@Composable get() = LocalAppTypography.current.bodyMedium
val bodySmall: TextUnit
@Composable get() = LocalAppTypography.current.bodySmall
// Caption sizes
val captionLarge = 13.sp // 大说明文字
val captionMedium = 12.sp // 中等说明文字
val captionSmall = 11.sp // 小说明文字
val captionLarge: TextUnit
@Composable get() = LocalAppTypography.current.captionLarge
val captionMedium: TextUnit
@Composable get() = LocalAppTypography.current.captionMedium
val captionSmall: TextUnit
@Composable get() = LocalAppTypography.current.captionSmall
// Special
val sectionTitle = 12.sp // 区块标题
val badge = 10.sp // 徽章文字
val sectionTitle: TextUnit
@Composable get() = LocalAppTypography.current.sectionTitle
val badge: TextUnit
@Composable get() = LocalAppTypography.current.badge
// Line heights
val lineHeightNormal = 22.sp // 正常行高
val lineHeightTight = 20.sp // 紧凑行高
val lineHeightLoose = 24.sp // 宽松行高
val lineHeightNormal: TextUnit
@Composable get() = LocalAppTypography.current.lineHeightNormal
val lineHeightTight: TextUnit
@Composable get() = LocalAppTypography.current.lineHeightTight
val lineHeightLoose: TextUnit
@Composable get() = LocalAppTypography.current.lineHeightLoose
}
/**
* 获取当前的 AppTypographyData
* 根据大字模式返回对应的字体大小
*/
@Composable
fun rememberAppTypography(): AppTypographyData {
val isLargeFont = AppSettings.rememberLargeFontMode()
return remember(isLargeFont) {
if (isLargeFont) LargeTypography else NormalTypography
}
}
/**

View File

@@ -1,8 +1,6 @@
package com.huaga.life_echo.ui.theme
import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
@@ -10,11 +8,7 @@ import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.sp
import com.huaga.life_echo.ui.settings.AppSettings
// 深色主题配色方案
@@ -64,7 +58,7 @@ fun LifeechoTheme(
) {
// 使用AppSettings中的状态这样当设置变化时会触发重组
val isDarkMode = darkTheme ?: AppSettings.rememberDarkMode()
val isLargeFont = AppSettings.rememberLargeFontMode()
val appTypography = rememberAppTypography()
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
@@ -74,27 +68,15 @@ fun LifeechoTheme(
isDarkMode -> DarkColorScheme
else -> LightColorScheme
}
// 根据大字模式调整字体大小
val adjustedTypography = if (isLargeFont) {
Typography.copy(
bodyLarge = Typography.bodyLarge.copy(fontSize = 18.sp),
bodyMedium = Typography.bodyMedium.copy(fontSize = 16.sp),
bodySmall = Typography.bodySmall.copy(fontSize = 14.sp),
titleLarge = Typography.titleLarge.copy(fontSize = 24.sp),
titleMedium = Typography.titleMedium.copy(fontSize = 20.sp),
titleSmall = Typography.titleSmall.copy(fontSize = 18.sp),
headlineLarge = Typography.headlineLarge.copy(fontSize = 32.sp),
headlineMedium = Typography.headlineMedium.copy(fontSize = 28.sp),
headlineSmall = Typography.headlineSmall.copy(fontSize = 24.sp)
)
} else {
Typography
}
MaterialTheme(
colorScheme = colorScheme,
typography = adjustedTypography,
content = content
)
// 提供 LocalAppTypography这样所有子组件都可以使用大字模式
CompositionLocalProvider(
LocalAppTypography provides appTypography
) {
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}
}