From 8f24f17da87201bf616b7b5ab6b36703ed502fe6 Mon Sep 17 00:00:00 2001 From: Remy Chantenay Date: Thu, 12 Oct 2023 08:36:33 +0200 Subject: [PATCH 1/2] Add label name length validation upon creation --- .../ui/components/LabelsSelectionSheet.kt | 29 +++++++++++---- .../omnivore/ui/components/LabelsViewModel.kt | 37 ++++++++++--------- .../app/src/main/res/values/strings.xml | 1 + 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt index 0461149a7..7022e28f8 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt @@ -3,6 +3,7 @@ package app.omnivore.omnivore.ui.components import LabelChip +import android.widget.Toast import androidx.compose.foundation.* import androidx.compose.foundation.interaction.FocusInteraction import androidx.compose.foundation.interaction.MutableInteractionSource @@ -341,19 +342,33 @@ fun LabelsSelectionSheetContent( ) if (!isLibraryMode && filterTextValue.text.isNotEmpty() && currentLabel == null) { + val context = LocalContext.current Row( horizontalArrangement = Arrangement.Start, verticalAlignment = Alignment.CenterVertically, modifier = Modifier .fillMaxWidth() .clickable { - val label = findOrCreateLabel( - labelsViewModel = labelsViewModel, - labels = labels, - name = filterTextValue - ) - state.addChip(LabelChipView(label)) - filterTextValue = TextFieldValue() + when(labelsViewModel.validateLabelName(filterTextValue.text)) { + LabelsViewModel.Error.LabelNameTooLong -> { + Toast.makeText( + context, + context.getString(R.string.label_selection_sheet_label_too_long_error_msg, + labelsViewModel.labelNameMaxLength), + Toast.LENGTH_SHORT + ).show() + } + null -> { + val label = findOrCreateLabel( + labelsViewModel = labelsViewModel, + labels = labels, + name = filterTextValue + ) + + state.addChip(LabelChipView(label)) + filterTextValue = TextFieldValue() + } + } } .padding(horizontal = 10.dp) .padding(top = 10.dp, bottom = 5.dp) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsViewModel.kt index f75959f70..7b26a05df 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsViewModel.kt @@ -1,34 +1,16 @@ package app.omnivore.omnivore.ui.components - -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context -import android.content.Intent -import android.net.Uri import android.util.Log -import android.widget.Toast -import androidx.compose.ui.platform.LocalContext -import androidx.core.content.ContextCompat.startActivity import androidx.lifecycle.* -import app.omnivore.omnivore.DatastoreKeys import app.omnivore.omnivore.DatastoreRepository import app.omnivore.omnivore.dataService.* import app.omnivore.omnivore.graphql.generated.type.CreateLabelInput -import app.omnivore.omnivore.graphql.generated.type.SetLabelsInput import app.omnivore.omnivore.models.ServerSyncStatus import app.omnivore.omnivore.networking.* -import app.omnivore.omnivore.persistence.entities.SavedItem -import app.omnivore.omnivore.persistence.entities.SavedItemAndSavedItemLabelCrossRef import app.omnivore.omnivore.persistence.entities.SavedItemLabel -import app.omnivore.omnivore.ui.components.LabelSwatchHelper -import app.omnivore.omnivore.ui.library.SavedItemAction import com.apollographql.apollo3.api.Optional.Companion.presentIfNotNull -import com.google.gson.Gson import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.* -import kotlinx.coroutines.flow.distinctUntilChanged -import java.time.Instant import java.time.LocalDate import java.time.ZoneOffset import java.time.format.DateTimeFormatter @@ -42,6 +24,25 @@ class LabelsViewModel @Inject constructor( private val dataService: DataService, private val networker: Networker ): ViewModel() { + val labelNameMaxLength = 64 + + enum class Error { + LabelNameTooLong + } + + /** + * Checks whether or not the provided label name is valid. + * @param labelName The name of the label. + * @return null if valid, [Error] otherwise. + */ + fun validateLabelName(labelName: String): Error? { + val trimmedName = labelName.trim() + if (trimmedName.count() > labelNameMaxLength) { + return Error.LabelNameTooLong + } + + return null + } fun createNewSavedItemLabelWithTemp(labelName: String, hexColorValue: String): SavedItemLabel { val tempId = UUID.randomUUID().toString() diff --git a/android/Omnivore/app/src/main/res/values/strings.xml b/android/Omnivore/app/src/main/res/values/strings.xml index ad7f2a3ea..2867be8e3 100644 --- a/android/Omnivore/app/src/main/res/values/strings.xml +++ b/android/Omnivore/app/src/main/res/values/strings.xml @@ -103,6 +103,7 @@ Search Save Create a new label named \"%1$s\" + The name provided is too long (must be less or equal than %1$d characters) Labels From 668485ba15b75b04a76b34942e707b5bcd31d881 Mon Sep 17 00:00:00 2001 From: Remy Chantenay Date: Sat, 14 Oct 2023 12:57:35 +0200 Subject: [PATCH 2/2] Trim labelname upon creation --- .../ui/components/LabelsSelectionSheet.kt | 15 ++++++++------- .../omnivore/ui/components/LabelsViewModel.kt | 3 +-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt index 7022e28f8..7dc98a9f7 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt @@ -220,12 +220,12 @@ class LabelChipView(label: SavedItemLabel) : Chip(label.name) { val label = label } -fun findOrCreateLabel(labelsViewModel: LabelsViewModel, labels: List, name: TextFieldValue): SavedItemLabel { - val found = labels.find { it.name == name.text } +fun findOrCreateLabel(labelsViewModel: LabelsViewModel, labels: List, name: String): SavedItemLabel { + val found = labels.find { it.name == name } if (found != null) { return found } - return labelsViewModel.createNewSavedItemLabelWithTemp(name.text, LabelSwatchHelper.random()) + return labelsViewModel.createNewSavedItemLabelWithTemp(name, LabelSwatchHelper.random()) } @Composable @@ -309,7 +309,7 @@ fun LabelsSelectionSheetContent( LabelChipView(it) } ?: null } else { - LabelChipView(findOrCreateLabel(labelsViewModel = labelsViewModel, labels = labels, name = it)) + LabelChipView(findOrCreateLabel(labelsViewModel = labelsViewModel, labels = labels, name = it.text)) } }, chipLeadingIcon = { chip -> CircleIcon(colorHex = chip.label.color) }, @@ -349,7 +349,8 @@ fun LabelsSelectionSheetContent( modifier = Modifier .fillMaxWidth() .clickable { - when(labelsViewModel.validateLabelName(filterTextValue.text)) { + val labelName = filterTextValue.text.trim() + when(labelsViewModel.validateLabelName(labelName)) { LabelsViewModel.Error.LabelNameTooLong -> { Toast.makeText( context, @@ -362,7 +363,7 @@ fun LabelsSelectionSheetContent( val label = findOrCreateLabel( labelsViewModel = labelsViewModel, labels = labels, - name = filterTextValue + name = labelName ) state.addChip(LabelChipView(label)) @@ -379,7 +380,7 @@ fun LabelsSelectionSheetContent( contentDescription = null, modifier = Modifier.padding(end = 8.dp) ) - Text(text = stringResource(R.string.label_selection_sheet_text_create, filterTextValue.text)) + Text(text = stringResource(R.string.label_selection_sheet_text_create, filterTextValue.text.trim())) } } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsViewModel.kt index 7b26a05df..ddcdaf07b 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsViewModel.kt @@ -36,8 +36,7 @@ class LabelsViewModel @Inject constructor( * @return null if valid, [Error] otherwise. */ fun validateLabelName(labelName: String): Error? { - val trimmedName = labelName.trim() - if (trimmedName.count() > labelNameMaxLength) { + if (labelName.count() > labelNameMaxLength) { return Error.LabelNameTooLong }