diff --git a/app-android/app/src/main/java/com/huaga/life_echo/MainActivity.kt b/app-android/app/src/main/java/com/huaga/life_echo/MainActivity.kt index 290e68d..7c79b9a 100644 --- a/app-android/app/src/main/java/com/huaga/life_echo/MainActivity.kt +++ b/app-android/app/src/main/java/com/huaga/life_echo/MainActivity.kt @@ -18,6 +18,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding 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.material3.Icon @@ -51,31 +52,30 @@ import com.huaga.life_echo.ui.theme.LightPurple class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - + // 初始化TokenManager TokenManager.initialize(this) // 启用边缘到边缘显示 enableEdgeToEdge() // 设置系统栏透明 WindowCompat.setDecorFitsSystemWindows(window, false) - - // 设置状态栏完全透明 + + // 设置状态栏和导航栏完全透明 window.statusBarColor = android.graphics.Color.TRANSPARENT window.navigationBarColor = android.graphics.Color.TRANSPARENT - - // 设置状态栏控制器,让内容可以延伸到状态栏下方 - val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) - windowInsetsController.isAppearanceLightStatusBars = !com.huaga.life_echo.ui.settings.AppSettings.darkMode - + setContent { - val darkMode = com.huaga.life_echo.ui.settings.AppSettings.darkMode + val darkMode = com.huaga.life_echo.ui.settings.AppSettings.rememberDarkMode() LifeechoTheme(darkTheme = darkMode) { - // 根据主题更新状态栏图标颜色 + // 根据主题更新系统栏图标颜色 androidx.compose.runtime.LaunchedEffect(darkMode) { val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) + // 亮色主题:深色图标(isAppearanceLightStatusBars = true) + // 暗色主题:浅色图标(isAppearanceLightStatusBars = false) windowInsetsController.isAppearanceLightStatusBars = !darkMode + windowInsetsController.isAppearanceLightNavigationBars = !darkMode } - LifeechoApp() + LifeechoApp(TokenManager.isLoggedIn) } } } @@ -84,25 +84,45 @@ class MainActivity : ComponentActivity() { @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") @PreviewScreenSizes @Composable -fun LifeechoApp() { +fun LifeechoApp(initialLoggedIn: Boolean = false) { + var isLoggedIn by rememberSaveable { mutableStateOf(initialLoggedIn) } val navController = rememberNavController() var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.CHAT) } // 获取当前路由,判断是否显示底部导航栏 val navBackStackEntry by navController.currentBackStackEntryAsState() val currentRoute = navBackStackEntry?.destination?.route - val shouldShowBottomBar = currentRoute != null && !currentRoute.startsWith("create_memory") + + // 同步登录状态变化 + androidx.compose.runtime.LaunchedEffect(TokenManager.isLoggedIn) { + isLoggedIn = TokenManager.isLoggedIn + } + + // 同步currentDestination与当前路由 + androidx.compose.runtime.LaunchedEffect(currentRoute) { + when (currentRoute) { + Screen.ConversationList.route -> currentDestination = AppDestinations.CHAT + Screen.MyMemoir.route -> currentDestination = AppDestinations.MEMOIR + Screen.Profile.route -> currentDestination = AppDestinations.PROFILE + } + } + + // 只在聊天对话选择页面、回忆录页面、我的页面显示底部导航栏 + val shouldShowBottomBar = currentRoute == Screen.ConversationList.route || + currentRoute == Screen.MyMemoir.route || + currentRoute == Screen.Profile.route Scaffold( - modifier = Modifier.fillMaxSize(), + modifier = Modifier + .fillMaxSize() + .windowInsetsPadding(WindowInsets.statusBars), bottomBar = { - // 底部导航栏 - 只在非聊天详情页显示 + // 底部导航栏 - 只在特定页面显示 if (shouldShowBottomBar) { Surface( modifier = Modifier .fillMaxWidth() - .windowInsetsPadding(WindowInsets.navigationBars) - .padding(bottom = 8.dp), + .windowInsetsPadding(WindowInsets.navigationBars), color = MaterialTheme.colorScheme.surface, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), shadowElevation = 8.dp @@ -140,7 +160,17 @@ fun LifeechoApp() { } ) { paddingValues -> Box(modifier = Modifier.padding(paddingValues)) { - AppNavigation(navController = navController) + AppNavigation( + navController = navController, + isLoggedIn = isLoggedIn, + onLoginSuccess = { isLoggedIn = true }, + onLogout = { + isLoggedIn = false + navController.navigate(Screen.Login.route) { + popUpTo(0) { inclusive = true } + } + } + ) } } } diff --git a/app-android/app/src/main/java/com/huaga/life_echo/config/AppConfig.kt b/app-android/app/src/main/java/com/huaga/life_echo/config/AppConfig.kt index 09bfff9..c68e696 100644 --- a/app-android/app/src/main/java/com/huaga/life_echo/config/AppConfig.kt +++ b/app-android/app/src/main/java/com/huaga/life_echo/config/AppConfig.kt @@ -2,8 +2,8 @@ package com.huaga.life_echo.config object AppConfig { // API 基础 URL(可以从 BuildConfig 或环境变量读取) - const val BASE_URL = "http://10.0.2.2:8000" // Android 模拟器使用 10.0.2.2 访问 localhost - const val WS_BASE_URL = "ws://10.0.2.2:8000" + const val BASE_URL = "https://lifecho.worldsplats.com" // Android 模拟器使用 10.0.2.2 访问 localhost + const val WS_BASE_URL = "https://lifecho.worldsplats.com" // 生产环境应该从配置文件或环境变量读取 // const val BASE_URL = BuildConfig.API_BASE_URL diff --git a/app-android/app/src/main/java/com/huaga/life_echo/navigation/AppNavigation.kt b/app-android/app/src/main/java/com/huaga/life_echo/navigation/AppNavigation.kt index 65cbf82..4546334 100644 --- a/app-android/app/src/main/java/com/huaga/life_echo/navigation/AppNavigation.kt +++ b/app-android/app/src/main/java/com/huaga/life_echo/navigation/AppNavigation.kt @@ -6,15 +6,7 @@ import androidx.navigation.NavType import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.navArgument -import com.huaga.life_echo.ui.screens.ConversationListScreen -import com.huaga.life_echo.ui.screens.CreateMemoryScreen -import com.huaga.life_echo.ui.screens.ExportDataScreen -import com.huaga.life_echo.ui.screens.LoginScreen -import com.huaga.life_echo.ui.screens.MyMemoirScreen -import com.huaga.life_echo.ui.screens.MyOrdersScreen -import com.huaga.life_echo.ui.screens.ProfileScreen -import com.huaga.life_echo.ui.screens.RegisterScreen -import com.huaga.life_echo.ui.screens.UpgradePlanScreen +import com.huaga.life_echo.ui.screens.* sealed class Screen(val route: String) { object ConversationList : Screen("conversation_list") @@ -28,13 +20,22 @@ sealed class Screen(val route: String) { object UpgradePlan : Screen("upgrade_plan") object MyOrders : Screen("my_orders") object ExportData : Screen("export_data") + object PlanDetails : Screen("plan_details") + object FAQ : Screen("faq") + object Feedback : Screen("feedback") + object About : Screen("about") } @Composable -fun AppNavigation(navController: NavHostController) { +fun AppNavigation( + navController: NavHostController, + isLoggedIn: Boolean = false, + onLoginSuccess: () -> Unit = {}, + onLogout: () -> Unit = {} +) { NavHost( navController = navController, - startDestination = Screen.ConversationList.route + startDestination = if (isLoggedIn) Screen.ConversationList.route else Screen.Login.route ) { composable(Screen.ConversationList.route) { ConversationListScreen( @@ -68,10 +69,26 @@ fun AppNavigation(navController: NavHostController) { composable(Screen.ExportData.route) { ExportDataScreen(navController = navController) } + composable(Screen.PlanDetails.route) { + PlanDetailsScreen(navController = navController) + } + composable(Screen.FAQ.route) { + FAQScreen(navController = navController) + } + composable(Screen.Feedback.route) { + FeedbackScreen(navController = navController) + } + composable(Screen.About.route) { + AboutScreen(navController = navController) + } composable(Screen.Login.route) { LoginScreen( onLoginSuccess = { - navController.popBackStack() + // 登录成功后导航到主界面 + navController.navigate(Screen.ConversationList.route) { + // 清除登录页面,避免返回 + popUpTo(Screen.Login.route) { inclusive = true } + } }, onNavigateToRegister = { navController.navigate(Screen.Register.route)