* feat(#107): implement saved connection profiles support * fix(connect): fallback profiles resolution and stubbing in tests
This commit is contained in:
8 files changed
+479
-13
No files matched your search
@@ -26,6 +26,8 @@ object AuthManager {
|
||||
private const val KEY_BOTTOM_NAV_ITEMS = "bottom_nav_items"
|
||||
private const val KEY_TYPING_EFFECT_ENABLED = "typing_effect_enabled"
|
||||
private const val KEY_TYPING_EFFECT_DELAY_MS = "typing_effect_delay_ms"
|
||||
private const val KEY_CONNECTION_PROFILES = "connection_profiles"
|
||||
private const val KEY_SELECTED_PROFILE_ID = "selected_profile_id"
|
||||
|
||||
private const val DEFAULT_HOST = "127.0.0.1"
|
||||
private const val DEFAULT_PORT = 9119
|
||||
@@ -39,6 +41,8 @@ object AuthManager {
|
||||
private val _bottomNavItemsFlow = MutableStateFlow<List<String>>(emptyList())
|
||||
val bottomNavItemsFlow: StateFlow<List<String>> = _bottomNavItemsFlow.asStateFlow()
|
||||
|
||||
private val gson = com.google.gson.Gson()
|
||||
|
||||
/**
|
||||
* Initialise the encrypted preferences.
|
||||
* Call this once from Application.onCreate() or MainActivity.onCreate().
|
||||
@@ -71,28 +75,112 @@ object AuthManager {
|
||||
"AuthManager not initialised – call AuthManager.init(context) first",
|
||||
)
|
||||
|
||||
// ── Connection Profiles ──────────────────────────────────────────────
|
||||
|
||||
fun getConnectionProfiles(): List<com.m57.hermescontrol.data.model.ConnectionProfile> {
|
||||
val json = requirePrefs().getString(KEY_CONNECTION_PROFILES, null) ?: return emptyList()
|
||||
return try {
|
||||
val type =
|
||||
object : com.google.gson.reflect.TypeToken<
|
||||
List<com.m57.hermescontrol.data.model.ConnectionProfile>,
|
||||
>() {}.type
|
||||
gson.fromJson(json, type) ?: emptyList()
|
||||
} catch (e: Exception) {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
fun saveConnectionProfiles(profiles: List<com.m57.hermescontrol.data.model.ConnectionProfile>) {
|
||||
val json = gson.toJson(profiles)
|
||||
requirePrefs().edit().putString(KEY_CONNECTION_PROFILES, json).apply()
|
||||
}
|
||||
|
||||
fun getProfileToken(profileId: String): String? {
|
||||
return requirePrefs().getString("token_$profileId", null)
|
||||
}
|
||||
|
||||
fun setProfileToken(
|
||||
profileId: String,
|
||||
token: String?,
|
||||
) {
|
||||
requirePrefs().edit().putString("token_$profileId", token).apply()
|
||||
}
|
||||
|
||||
fun getSelectedProfileId(): String? {
|
||||
val id = requirePrefs().getString(KEY_SELECTED_PROFILE_ID, null)
|
||||
return if (id.isNullOrBlank()) null else id
|
||||
}
|
||||
|
||||
fun setSelectedProfileId(id: String?) {
|
||||
requirePrefs().edit().putString(KEY_SELECTED_PROFILE_ID, id).apply()
|
||||
}
|
||||
|
||||
// ── Token ────────────────────────────────────────────────────────────
|
||||
|
||||
fun getToken(): String? = requirePrefs().getString(KEY_TOKEN, null)
|
||||
fun getToken(): String? {
|
||||
val selectedId = getSelectedProfileId()
|
||||
if (selectedId != null) {
|
||||
val token = getProfileToken(selectedId)
|
||||
if (token != null) return token
|
||||
}
|
||||
return requirePrefs().getString(KEY_TOKEN, null)
|
||||
}
|
||||
|
||||
fun setToken(token: String?) {
|
||||
requirePrefs().edit().putString(KEY_TOKEN, token).apply()
|
||||
val selectedId = getSelectedProfileId()
|
||||
if (selectedId != null) {
|
||||
setProfileToken(selectedId, token)
|
||||
} else {
|
||||
requirePrefs().edit().putString(KEY_TOKEN, token).apply()
|
||||
}
|
||||
}
|
||||
|
||||
// ── Host ─────────────────────────────────────────────────────────────
|
||||
|
||||
fun getHost(): String = requirePrefs().getString(KEY_HOST, DEFAULT_HOST) ?: DEFAULT_HOST
|
||||
fun getHost(): String {
|
||||
val selectedId = getSelectedProfileId()
|
||||
if (selectedId != null) {
|
||||
val profile = getConnectionProfiles().firstOrNull { it.id == selectedId }
|
||||
if (profile != null) return profile.host
|
||||
}
|
||||
return requirePrefs().getString(KEY_HOST, DEFAULT_HOST) ?: DEFAULT_HOST
|
||||
}
|
||||
|
||||
fun setHost(host: String) {
|
||||
requirePrefs().edit().putString(KEY_HOST, host).apply()
|
||||
val selectedId = getSelectedProfileId()
|
||||
if (selectedId != null) {
|
||||
val profiles =
|
||||
getConnectionProfiles().map {
|
||||
if (it.id == selectedId) it.copy(host = host) else it
|
||||
}
|
||||
saveConnectionProfiles(profiles)
|
||||
} else {
|
||||
requirePrefs().edit().putString(KEY_HOST, host).apply()
|
||||
}
|
||||
}
|
||||
|
||||
// ── Port ─────────────────────────────────────────────────────────────
|
||||
|
||||
fun getPort(): Int = requirePrefs().getInt(KEY_PORT, DEFAULT_PORT)
|
||||
fun getPort(): Int {
|
||||
val selectedId = getSelectedProfileId()
|
||||
if (selectedId != null) {
|
||||
val profile = getConnectionProfiles().firstOrNull { it.id == selectedId }
|
||||
if (profile != null) return profile.port
|
||||
}
|
||||
return requirePrefs().getInt(KEY_PORT, DEFAULT_PORT)
|
||||
}
|
||||
|
||||
fun setPort(port: Int) {
|
||||
requirePrefs().edit().putInt(KEY_PORT, port).apply()
|
||||
val selectedId = getSelectedProfileId()
|
||||
if (selectedId != null) {
|
||||
val profiles =
|
||||
getConnectionProfiles().map {
|
||||
if (it.id == selectedId) it.copy(port = port) else it
|
||||
}
|
||||
saveConnectionProfiles(profiles)
|
||||
} else {
|
||||
requirePrefs().edit().putInt(KEY_PORT, port).apply()
|
||||
}
|
||||
}
|
||||
|
||||
// ── Auto-reconnect ───────────────────────────────────────────────────
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.m57.hermescontrol.data.model
|
||||
|
||||
import java.util.UUID
|
||||
|
||||
data class ConnectionProfile(
|
||||
val id: String = UUID.randomUUID().toString(),
|
||||
val name: String,
|
||||
val host: String,
|
||||
val port: Int,
|
||||
)
|
||||
Reference in new issue
Block a user