feat: sauvegarde du compte CalDAV même si la connexion échoue, avec indicateur visuel
This commit is contained in:
@@ -15,6 +15,7 @@ import androidx.compose.material.icons.outlined.Add
|
||||
import androidx.compose.material.icons.outlined.Delete
|
||||
import androidx.compose.material.icons.outlined.Download
|
||||
import androidx.compose.material.icons.outlined.Sync
|
||||
import androidx.compose.material.icons.outlined.Warning
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
@@ -23,6 +24,7 @@ import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.SegmentedButton
|
||||
@@ -185,9 +187,10 @@ fun SettingsScreen(
|
||||
}
|
||||
discovery.second?.let { error ->
|
||||
Text(
|
||||
text = error,
|
||||
text = "Connexion échouée — le compte a été ajouté sans synchronisation : $error",
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -240,10 +243,28 @@ private fun SectionTitle(text: String) {
|
||||
|
||||
@Composable
|
||||
private fun CalDavSourceRow(source: Source, onDelete: () -> Unit) {
|
||||
val connectionFailed = source.caldavData?.calendarHomeUrl == null
|
||||
ListItem(
|
||||
leadingContent = { Icon(Icons.Outlined.AccountCircle, contentDescription = null) },
|
||||
leadingContent = {
|
||||
if (connectionFailed) {
|
||||
Icon(Icons.Outlined.Warning, contentDescription = "Connexion échouée", tint = MaterialTheme.colorScheme.error)
|
||||
} else {
|
||||
Icon(Icons.Outlined.AccountCircle, contentDescription = null)
|
||||
}
|
||||
},
|
||||
headlineContent = { Text(source.displayName) },
|
||||
supportingContent = { Text(source.caldavData?.serverUrl ?: "") },
|
||||
supportingContent = {
|
||||
Column {
|
||||
Text(source.caldavData?.serverUrl ?: "")
|
||||
if (connectionFailed) {
|
||||
Text(
|
||||
text = "Non connecté",
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
trailingContent = {
|
||||
IconButton(onClick = onDelete) {
|
||||
Icon(Icons.Outlined.Delete, contentDescription = "Supprimer", tint = MaterialTheme.colorScheme.error)
|
||||
|
||||
@@ -11,6 +11,8 @@ import com.planify.mobile.data.preferences.AppPreferences
|
||||
import com.planify.mobile.data.preferences.ThemeMode
|
||||
import com.planify.mobile.data.sync.SyncScheduler
|
||||
import com.planify.mobile.domain.model.Source
|
||||
import com.planify.mobile.domain.model.SourceCalDavData
|
||||
import com.planify.mobile.domain.model.SourceType
|
||||
import com.planify.mobile.domain.repository.ProjectRepository
|
||||
import com.planify.mobile.domain.repository.SourceRepository
|
||||
import com.planify.mobile.domain.repository.TaskRepository
|
||||
@@ -23,6 +25,9 @@ import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
data class SettingsUiState(
|
||||
@@ -98,6 +103,23 @@ class SettingsViewModel @Inject constructor(
|
||||
if (uiState.value.syncEnabled) syncScheduler.schedule()
|
||||
}
|
||||
is DiscoveryResult.Failure -> {
|
||||
// Save the account anyway so the user keeps their credentials
|
||||
val now = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
|
||||
val sourceId = UUID.randomUUID().toString()
|
||||
val fallback = Source(
|
||||
id = sourceId,
|
||||
type = SourceType.CALDAV,
|
||||
displayName = username,
|
||||
addedAt = now,
|
||||
updatedAt = now,
|
||||
caldavData = SourceCalDavData(
|
||||
serverUrl = baseUrl,
|
||||
username = username,
|
||||
calendarHomeUrl = null,
|
||||
),
|
||||
)
|
||||
credentialStore.savePassword(sourceId, password)
|
||||
sourceRepository.insertSource(fallback)
|
||||
_discoveryState.update { false to result.message }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user