android: bring BoardScreen and NoteCard back under detekt's complexity limit
CI & Build / Python lint (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 3s
Android / Build, or is the channel already serving this? (push) Successful in 3s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Skipped
Desktop (Tauri) / Tauri desktop (Linux) (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Skipped
Desktop (Tauri) / Update manifest (push) Skipped
CI & Build / Web typecheck and unit tests (push) Successful in 10s
CI & Build / Python tests (push) Successful in 12s
Android / Core and FFI clippy and tests (push) Successful in 26s
CI & Build / integration (push) Successful in 1m7s
CI & Build / Build & push image (push) Skipped
Android / Kotlin + Rust (APK) (push) Successful in 9m31s
Android / Build the server image (push) Successful in 1s

Run 8693's detekt failed both on CyclomaticComplexMethod (17 and 15 against
15) after the filters and drag-to-reorder landed.

- BoardState now carries `filterable` and `reorderable`, so the board's
  rules for when the filter row shows and when a card can be carried live
  with the state they read instead of as boolean chains in the screen.
- NoteCard's contents (tags, body, links, attachments, reminder, sharing)
  move to their own CardContents composable, leaving NoteCard the gestures,
  the frame and the menu.

No behaviour change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 23:38:37 -04:00
co-authored by Claude Opus 5.5
parent 3b4fe310b8
commit 802eab4ef9
3 changed files with 92 additions and 80 deletions
@@ -195,10 +195,7 @@ fun BoardScreen(
onMenu = { scope.launch { drawerState.open() } }, onMenu = { scope.launch { drawerState.open() } },
) )
// The main board only, and not while searching, as on the web: a if (state.filterable) {
// search spans everything, so a filter row over its hits would be a
// control that does nothing.
if (state.destination == Destination.Notes && !state.searching) {
FilterRow( FilterRow(
filters = state.filters, filters = state.filters,
onOpen = { filtering = true }, onOpen = { filtering = true },
@@ -257,13 +254,7 @@ fun BoardScreen(
onToggleItem = onToggleItem, onToggleItem = onToggleItem,
onNoteAction = onCardAction, onNoteAction = onCardAction,
onConfirmDelete = { confirmingDelete = it }, onConfirmDelete = { confirmingDelete = it },
// The whole board in one order, as on the web: not a reorderable = state.reorderable,
// search, another view, or a filtered subset, whose
// order would be renumbered against notes it can't see.
reorderable =
state.destination == Destination.Notes &&
!state.searching &&
state.filters.count == 0,
onReorder = onReorder, onReorder = onReorder,
) )
} }
@@ -85,6 +85,18 @@ data class BoardState(
) { ) {
/** Search overrides the destination while there is a query to run. */ /** Search overrides the destination while there is a query to run. */
val searching: Boolean get() = query.isNotBlank() val searching: Boolean get() = query.isNotBlank()
/**
* The main board only, and not while searching, as on the web: a search spans
* everything, so a filter over its hits would be a control that does nothing.
*/
val filterable: Boolean get() = destination == Destination.Notes && !searching
/**
* The whole board in one order, as on the web: not a search, another view, or a
* filtered subset, whose order would be renumbered against notes it can't see.
*/
val reorderable: Boolean get() = filterable && filters.count == 0
} }
/** /**
@@ -108,6 +108,25 @@ fun NoteCard(
.border(1.dp, if (dark) CARD_EDGE_DARK else CARD_EDGE_LIGHT, RoundedCornerShape(CARD_RADIUS)) .border(1.dp, if (dark) CARD_EDGE_DARK else CARD_EDGE_LIGHT, RoundedCornerShape(CARD_RADIUS))
.padding(12.dp), .padding(12.dp),
) { ) {
CardContents(note = note, onToggleItem = onToggleItem)
}
NoteMenu(
note = note,
expanded = menuOpen,
onDismiss = { menuOpen = false },
onAction = onAction,
onConfirmDelete = onConfirmDelete,
)
}
}
/** What a card shows, top to bottom: tags, body, links, attachments, reminder, sharing. */
@Composable
private fun CardContents(
note: Note,
onToggleItem: (Int, Boolean) -> Unit,
) {
// TAGS FIRST, on a row of their own above the body: a board is scanned, and // TAGS FIRST, on a row of their own above the body: a board is scanned, and
// what a note is about should be the first thing the eye lands on. Not beside // what a note is about should be the first thing the eye lands on. Not beside
// the body, whose first line is the note's name. // the body, whose first line is the note's name.
@@ -177,16 +196,6 @@ fun NoteCard(
} }
SharedChip(note) SharedChip(note)
}
NoteMenu(
note = note,
expanded = menuOpen,
onDismiss = { menuOpen = false },
onAction = onAction,
onConfirmDelete = onConfirmDelete,
)
}
} }
/** /**