feat: Enhance PreferencesManager and SyncRepository for better server settings management and error handling

This commit is contained in:
2025-10-25 16:17:28 +02:00
parent 05f62e9f73
commit 22ec511ca7
5 changed files with 42 additions and 6 deletions
@@ -18,9 +18,14 @@ class PreferencesManager(context: Context) {
}
fun setServerUrl(url: String) {
val cleanUrl = url.trim().let {
if (it.endsWith("/")) it else "$it/"
val raw = url.trim()
if (raw.isBlank()) {
// Remove the key entirely to fall back to default URL on reads
prefs.edit().remove(KEY_SERVER_URL).apply()
_serverUrl.value = getServerUrl()
return
}
val cleanUrl = raw.let { if (it.endsWith("/")) it else "$it/" }
prefs.edit().putString(KEY_SERVER_URL, cleanUrl).apply()
_serverUrl.value = cleanUrl
}
@@ -38,13 +43,32 @@ class PreferencesManager(context: Context) {
}
fun setServerPassword(password: String) {
prefs.edit().putString(KEY_SERVER_PASSWORD, password).apply()
if (password.isBlank()) {
prefs.edit().remove(KEY_SERVER_PASSWORD).apply()
} else {
prefs.edit().putString(KEY_SERVER_PASSWORD, password).apply()
}
}
// Clear sync-related state so the next sync starts from scratch
fun clearSyncState() {
prefs.edit().remove(KEY_LAST_SYNC_TIMESTAMP).apply()
}
fun clearServerSettings() {
prefs.edit()
.remove(KEY_SERVER_URL)
.remove(KEY_SERVER_PASSWORD)
.remove(KEY_LAST_SYNC_TIMESTAMP)
.apply()
_serverUrl.value = getServerUrl()
}
companion object {
private const val KEY_SERVER_URL = "server_url"
private const val KEY_FIRST_RUN = "first_run"
private const val KEY_SERVER_PASSWORD = "server_password"
private const val KEY_LAST_SYNC_TIMESTAMP = "last_sync_timestamp"
private const val DEFAULT_SERVER_URL = "http://10.0.2.2:3000/api/"
@Volatile
@@ -121,6 +121,12 @@ class SyncRepository(context: Context) {
return@withContext Result.success(Unit)
} else {
if (response.code() == 401) {
// Unauthorized: likely bad/missing password. Reset sync baseline and surface a clear error.
Logger.e("Sync", "[ERROR] Unauthorized (401). Check server password in Settings.")
setLastSyncTimestamp(0)
return@withContext Result.failure(Exception("Unauthorized (401). Please verify server password."))
}
Logger.e("Sync", "[ERROR] Sync failed: HTTP ${response.code()}")
return@withContext Result.failure(Exception("Sync failed: ${response.code()}"))
}
@@ -160,6 +160,8 @@ class ServerSetupViewModel(
// Password is valid, save both URL and password
preferencesManager.setServerUrl(finalUrl)
preferencesManager.setServerPassword(password)
// Reset sync baseline for a fresh initial sync on new server
preferencesManager.clearSyncState()
preferencesManager.setIsFirstRun(false)
ApiClient.setBaseUrl(finalUrl)
_validationResult.value = true
@@ -11,6 +11,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.collabtable.app.R
import com.collabtable.app.data.database.CollabTableDatabase
import com.collabtable.app.data.api.ApiClient
import com.collabtable.app.data.preferences.PreferencesManager
import com.collabtable.app.data.repository.SyncRepository
import com.collabtable.app.utils.Logger
@@ -174,10 +175,13 @@ fun SettingsScreen(
CollabTableDatabase.clearDatabase(context)
}
// Clear preferences
preferencesManager.setServerUrl("")
preferencesManager.setServerPassword("")
// Clear preferences (URL, password, last sync)
preferencesManager.clearServerSettings()
preferencesManager.setIsFirstRun(true)
// Clear in-memory logs as part of local data
Logger.clear()
// Reset API client base URL to current preference (default)
ApiClient.setBaseUrl(preferencesManager.getServerUrl())
Logger.i("Settings", "Left server successfully")