feat: add manual 'Check Update' button in Settings > About section

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 22:30:25 +08:00
parent 029abaa60c
commit 92ae0b5e46
2 changed files with 50 additions and 7 deletions

View File

@@ -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<String> = _username.asStateFlow()
private val _updateMessage = MutableStateFlow<String?>(null)
val updateMessage: StateFlow<String?> = _updateMessage.asStateFlow()
val ttsEnabled: StateFlow<Boolean> = tokenDataStore.ttsEnabled
.stateIn(viewModelScope, SharingStarted.Eagerly, false)
@@ -80,6 +85,23 @@ class SettingsViewModel @Inject constructor(
val notificationQuietEnd: StateFlow<String> = 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

View File

@@ -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
}
}
}