feat(ui): brouillon enregistrement carnet local prioritaire

EBO <eric.bouhana@softalys.com> committé le 2026-07-22 15:51

7c82759e6b2655759517b59f6a7e44ca93ceb569

1 parent(s)

5 fichiers modifiés +52 -41
M android/app/src/main/java/fr/ebii/card2vcf/ui/ContactDraftScreen.kt
+27 -38
@@ -5,7 +5,6 @@ import androidx.compose.foundation.border
5 5 import androidx.compose.foundation.layout.Arrangement
6 6 import androidx.compose.foundation.layout.Box
7 7 import androidx.compose.foundation.layout.Column
8 -import androidx.compose.foundation.layout.Row
9 8 import androidx.compose.foundation.layout.fillMaxSize
10 9 import androidx.compose.foundation.layout.fillMaxWidth
11 10 import androidx.compose.foundation.layout.padding
@@ -39,14 +38,13 @@ private val Square = RoundedCornerShape(0.dp)
39 38 fun ContactDraftScreen(
40 39 draft: ContactDraftUi,
41 40 onCardChange: (fr.ebii.card2vcf.contact.ContactCard) -> Unit,
41 + onSaveToCarnet: () -> Unit,
42 42 onCreateContact: () -> Unit,
43 43 onExportVcf: () -> Unit,
44 44 onRetry: () -> Unit,
45 45 modifier: Modifier = Modifier,
46 - /** Mode rescan : bouton primary « Mettre à jour ». */
47 - onUpdateContact: (() -> Unit)? = null,
46 + isEditing: Boolean = false,
48 47 ) {
49 - val isUpdate = onUpdateContact != null
50 48 Column(
51 49 modifier.fillMaxSize().background(Fond).padding(horizontal = 18.dp, vertical = 16.dp),
52 50 verticalArrangement = Arrangement.spacedBy(14.dp),
@@ -66,40 +64,31 @@ fun ContactDraftScreen(
66 64 Text(draft.rawOcrText, fontFamily = FontFamily.Monospace, color = TexteFaible)
67 65 }
68 66 }
69 - if (isUpdate) {
70 - Button(
71 - onClick = onUpdateContact,
72 - modifier = Modifier.fillMaxWidth(),
73 - shape = Square,
74 - colors = ButtonDefaults.buttonColors(containerColor = Ink, contentColor = OnPrimary),
75 - ) {
76 - Text(stringResource(R.string.edit_mettre_a_jour))
77 - }
78 - OutlinedButton(
79 - onClick = onExportVcf,
80 - modifier = Modifier.fillMaxWidth(),
81 - shape = Square,
82 - ) {
83 - Text(stringResource(R.string.scan_exporter_vcf))
84 - }
85 - } else {
86 - Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(10.dp)) {
87 - Button(
88 - onClick = onCreateContact,
89 - modifier = Modifier.weight(1f),
90 - shape = Square,
91 - colors = ButtonDefaults.buttonColors(containerColor = Ink, contentColor = OnPrimary),
92 - ) {
93 - Text(stringResource(R.string.scan_creer_contact))
94 - }
95 - OutlinedButton(
96 - onClick = onExportVcf,
97 - modifier = Modifier.weight(1f),
98 - shape = Square,
99 - ) {
100 - Text(stringResource(R.string.scan_exporter_vcf))
101 - }
102 - }
67 + Button(
68 + onClick = onSaveToCarnet,
69 + modifier = Modifier.fillMaxWidth(),
70 + shape = Square,
71 + colors = ButtonDefaults.buttonColors(containerColor = Ink, contentColor = OnPrimary),
72 + ) {
73 + Text(
74 + stringResource(
75 + if (isEditing) R.string.edit_mettre_a_jour else R.string.scan_enregistrer_carnet,
76 + ),
77 + )
78 + }
79 + OutlinedButton(
80 + onClick = onCreateContact,
81 + modifier = Modifier.fillMaxWidth(),
82 + shape = Square,
83 + ) {
84 + Text(stringResource(R.string.scan_creer_contact))
85 + }
86 + OutlinedButton(
87 + onClick = onExportVcf,
88 + modifier = Modifier.fillMaxWidth(),
89 + shape = Square,
90 + ) {
91 + Text(stringResource(R.string.scan_exporter_vcf))
103 92 }
104 93 OutlinedButton(
105 94 onClick = onRetry,
M android/app/src/main/java/fr/ebii/card2vcf/ui/ScanCarteScreen.kt
+2 -1
@@ -70,10 +70,11 @@ fun ScanCarteScreen(
70 70 is ScanUiState.DraftReady -> ContactDraftScreen(
71 71 draft = s.draft,
72 72 onCardChange = viewModel::updateDraft,
73 + onSaveToCarnet = viewModel::saveToCarnet,
73 74 onCreateContact = { onCreateContact(s.draft.card) },
74 75 onExportVcf = { onExportVcf(s.draft.card) },
75 76 onRetry = viewModel::reset,
76 - onUpdateContact = if (viewModel.isEditing) viewModel::updateFromDraft else null,
77 + isEditing = viewModel.isEditing,
77 78 modifier = modifier,
78 79 )
79 80 ScanUiState.Scanning -> ScanProgress(R.string.scan_en_cours)
M android/app/src/main/java/fr/ebii/card2vcf/ui/ScanCarteViewModel.kt
+19 -0
@@ -101,6 +101,25 @@ class ScanCarteViewModel(
101 101 }
102 102 }
103 103
104 + /** Enregistre le brouillon dans le carnet local (nouveau contact). Retourne l'id via [saveDoneId]. */
105 + fun saveToCarnet() {
106 + if (editingContactId != null) {
107 + updateFromDraft()
108 + return
109 + }
110 + val draft = (_state.value as? ScanUiState.DraftReady)?.draft ?: return
111 + viewModelScope.launch {
112 + val id = withContext(Dispatchers.IO) {
113 + repository.insertFromCard(
114 + card = draft.card,
115 + cardBitmap = draft.preview,
116 + profileBitmap = null,
117 + )
118 + }
119 + _saveDoneId.value = id
120 + }
121 + }
122 +
104 123 /** Met à jour le contact existant (mode rescan) à partir du brouillon courant. */
105 124 fun updateFromDraft() {
106 125 val editId = editingContactId ?: return
M android/app/src/main/res/values-en/strings.xml
+2 -1
@@ -10,7 +10,8 @@
10 10 <string name="scan_ocr_en_cours">Recognizing text…</string>
11 11 <string name="scan_structuration">Analyzing contact…</string>
12 12 <string name="scan_brouillon_titre">Review contact</string>
13 - <string name="scan_brouillon_sous_titre">Edit fields before creating the contact or exporting VCF.</string>
13 + <string name="scan_brouillon_sous_titre">Edit fields, save to the address book, or export to Contacts / VCF.</string>
14 + <string name="scan_enregistrer_carnet">Save</string>
14 15 <string name="scan_ocr_brut">Raw OCR text</string>
15 16 <string name="scan_creer_contact">Create contact</string>
16 17 <string name="scan_exporter_vcf">Export VCF</string>
M android/app/src/main/res/values/strings.xml
+2 -1
@@ -10,7 +10,8 @@
10 10 <string name="scan_ocr_en_cours">Reconnaissance du texte…</string>
11 11 <string name="scan_structuration">Analyse du contact…</string>
12 12 <string name="scan_brouillon_titre">Vérifier le contact</string>
13 - <string name="scan_brouillon_sous_titre">Corrigez les champs avant de créer le contact ou d\'exporter le VCF.</string>
13 + <string name="scan_brouillon_sous_titre">Corrigez les champs, enregistrez dans le carnet, ou exportez vers Contacts / VCF.</string>
14 + <string name="scan_enregistrer_carnet">Enregistrer</string>
14 15 <string name="scan_ocr_brut">Texte OCR brut</string>
15 16 <string name="scan_creer_contact">Créer le contact</string>
16 17 <string name="scan_exporter_vcf">Exporter VCF</string>