mirror of
https://github.com/kuhyx/todo-app.git
synced 2026-11-10 19:07:02 +01:00
Editing an existing note looked nothing like capturing a new one: it always showed the template dropdown, the View/Guided/Raw pills and the priority/status row. The cause was one missing argument -- both screens already embedded the same NoteEditor, but NoteDetailScreen never passed advancedMode, which defaults to true in the widget while the app-wide AppSettings.advancedMode defaults to false. Extract the shared form as three single-purpose components rather than one widget owning several jobs: - note_meta_row.dart renders the priority/status row (was capture_meta_row.dart; drops the private _MetaDropdown duplicate the detail screen carried, which used DropdownButtonFormField where the shared one uses DropdownButton). - note_form_chrome_gate.dart owns chrome visibility and nothing else, replacing the _chromeVisible flag both screens copy-pasted. - note_form.dart composes those two with NoteEditor. appSettings is now a required parameter through NotesListScreen and NoteDetailScreen. Required, not defaulted: a silent default is exactly what caused this, so it must not be reintroducible. Also in the capture app bar: drop the decorative Icons.list_alt_outlined beside the note count, since the adjacent Icons.list button already names what is counted, and move the count to the right of that button. The finalize-and-clear action becomes Icons.check instead of Icons.add -- it never saved anything (every keystroke is already persisted), so a plus sign misdescribed it. 314 tests, 100% line coverage. Verified in a running web build that edit and capture render identically with advanced mode both off and on. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
59 lines
2.0 KiB
Dart
59 lines
2.0 KiB
Dart
/// Decides whether a note form's chrome (the priority/status row) is visible.
|
|
///
|
|
/// This is the one piece of state capture and the detail screen used to keep
|
|
/// separately, in copy-pasted form -- which is how the two drifted apart. It
|
|
/// lives here so both surfaces resolve visibility by the same rule.
|
|
library;
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
/// Holds the editor's chrome-visibility signal and resolves it against
|
|
/// advanced mode.
|
|
///
|
|
/// Decides visibility and nothing else: it neither builds the metadata row nor
|
|
/// the editor. [builder] receives the resolved answer plus the callback to
|
|
/// hand to `NoteEditor.onChromeVisibleChanged`.
|
|
class NoteFormChromeGate extends StatefulWidget {
|
|
/// Creates a gate resolving visibility against [advancedMode].
|
|
const NoteFormChromeGate({
|
|
required this.advancedMode,
|
|
required this.builder,
|
|
super.key,
|
|
});
|
|
|
|
/// When false the chrome is never shown, whatever the editor reports --
|
|
/// casual capture needs neither the metadata row nor the mode toggle.
|
|
final bool advancedMode;
|
|
|
|
/// Built with the resolved visibility and the editor's visibility callback.
|
|
final Widget Function(
|
|
BuildContext context, {
|
|
required bool chromeVisible,
|
|
required ValueChanged<bool> onChromeVisibleChanged,
|
|
})
|
|
builder;
|
|
|
|
@override
|
|
State<NoteFormChromeGate> createState() => _NoteFormChromeGateState();
|
|
}
|
|
|
|
class _NoteFormChromeGateState extends State<NoteFormChromeGate> {
|
|
/// What the editor last reported. Starts true because a freshly mounted
|
|
/// editor shows its chrome until Guided (wizard or bare stepper) takes over.
|
|
bool _editorChromeVisible = true;
|
|
|
|
void _setEditorChromeVisible(bool visible) {
|
|
if (visible == _editorChromeVisible) return;
|
|
setState(() => _editorChromeVisible = visible);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return widget.builder(
|
|
context,
|
|
chromeVisible: widget.advancedMode && _editorChromeVisible,
|
|
onChromeVisibleChanged: _setEditorChromeVisible,
|
|
);
|
|
}
|
|
}
|