Web: - 看板四列可拖拽,非法流转当场说明原因;勾选后可批量移动 - 详情侧栏全部可编辑(标题/优先级/截止/标签/备注/评论),409 自动刷新 - 快速录入 #标签 !优先级;键盘流 j/k、Enter、e、Esc - Playwright 真浏览器 e2e 7 项断言全绿(web/e2e/smoke.mjs) - 1000 条任务实测首屏 P50 38-55ms Android(未编译验证:本机无 JDK/Gradle): - 任务列表/详情/勾选完成/快速新建,冲突时提示并刷新 - 修:User/Member 字段名与后端 nickmame/phone 对齐,原先必然反序列化失败
85 lines
2.7 KiB
Kotlin
85 lines
2.7 KiB
Kotlin
package com.dadao.task
|
|
|
|
import android.os.Bundle
|
|
import androidx.activity.ComponentActivity
|
|
import androidx.activity.compose.setContent
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.Surface
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.runtime.mutableStateOf
|
|
import androidx.compose.runtime.remember
|
|
import androidx.compose.runtime.setValue
|
|
import androidx.compose.ui.Modifier
|
|
import com.dadao.task.data.Api
|
|
import com.dadao.task.data.TokenStore
|
|
import com.dadao.task.data.Workspace
|
|
import com.dadao.task.ui.DadaoTheme
|
|
import com.dadao.task.ui.HomeScreen
|
|
import com.dadao.task.ui.LoginScreen
|
|
import com.dadao.task.ui.TaskListScreen
|
|
|
|
class MainActivity : ComponentActivity() {
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
setContent {
|
|
DadaoTheme {
|
|
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
|
|
AppRoot()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private enum class Screen { Splash, Login, Home, Tasks }
|
|
|
|
@Composable
|
|
private fun AppRoot() {
|
|
val context = androidx.compose.ui.platform.LocalContext.current
|
|
val tokens = remember { TokenStore(context) }
|
|
val api = remember { Api(tokens) }
|
|
var screen by remember { mutableStateOf(if (tokens.isLoggedIn) Screen.Splash else Screen.Login) }
|
|
var current by remember { mutableStateOf<Workspace?>(null) }
|
|
|
|
// 有本地令牌就先静默校验一次:令牌过期/被吊销要退回登录页,而不是进了主页再崩。
|
|
LaunchedEffect(screen) {
|
|
if (screen == Screen.Splash) {
|
|
screen = try {
|
|
api.me()
|
|
Screen.Home
|
|
} catch (e: Exception) {
|
|
tokens.clear()
|
|
Screen.Login
|
|
}
|
|
}
|
|
}
|
|
|
|
when (screen) {
|
|
Screen.Splash -> Unit // 校验中,空白过渡即可
|
|
Screen.Login -> LoginScreen(api = api, onLoggedIn = { screen = Screen.Home })
|
|
Screen.Home -> HomeScreen(
|
|
api = api,
|
|
onLogout = {
|
|
tokens.clear()
|
|
screen = Screen.Login
|
|
},
|
|
onOpenWorkspace = { ws ->
|
|
current = ws
|
|
screen = Screen.Tasks
|
|
},
|
|
)
|
|
Screen.Tasks -> {
|
|
val ws = current
|
|
if (ws == null) {
|
|
screen = Screen.Home
|
|
} else {
|
|
TaskListScreen(api = api, workspace = ws, onBack = { screen = Screen.Home })
|
|
}
|
|
}
|
|
}
|
|
}
|