diff --git a/android/app/src/main/java/com/tiangong/aiagent/ui/settings/SettingsScreen.kt b/android/app/src/main/java/com/tiangong/aiagent/ui/settings/SettingsScreen.kt index fa75598..cee6286 100644 --- a/android/app/src/main/java/com/tiangong/aiagent/ui/settings/SettingsScreen.kt +++ b/android/app/src/main/java/com/tiangong/aiagent/ui/settings/SettingsScreen.kt @@ -23,6 +23,7 @@ import com.tiangong.aiagent.data.local.TokenDataStore import com.tiangong.aiagent.data.remote.ApiService import com.tiangong.aiagent.data.remote.DynamicUrlInterceptor import com.tiangong.aiagent.data.repository.AuthRepository +import com.tiangong.aiagent.util.AppUpdateManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted @@ -37,12 +38,16 @@ class SettingsViewModel @Inject constructor( private val authRepository: AuthRepository, private val tokenDataStore: TokenDataStore, private val dynamicUrlInterceptor: DynamicUrlInterceptor, - private val apiService: ApiService + private val apiService: ApiService, + private val appUpdateManager: AppUpdateManager ) : ViewModel() { private val _username = MutableStateFlow("admin") val username: StateFlow = _username.asStateFlow() + private val _updateMessage = MutableStateFlow(null) + val updateMessage: StateFlow = _updateMessage.asStateFlow() + val ttsEnabled: StateFlow = tokenDataStore.ttsEnabled .stateIn(viewModelScope, SharingStarted.Eagerly, false) @@ -80,6 +85,23 @@ class SettingsViewModel @Inject constructor( val notificationQuietEnd: StateFlow = tokenDataStore.notificationQuietEnd .stateIn(viewModelScope, SharingStarted.Eagerly, "07:00") + fun checkUpdate() { + _updateMessage.value = "正在检查..." + appUpdateManager.checkForUpdate { response -> + _updateMessage.value = if (response.hasUpdate) { + "发现新版本 ${response.latestVersion}" + } else if (response.releaseNotes.isNotBlank()) { + response.releaseNotes // error message + } else { + "已是最新版本 (${response.currentVersion})" + } + } + } + + fun clearUpdateMessage() { + _updateMessage.value = null + } + fun logout() { viewModelScope.launch { authRepository.logout() @@ -380,7 +402,7 @@ fun SettingsScreen( ListItem( headlineContent = { Text("天工智能体") }, - supportingContent = { Text("版本 1.0.0") }, + supportingContent = { Text("版本 ${BuildConfig.VERSION_NAME}") }, leadingContent = { Icon(Icons.Default.Info, contentDescription = null) }, @@ -389,6 +411,18 @@ fun SettingsScreen( } else Modifier ) + HorizontalDivider(modifier = Modifier.padding(horizontal = 16.dp)) + + val updateMessage by viewModel.updateMessage.collectAsState() + ListItem( + headlineContent = { Text("检查更新") }, + supportingContent = { Text(updateMessage ?: "点击检查新版本") }, + leadingContent = { + Icon(Icons.Default.Update, contentDescription = null) + }, + modifier = Modifier.clickable { viewModel.checkUpdate() } + ) + Spacer(modifier = Modifier.height(32.dp)) // Logout button diff --git a/android/app/src/main/java/com/tiangong/aiagent/util/AppUpdateManager.kt b/android/app/src/main/java/com/tiangong/aiagent/util/AppUpdateManager.kt index f8cdb71..825c16d 100644 --- a/android/app/src/main/java/com/tiangong/aiagent/util/AppUpdateManager.kt +++ b/android/app/src/main/java/com/tiangong/aiagent/util/AppUpdateManager.kt @@ -23,20 +23,29 @@ class AppUpdateManager @Inject constructor( * Check for app update asynchronously. If update is found, shows a dialog. * Called from MainActivity.onCreate(). */ - fun checkForUpdate() { + fun checkForUpdate(onResult: ((AppVersionResponse) -> Unit)? = null) { CoroutineScope(Dispatchers.IO).launch { try { val response = apiService.checkUpdate( platform = "android", version = BuildConfig.VERSION_NAME ) - if (response.hasUpdate) { - withContext(Dispatchers.Main) { + withContext(Dispatchers.Main) { + if (response.hasUpdate) { showUpdateDialog(response) } + onResult?.invoke(response) + } + } catch (e: Exception) { + withContext(Dispatchers.Main) { + onResult?.invoke( + AppVersionResponse( + latestVersion = "", currentVersion = BuildConfig.VERSION_NAME, + hasUpdate = false, forceUpdate = false, + releaseNotes = "检查失败: ${e.message}" + ) + ) } - } catch (_: Exception) { - // Silently ignore — update check is non-critical } } }