diff --git a/android/app/src/main/java/com/fabledsword/inkwell/ui/BoardViewModel.kt b/android/app/src/main/java/com/fabledsword/inkwell/ui/BoardViewModel.kt index 8cf5817..59887db 100644 --- a/android/app/src/main/java/com/fabledsword/inkwell/ui/BoardViewModel.kt +++ b/android/app/src/main/java/com/fabledsword/inkwell/ui/BoardViewModel.kt @@ -505,8 +505,7 @@ class BoardViewModel( action.name.trim().takeIf { it.isNotEmpty() }?.let { name -> mutate { val label = it.createLabel(name) - val manual = note.labels.filterNot { l -> l.viaTag }.map { l -> l.id } - it.setNoteLabels(id, (manual + label.id).distinct()) + it.setNoteLabels(id, (note.manualLabelIds + label.id).distinct()) } // The drawer lists labels with their note counts, and both // just changed. diff --git a/android/app/src/main/java/com/fabledsword/inkwell/ui/EditorChrome.kt b/android/app/src/main/java/com/fabledsword/inkwell/ui/EditorChrome.kt index 000e247..104e60f 100644 --- a/android/app/src/main/java/com/fabledsword/inkwell/ui/EditorChrome.kt +++ b/android/app/src/main/java/com/fabledsword/inkwell/ui/EditorChrome.kt @@ -361,10 +361,7 @@ fun EditorLabelRow( // Only the MANUAL labels are sent: the core replaces // exactly those, and including a tag label here would ask // it to own something the body text already owns. - val kept = - note.labels - .filterNot { it.viaTag || it.id == label.id } - .map { it.id } + val kept = note.manualLabelIds - label.id onAction(EditorAction.SetLabels(kept)) }) { Icon( diff --git a/android/app/src/main/java/com/fabledsword/inkwell/ui/EditorPickers.kt b/android/app/src/main/java/com/fabledsword/inkwell/ui/EditorPickers.kt index 25826cd..68009c3 100644 --- a/android/app/src/main/java/com/fabledsword/inkwell/ui/EditorPickers.kt +++ b/android/app/src/main/java/com/fabledsword/inkwell/ui/EditorPickers.kt @@ -76,11 +76,7 @@ fun LabelSheet( onDismiss: () -> Unit, ) { var typed by remember { mutableStateOf("") } - val manual = - note.labels - .filterNot { it.viaTag } - .map { it.id } - .toSet() + val manual = note.manualLabelIds.toSet() val viaTag = note.labels .filter { it.viaTag } diff --git a/android/app/src/main/java/com/fabledsword/inkwell/ui/NoteAccess.kt b/android/app/src/main/java/com/fabledsword/inkwell/ui/NoteAccess.kt index f75cf45..cb7fc2a 100644 --- a/android/app/src/main/java/com/fabledsword/inkwell/ui/NoteAccess.kt +++ b/android/app/src/main/java/com/fabledsword/inkwell/ui/NoteAccess.kt @@ -29,3 +29,11 @@ val Note.readOnlyHere: Boolean /** The owner's own controls apply: tags, reminder, files, previews, share, trash. */ val Note.ownerControlsHere: Boolean get() = !readOnlyHere && access == NoteAccess.OWNER + +/** + * The tags attached by hand (the picker, or a lifted line), as opposed to the ones + * the body's own `#tags` carry. A label write sets exactly these; a body tag is the + * body's to keep. + */ +val Note.manualLabelIds: List + get() = labels.filterNot { it.viaTag }.map { it.id } diff --git a/android/app/src/main/java/com/fabledsword/inkwell/ui/NoteCard.kt b/android/app/src/main/java/com/fabledsword/inkwell/ui/NoteCard.kt index 00c83d7..98b9fa2 100644 --- a/android/app/src/main/java/com/fabledsword/inkwell/ui/NoteCard.kt +++ b/android/app/src/main/java/com/fabledsword/inkwell/ui/NoteCard.kt @@ -456,10 +456,7 @@ private fun SharedChip(note: Note) { val text = when { note.access != NoteAccess.OWNER -> - stringResource( - R.string.share_chip_by, - note.sharedBy?.displayName?.takeIf { it.isNotBlank() } ?: stringResource(R.string.share_someone), - ) + stringResource(R.string.share_chip_by, sharerName(note)) note.shared -> stringResource(R.string.share_chip_shared) else -> return } diff --git a/android/app/src/main/java/com/fabledsword/inkwell/ui/ShareSheet.kt b/android/app/src/main/java/com/fabledsword/inkwell/ui/ShareSheet.kt index f154305..69e97e2 100644 --- a/android/app/src/main/java/com/fabledsword/inkwell/ui/ShareSheet.kt +++ b/android/app/src/main/java/com/fabledsword/inkwell/ui/ShareSheet.kt @@ -37,11 +37,16 @@ import com.fabledsword.inkwell.core.NoteShare import com.fabledsword.inkwell.core.ShareGroup import com.fabledsword.inkwell.core.ShareTarget +/** Who shared [note] with us, by name, or "Someone" when the server sent none. */ +@Composable +internal fun sharerName(note: Note): String = + note.sharedBy?.displayName?.takeIf { it.isNotBlank() } ?: stringResource(R.string.share_someone) + /** "Shared by Robin ยท view only" over someone else's note; nothing over our own. */ @Composable fun SharedByLine(note: Note) { if (note.access == NoteAccess.OWNER) return - val who = note.sharedBy?.displayName?.takeIf { it.isNotBlank() } ?: stringResource(R.string.share_someone) + val who = sharerName(note) val line = if (note.access == NoteAccess.EDIT) { stringResource(R.string.share_by_can_edit, who)