todo-app/lib/ui/notes_assign_flow.dart
Krzysztof kuhy Rudnicki 757c54beda Multi-select notes with an icon action bar
An app-bar toggle enters selection mode: a tap toggles a note (tint +
check on grid tiles, ListTile.selected + check in the list), Ctrl/Cmd-
click toggles and Shift-click range-selects on desktop, long-press
outside the mode still opens the per-note sheet. While anything is
selected an icon-only bottom bar sets status or priority for the whole
selection in one bulkUpdate, assigns plain notes to a repo picked from
the repos on notes or typed as owner/name, or clears the selection. A
refused assign (note already in a repo) flashes a block icon. Labels
are semantic only; menus pass an empty tooltip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWXdsB7CQPNXVN829G1
2026-11-10 15:39:13 +01:00

38 lines
1.3 KiB
Dart

/// The selection bar's assign flow: pick a repo, move the notes into it.
///
/// Data-layer only ([assignToRepo]); the UI never reaches the board, so an
/// assign never starts a task.
library;
import 'package:flutter/material.dart';
import 'package:todo/data/note_repository.dart';
import 'package:todo/data/repo_assign.dart';
import 'package:todo/ui/note_selection.dart';
import 'package:todo/ui/repo_picker_sheet.dart';
/// Asks for a repo and assigns the selected plain notes to it, in
/// selection order. True when some notes were refused (already in a repo);
/// those stay selected, the moved ones leave the selection.
Future<bool> assignSelection(
BuildContext context,
NoteRepository repository,
NoteSelection selection,
) async {
final all = await repository.listNotes();
final repos = {for (final n in all) ?n.repo}.toList()..sort();
if (!context.mounted) return false;
final repo = await showModalBottomSheet<String>(
context: context,
isScrollControlled: true,
showDragHandle: true,
builder: (_) => RepoPickerSheet(repos: repos),
);
if (repo == null) return false;
final byId = {for (final n in all) n.id: n};
final chosen = [for (final id in selection.ids) ?byId[id]];
final refused = await assignToRepo(repository, chosen, repo);
selection.retain({for (final n in refused) n.id});
return refused.isNotEmpty;
}