mirror of
https://github.com/kuhyx/todo-app.git
synced 2026-11-11 18:14:02 +01:00
Glyph + spoken label replaces every app-written string the guard found: empty states, tile meta, sheet dates/fields, date presets, template/section headings, status footer, snackbars, GitHub and cloud-image results, upload/download badges, Material tooltips. Guard tests (text_free_*_test) walk the painted tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
1.9 KiB
Dart
64 lines
1.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'package:todo/data/note.dart';
|
|
import 'package:todo/images/attachment_links.dart';
|
|
|
|
/// [text] without the line that serves as the title.
|
|
String noteBodyOf(String text) {
|
|
final lines = text.split('\n');
|
|
final title = lines.indexWhere(
|
|
(l) => l.trim().isNotEmpty && attachmentOfLine(l.trim()) == null,
|
|
);
|
|
if (title < 0) return text.trim();
|
|
return [...lines.take(title), ...lines.skip(title + 1)].join('\n').trim();
|
|
}
|
|
|
|
String _stamp(DateTime t) {
|
|
String two(int n) => n.toString().padLeft(2, '0');
|
|
final date = '${t.year}-${two(t.month)}-${two(t.day)}';
|
|
return '$date ${two(t.hour)}:${two(t.minute)}';
|
|
}
|
|
|
|
/// What a grid tile leaves out: the note body and its two dates.
|
|
class NoteSheetDetails extends StatelessWidget {
|
|
/// Shows the body and the dates of [note].
|
|
const NoteSheetDetails({required this.note, super.key});
|
|
|
|
/// The note being shown.
|
|
final Note note;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final theme = Theme.of(context).textTheme;
|
|
final body = noteBodyOf(note.text);
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
if (body.isNotEmpty) ...[
|
|
const SizedBox(height: 12),
|
|
Text(body, style: theme.bodyMedium),
|
|
],
|
|
const SizedBox(height: 12),
|
|
Wrap(
|
|
spacing: 12,
|
|
children: [
|
|
_dated(Icons.history, 'Edited', note.updatedAt, theme.bodySmall),
|
|
_dated(Icons.add, 'Created', note.createdAt, theme.bodySmall),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
/// A glyph (edited = history, created = plus) before its timestamp.
|
|
Widget _dated(IconData icon, String spoken, DateTime t, TextStyle? style) =>
|
|
Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(icon, size: 16, semanticLabel: spoken),
|
|
const SizedBox(width: 4),
|
|
Text(_stamp(t), style: style),
|
|
],
|
|
);
|
|
}
|