Rainytoken/app/src/main/java/com/rainy/token/ui/RainyTokenNavHost.kt
WaterRain 3aca009290
🎉 RainyToken — AI 余额查询 APP
- Jetpack Compose + Material 3 仪表盘
- DeepSeek REST API 余额查询
- OpenCode Go WebView 抓取用量
- 3 张 Canvas 图表(消耗/请求/Token)
- 原始记录分页浏览
- DataStore + 内存缓存
- 桌面小组件
2026-06-16 01:46:03 +00:00

116 lines
4.8 KiB
Kotlin

package com.rainy.token.ui
import androidx.compose.runtime.Composable
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.rainy.token.domain.service.ServiceType
import com.rainy.token.ui.dashboard.DashboardScreen
import com.rainy.token.ui.dashboard.UsageDataScreen
import com.rainy.token.ui.dashboard.UsageDetailScreen
import com.rainy.token.ui.dashboard.UsageOverviewScreen
import com.rainy.token.ui.servicedetail.ServiceDetailScreen
import com.rainy.token.ui.settings.CredentialEditScreen
import com.rainy.token.ui.settings.SettingsScreen
import com.rainy.token.ui.webview.WebViewLoginScreen
/**
* 应用导航图。当前阶段 4 接入了完整路径:
* Dashboard → Settings → CredentialEdit → WebViewLogin
* Dashboard → ServiceDetail
*/
object Routes {
const val DASHBOARD = "dashboard"
const val SETTINGS = "settings"
const val CREDENTIAL_EDIT = "credential_edit/{type}"
fun credentialEdit(type: ServiceType) = "credential_edit/${type.name}"
const val WEBVIEW_LOGIN = "webview_login/{type}"
fun webviewLogin(type: ServiceType) = "webview_login/${type.name}"
const val SERVICE_DETAIL = "service/{type}"
fun serviceDetail(type: ServiceType) = "service/${type.name}"
const val USAGE_DETAIL = "usage_detail"
const val USAGE_OVERVIEW = "usage_overview"
const val USAGE_DATA = "usage_data"
}
private fun parseServiceType(typeName: String?): ServiceType =
typeName?.let {
ServiceType.fromStorageKey(it) ?: runCatching { ServiceType.valueOf(it) }.getOrNull()
} ?: ServiceType.DEEPSEEK
@Composable
fun RainyTokenNavHost() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Routes.DASHBOARD) {
composable(Routes.DASHBOARD) {
DashboardScreen(
onOpenSettings = { navController.navigate(Routes.SETTINGS) },
onOpenService = { type -> navController.navigate(Routes.serviceDetail(type)) },
onOpenUsageDetail = { navController.navigate(Routes.USAGE_DETAIL) }
)
}
composable(Routes.USAGE_DETAIL) {
UsageDetailScreen(
onBack = { navController.popBackStack() },
onOpenOverview = { navController.navigate(Routes.USAGE_OVERVIEW) },
onOpenData = { navController.navigate(Routes.USAGE_DATA) }
)
}
composable(Routes.USAGE_OVERVIEW) {
UsageOverviewScreen(
onBack = { navController.popBackStack() }
)
}
composable(Routes.USAGE_DATA) {
UsageDataScreen(
onBack = { navController.popBackStack() }
)
}
composable(Routes.SETTINGS) {
SettingsScreen(
onBack = { navController.popBackStack() },
onEditCredential = { type -> navController.navigate(Routes.credentialEdit(type)) }
)
}
composable(
route = Routes.CREDENTIAL_EDIT,
arguments = listOf(navArgument("type") { type = NavType.StringType })
) { backStackEntry ->
val type = parseServiceType(backStackEntry.arguments?.getString("type"))
CredentialEditScreen(
service = type,
onBack = { navController.popBackStack() },
onStartWebViewLogin = { service -> navController.navigate(Routes.webviewLogin(service)) },
onWebViewLoginSuccess = { /* 登录后回到编辑页,由 LaunchedEffect 触发刷新 */ }
)
}
composable(
route = Routes.WEBVIEW_LOGIN,
arguments = listOf(navArgument("type") { type = NavType.StringType })
) { backStackEntry ->
val type = parseServiceType(backStackEntry.arguments?.getString("type"))
WebViewLoginScreen(
service = type,
onBack = { navController.popBackStack() },
onLoginSucceeded = {
// 登录成功直接回退到 CredentialEdit 页
navController.popBackStack()
}
)
}
composable(
route = Routes.SERVICE_DETAIL,
arguments = listOf(navArgument("type") { type = NavType.StringType })
) { backStackEntry ->
val type = parseServiceType(backStackEntry.arguments?.getString("type"))
ServiceDetailScreen(
service = type,
onBack = { navController.popBackStack() },
onConfigureCredential = { svc -> navController.navigate(Routes.credentialEdit(svc)) },
onStartWebViewLogin = { svc -> navController.navigate(Routes.webviewLogin(svc)) }
)
}
}
}