- Jetpack Compose + Material 3 仪表盘 - DeepSeek REST API 余额查询 - OpenCode Go WebView 抓取用量 - 3 张 Canvas 图表(消耗/请求/Token) - 原始记录分页浏览 - DataStore + 内存缓存 - 桌面小组件
116 lines
4.8 KiB
Kotlin
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)) }
|
|
)
|
|
}
|
|
}
|
|
} |