chore: 更新应用配置和工具类
- 更新AppConfig应用配置 - 更新MainActivity主活动 - 更新MockDataProvider模拟数据 - 更新Chapter数据模型 - 更新AndroidManifest配置
This commit is contained in:
@@ -18,7 +18,8 @@
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.Lifeecho" >
|
||||
android:theme="@style/Theme.Lifeecho"
|
||||
android:windowSoftInputMode="adjustResize" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
||||
@@ -5,7 +5,11 @@ import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -21,6 +25,7 @@ import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.statusBars
|
||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
@@ -29,6 +34,7 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -60,9 +66,9 @@ class MainActivity : ComponentActivity() {
|
||||
// 设置系统栏透明
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
|
||||
// 设置状态栏和导航栏完全透明
|
||||
window.statusBarColor = android.graphics.Color.TRANSPARENT
|
||||
window.navigationBarColor = android.graphics.Color.TRANSPARENT
|
||||
// 设置状态栏和导航栏完全透明(使用 WindowInsetsController 在 LaunchedEffect 中处理)
|
||||
// 注意:在 API 30+ 中,直接设置 statusBarColor 和 navigationBarColor 已弃用
|
||||
// 我们通过 WindowInsetsController 来管理系统栏外观
|
||||
|
||||
setContent {
|
||||
val darkMode = com.huaga.life_echo.ui.settings.AppSettings.rememberDarkMode()
|
||||
@@ -184,9 +190,30 @@ fun BottomNavItem(
|
||||
val iconColor = if (isSelected) LightPurple else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
val textColor = if (isSelected) LightPurple else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
|
||||
// 选中状态的缩放动画
|
||||
val scale by animateFloatAsState(
|
||||
targetValue = if (isSelected) 1.1f else 1f,
|
||||
animationSpec = tween(durationMillis = 200, easing = androidx.compose.animation.core.FastOutSlowInEasing),
|
||||
label = "nav_item_scale"
|
||||
)
|
||||
|
||||
// 点击时的缩放动画
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
val isPressed by interactionSource.collectIsPressedAsState()
|
||||
val pressScale by animateFloatAsState(
|
||||
targetValue = if (isPressed) 0.9f else 1f,
|
||||
animationSpec = tween(durationMillis = 100),
|
||||
label = "nav_item_press_scale"
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable { onClick() }
|
||||
.clickable(
|
||||
interactionSource = interactionSource,
|
||||
indication = null, // 移除默认的点击波纹效果,使用自定义动画
|
||||
onClick = onClick
|
||||
)
|
||||
.scale(scale * pressScale) // 应用缩放动画
|
||||
.padding(horizontal = 16.dp, vertical = 4.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.huaga.life_echo.config
|
||||
|
||||
object AppConfig {
|
||||
// API 基础 URL(可以从 BuildConfig 或环境变量读取)
|
||||
const val BASE_URL = "https://lifecho.worldsplats.com" // Android 模拟器使用 10.0.2.2 访问 localhost
|
||||
const val WS_BASE_URL = "https://lifecho.worldsplats.com"
|
||||
// API 基础 URL - 内网地址,用于同一局域网下的物理机测试
|
||||
// 当前主机IP: 192.168.10.9,端口: 8000
|
||||
// 如果IP地址变化,请修改此处
|
||||
const val BASE_URL = "http://192.168.10.9:8000"
|
||||
const val WS_BASE_URL = "ws://192.168.10.9:8000"
|
||||
|
||||
// 生产环境应该从配置文件或环境变量读取
|
||||
// const val BASE_URL = BuildConfig.API_BASE_URL
|
||||
|
||||
@@ -12,6 +12,7 @@ data class Chapter(
|
||||
val status: String, // draft, partial, completed
|
||||
val updatedAt: Long,
|
||||
val category: String,
|
||||
val pageCount: Int? = null
|
||||
val pageCount: Int? = null,
|
||||
val isNew: Boolean = false
|
||||
)
|
||||
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
package com.huaga.life_echo.data.mock
|
||||
|
||||
import com.huaga.life_echo.network.models.*
|
||||
import kotlinx.serialization.Serializable
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.huaga.life_echo.network.models.BookDto
|
||||
import com.huaga.life_echo.network.models.ChapterContentDto
|
||||
import com.huaga.life_echo.network.models.ChapterDto
|
||||
import com.huaga.life_echo.network.models.ConversationDetailDto
|
||||
import com.huaga.life_echo.network.models.ConversationListItemDto
|
||||
import com.huaga.life_echo.network.models.FAQDto
|
||||
import com.huaga.life_echo.network.models.MessageDto
|
||||
import com.huaga.life_echo.network.models.OrderDto
|
||||
import com.huaga.life_echo.network.models.PlanBenefitDto
|
||||
import com.huaga.life_echo.network.models.PlanDto
|
||||
import com.huaga.life_echo.network.models.QuotaCheckDto
|
||||
import com.huaga.life_echo.network.models.UserProfileDto
|
||||
|
||||
/**
|
||||
* Mock数据提供者
|
||||
@@ -89,47 +101,57 @@ object MockDataProvider {
|
||||
}
|
||||
|
||||
// 获取Mock章节列表
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
fun getMockChapters(): List<ChapterDto> {
|
||||
val now = java.time.Instant.now().toString()
|
||||
return listOf(
|
||||
ChapterDto(
|
||||
id = "chapter_001",
|
||||
title = "童年与家庭",
|
||||
content = "我出生在一个普通的农村家庭,父母都是勤劳朴实的农民。\n\n父亲是村里的木匠,手艺精湛,邻里乡亲都愿意找他帮忙。",
|
||||
orderIndex = 1,
|
||||
order_index = 1,
|
||||
status = "completed",
|
||||
category = "childhood",
|
||||
pageCount = 3,
|
||||
updatedAt = System.currentTimeMillis() - 86400000
|
||||
images = emptyList(),
|
||||
updated_at = now,
|
||||
is_new = false,
|
||||
source_segments = emptyList()
|
||||
),
|
||||
ChapterDto(
|
||||
id = "chapter_002",
|
||||
title = "上学的日子",
|
||||
content = "上学的日子总是充满欢声笑语,虽然条件艰苦,但学习的快乐让我忘记了生活的艰辛。",
|
||||
orderIndex = 2,
|
||||
order_index = 2,
|
||||
status = "partial",
|
||||
category = "education",
|
||||
pageCount = 2,
|
||||
updatedAt = System.currentTimeMillis() - 43200000
|
||||
images = emptyList(),
|
||||
updated_at = now,
|
||||
is_new = false,
|
||||
source_segments = emptyList()
|
||||
),
|
||||
ChapterDto(
|
||||
id = "chapter_003",
|
||||
title = "工作与事业",
|
||||
content = "工作是我人生中重要的转折点,让我学会了承担责任,也让我明白了生活的意义。",
|
||||
orderIndex = 3,
|
||||
order_index = 3,
|
||||
status = "pending",
|
||||
category = "career",
|
||||
pageCount = null,
|
||||
updatedAt = System.currentTimeMillis()
|
||||
images = emptyList(),
|
||||
updated_at = now,
|
||||
is_new = true,
|
||||
source_segments = emptyList()
|
||||
),
|
||||
ChapterDto(
|
||||
id = "chapter_004",
|
||||
title = "爱情与婚姻",
|
||||
content = "爱情是人生中最美好的经历之一,它让我懂得了什么是真正的幸福。",
|
||||
orderIndex = 4,
|
||||
order_index = 4,
|
||||
status = "pending",
|
||||
category = "family",
|
||||
pageCount = null,
|
||||
updatedAt = System.currentTimeMillis()
|
||||
images = emptyList(),
|
||||
updated_at = now,
|
||||
is_new = true,
|
||||
source_segments = emptyList()
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -138,17 +160,17 @@ object MockDataProvider {
|
||||
fun getMockBookInfo(): BookDto {
|
||||
return BookDto(
|
||||
id = "book_001",
|
||||
userId = "user_001",
|
||||
title = "这一生",
|
||||
subtitle = "我的回忆录",
|
||||
totalPages = 5,
|
||||
totalWords = 5000,
|
||||
updatedAt = System.currentTimeMillis(),
|
||||
lastUpdatedAt = System.currentTimeMillis() - 120000 // 2分钟前
|
||||
total_pages = 5,
|
||||
total_words = 5000,
|
||||
cover_image_url = null,
|
||||
has_update = true,
|
||||
last_update_chapter_id = "chapter_003"
|
||||
)
|
||||
}
|
||||
|
||||
// 获取Mock章节内容
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
fun getMockChapterContent(id: String): ChapterContentDto {
|
||||
val chapters = getMockChapters()
|
||||
val chapter = chapters.find { it.id == id } ?: chapters[0]
|
||||
@@ -157,11 +179,17 @@ object MockDataProvider {
|
||||
id = chapter.id,
|
||||
title = chapter.title,
|
||||
content = chapter.content,
|
||||
orderIndex = chapter.orderIndex,
|
||||
orderIndex = chapter.order_index,
|
||||
status = chapter.status,
|
||||
category = chapter.category,
|
||||
pageCount = chapter.pageCount,
|
||||
updatedAt = chapter.updatedAt ?: System.currentTimeMillis(),
|
||||
pageCount = null,
|
||||
updatedAt = chapter.updated_at?.let {
|
||||
try {
|
||||
java.time.Instant.parse(it).toEpochMilli()
|
||||
} catch (e: Exception) {
|
||||
System.currentTimeMillis()
|
||||
}
|
||||
} ?: System.currentTimeMillis(),
|
||||
quotes = if (chapter.category == "childhood") {
|
||||
listOf("\"日子虽然清苦, 但那时候的快乐是最纯粹的。\"")
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user