Fix license list loading and crash on duplicate subs.
Read admin token from DataStore before API calls, reload licenses after save, and use unique product key as LazyColumn item key. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,12 +4,11 @@ import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.flow.update
|
||||
import ru.mailib.ttrpg.licensemanager.data.AppSettings
|
||||
import ru.mailib.ttrpg.licensemanager.data.CreateProductKeyRequest
|
||||
import ru.mailib.ttrpg.licensemanager.data.LicenseEntry
|
||||
@@ -45,8 +44,7 @@ class LicenseViewModel(application: Application) : AndroidViewModel(application)
|
||||
private val settingsRepository = SettingsRepository(application)
|
||||
private val licenseRepository = LicenseRepository(settingsRepository)
|
||||
|
||||
val settings: StateFlow<AppSettings> = settingsRepository.settings
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), AppSettings())
|
||||
private suspend fun currentSettings(): AppSettings = settingsRepository.settings.first()
|
||||
|
||||
private val _listState = MutableStateFlow(LicenseListUiState())
|
||||
val listState: StateFlow<LicenseListUiState> = _listState.asStateFlow()
|
||||
@@ -59,17 +57,14 @@ class LicenseViewModel(application: Application) : AndroidViewModel(application)
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
settings.collect { appSettings ->
|
||||
_settingsState.update {
|
||||
it.copy(adminToken = appSettings.adminToken)
|
||||
}
|
||||
}
|
||||
val initial = settingsRepository.settings.first()
|
||||
_settingsState.update { it.copy(adminToken = initial.adminToken) }
|
||||
}
|
||||
}
|
||||
|
||||
fun loadLicenses() {
|
||||
viewModelScope.launch {
|
||||
val currentSettings = settings.value
|
||||
val currentSettings = currentSettings()
|
||||
_listState.update { it.copy(isLoading = true, error = null) }
|
||||
licenseRepository.listLicenses(currentSettings)
|
||||
.onSuccess { licenses ->
|
||||
@@ -84,7 +79,7 @@ class LicenseViewModel(application: Application) : AndroidViewModel(application)
|
||||
fun revokeLicense(sub: String) {
|
||||
viewModelScope.launch {
|
||||
_listState.update { it.copy(revokingSub = sub, error = null) }
|
||||
licenseRepository.revokeLicense(settings.value, sub)
|
||||
licenseRepository.revokeLicense(currentSettings(), sub)
|
||||
.onSuccess {
|
||||
loadLicenses()
|
||||
_listState.update { it.copy(revokingSub = null) }
|
||||
@@ -136,7 +131,7 @@ class LicenseViewModel(application: Application) : AndroidViewModel(application)
|
||||
viewModelScope.launch {
|
||||
_generateState.update { it.copy(isSubmitting = true, error = null, createdKey = null) }
|
||||
licenseRepository.createProductKey(
|
||||
settings.value,
|
||||
currentSettings(),
|
||||
CreateProductKeyRequest(
|
||||
pid = state.pid.trim(),
|
||||
maxDevices = maxDevices,
|
||||
@@ -161,11 +156,13 @@ class LicenseViewModel(application: Application) : AndroidViewModel(application)
|
||||
}
|
||||
}
|
||||
|
||||
fun saveSettings() {
|
||||
fun saveSettings(onSaved: () -> Unit = {}) {
|
||||
val draft = _settingsState.value
|
||||
viewModelScope.launch {
|
||||
settingsRepository.save(draft.adminToken)
|
||||
_settingsState.update { it.copy(savedMessage = "Сохранено") }
|
||||
loadLicenses()
|
||||
onSaved()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ fun LicenseListScreen(viewModel: LicenseViewModel) {
|
||||
ErrorMessage(message = state.error ?: "")
|
||||
}
|
||||
}
|
||||
items(state.licenses, key = { it.sub }) { license ->
|
||||
items(state.licenses, key = { it.key }) { license ->
|
||||
LicenseCard(
|
||||
license = license,
|
||||
isRevoking = state.revokingSub == license.sub,
|
||||
|
||||
@@ -64,10 +64,7 @@ fun SettingsScreen(viewModel: LicenseViewModel, onBack: () -> Unit) {
|
||||
}
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
viewModel.saveSettings()
|
||||
onBack()
|
||||
},
|
||||
onClick = { viewModel.saveSettings(onSaved = onBack) },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text("Сохранить")
|
||||
|
||||
Reference in New Issue
Block a user