feat: Enhance PreferencesManager and SyncRepository for better server settings management and error handling
This commit is contained in:
+26
-2
@@ -18,9 +18,14 @@ class PreferencesManager(context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setServerUrl(url: String) {
|
fun setServerUrl(url: String) {
|
||||||
val cleanUrl = url.trim().let {
|
val raw = url.trim()
|
||||||
if (it.endsWith("/")) it else "$it/"
|
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()
|
prefs.edit().putString(KEY_SERVER_URL, cleanUrl).apply()
|
||||||
_serverUrl.value = cleanUrl
|
_serverUrl.value = cleanUrl
|
||||||
}
|
}
|
||||||
@@ -38,13 +43,32 @@ class PreferencesManager(context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setServerPassword(password: String) {
|
fun setServerPassword(password: String) {
|
||||||
|
if (password.isBlank()) {
|
||||||
|
prefs.edit().remove(KEY_SERVER_PASSWORD).apply()
|
||||||
|
} else {
|
||||||
prefs.edit().putString(KEY_SERVER_PASSWORD, password).apply()
|
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 {
|
companion object {
|
||||||
private const val KEY_SERVER_URL = "server_url"
|
private const val KEY_SERVER_URL = "server_url"
|
||||||
private const val KEY_FIRST_RUN = "first_run"
|
private const val KEY_FIRST_RUN = "first_run"
|
||||||
private const val KEY_SERVER_PASSWORD = "server_password"
|
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/"
|
private const val DEFAULT_SERVER_URL = "http://10.0.2.2:3000/api/"
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
|
|||||||
+6
@@ -121,6 +121,12 @@ class SyncRepository(context: Context) {
|
|||||||
|
|
||||||
return@withContext Result.success(Unit)
|
return@withContext Result.success(Unit)
|
||||||
} else {
|
} 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()}")
|
Logger.e("Sync", "[ERROR] Sync failed: HTTP ${response.code()}")
|
||||||
return@withContext Result.failure(Exception("Sync failed: ${response.code()}"))
|
return@withContext Result.failure(Exception("Sync failed: ${response.code()}"))
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -160,6 +160,8 @@ class ServerSetupViewModel(
|
|||||||
// Password is valid, save both URL and password
|
// Password is valid, save both URL and password
|
||||||
preferencesManager.setServerUrl(finalUrl)
|
preferencesManager.setServerUrl(finalUrl)
|
||||||
preferencesManager.setServerPassword(password)
|
preferencesManager.setServerPassword(password)
|
||||||
|
// Reset sync baseline for a fresh initial sync on new server
|
||||||
|
preferencesManager.clearSyncState()
|
||||||
preferencesManager.setIsFirstRun(false)
|
preferencesManager.setIsFirstRun(false)
|
||||||
ApiClient.setBaseUrl(finalUrl)
|
ApiClient.setBaseUrl(finalUrl)
|
||||||
_validationResult.value = true
|
_validationResult.value = true
|
||||||
|
|||||||
+7
-3
@@ -11,6 +11,7 @@ import androidx.compose.ui.res.stringResource
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.collabtable.app.R
|
import com.collabtable.app.R
|
||||||
import com.collabtable.app.data.database.CollabTableDatabase
|
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.preferences.PreferencesManager
|
||||||
import com.collabtable.app.data.repository.SyncRepository
|
import com.collabtable.app.data.repository.SyncRepository
|
||||||
import com.collabtable.app.utils.Logger
|
import com.collabtable.app.utils.Logger
|
||||||
@@ -174,10 +175,13 @@ fun SettingsScreen(
|
|||||||
CollabTableDatabase.clearDatabase(context)
|
CollabTableDatabase.clearDatabase(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear preferences
|
// Clear preferences (URL, password, last sync)
|
||||||
preferencesManager.setServerUrl("")
|
preferencesManager.clearServerSettings()
|
||||||
preferencesManager.setServerPassword("")
|
|
||||||
preferencesManager.setIsFirstRun(true)
|
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")
|
Logger.i("Settings", "Left server successfully")
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user