From 895d2f4f1b7668b5dbc144aa50ff3d96e5bd9e36 Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Fri, 27 Dec 2019 11:04:19 +0100 Subject: [PATCH] Give each Note a title We're moving away from being a Journal Editor to being a Note Editor. I don't want to discard the Journaling parts, as Journaling is really a subset of Note Taking - so in the future it would be nice if this could be somehow toggled. Maybe each Folder can have different display settings. Probably in the "pro" version. --- lib/core/note.dart | 19 +++++++++++++ lib/screens/journal_browsing.dart | 33 ++++++++++++++++++---- lib/screens/journal_editor.dart | 47 ++++++++++++++++++++++++++++--- 3 files changed, 90 insertions(+), 9 deletions(-) diff --git a/lib/core/note.dart b/lib/core/note.dart index 4bc77fc4..6a3e4f35 100644 --- a/lib/core/note.dart +++ b/lib/core/note.dart @@ -20,6 +20,7 @@ class Note with ChangeNotifier implements Comparable { NotesFolder parent; String _filePath; + String _title = ""; DateTime _created; DateTime _modified; NoteData _data = NoteData(); @@ -86,6 +87,21 @@ class Note with ChangeNotifier implements Comparable { notifyListeners(); } + String get title { + return _title; + } + + set title(String title) { + _title = title; + + if (_title.isEmpty) { + _data.props.remove('title'); + } else { + _data.props['title'] = title; + } + notifyListeners(); + } + NoteData get data { return _data; } @@ -99,6 +115,9 @@ class Note with ChangeNotifier implements Comparable { if (data.props.containsKey("modified")) { _modified = parseDateTime(data.props['modified'].toString()); } + if (data.props.containsKey("title")) { + _title = data.props['title'].toString(); + } _created ??= DateTime(0, 0, 0, 0, 0, 0, 0, 0); notifyListeners(); diff --git a/lib/screens/journal_browsing.dart b/lib/screens/journal_browsing.dart index a89781b5..dd054788 100644 --- a/lib/screens/journal_browsing.dart +++ b/lib/screens/journal_browsing.dart @@ -49,7 +49,7 @@ class JournalBrowsingScreenState extends State { return Scaffold( appBar: AppBar( - title: const Text('TIMELINE'), + title: const Text('BROWSE'), actions: [ IconButton( icon: Icon(Icons.delete), @@ -124,6 +124,9 @@ class NoteViewer extends StatelessWidget { final Note note; const NoteViewer({Key key, @required this.note}) : super(key: key); + final bool showJournalHeader = false; + final bool showTitle = true; + @override Widget build(BuildContext context) { ThemeData theme = Theme.of(context); @@ -137,10 +140,16 @@ class NoteViewer extends StatelessWidget { var view = SingleChildScrollView( child: Column( children: [ - note.hasValidDate() ? JournalEditorHeader(note) : Container(), - MarkdownBody( - data: note.body, - styleSheet: MarkdownStyleSheet.fromTheme(theme), + if (note.hasValidDate() && showJournalHeader) + JournalEditorHeader(note), + if (showTitle && note.title.isNotEmpty) + NoteTitleHeader(note.title), + Padding( + padding: const EdgeInsets.only(top: 8.0, bottom: 8.0), + child: MarkdownBody( + data: note.body, + styleSheet: MarkdownStyleSheet.fromTheme(theme), + ), ), const SizedBox(height: 64.0), // _buildFooter(context), @@ -179,3 +188,17 @@ class NoteViewer extends StatelessWidget { } */ } + +class NoteTitleHeader extends StatelessWidget { + final String header; + NoteTitleHeader(this.header); + + @override + Widget build(BuildContext context) { + var textTheme = Theme.of(context).textTheme; + return Padding( + padding: const EdgeInsets.only(top: 8.0, bottom: 8.0), + child: Text(header, style: textTheme.title), + ); + } +} diff --git a/lib/screens/journal_editor.dart b/lib/screens/journal_editor.dart index d2b4dd81..59adb016 100644 --- a/lib/screens/journal_editor.dart +++ b/lib/screens/journal_editor.dart @@ -29,20 +29,27 @@ class JournalEditorState extends State { Note note; final bool newNote; TextEditingController _textController = TextEditingController(); + TextEditingController _titleTextController = TextEditingController(); + bool rawEditor = false; final serializer = MarkdownYAMLSerializer(); + final bool journalMode = false; + final bool showTitle = true; + JournalEditorState.newNote(NotesFolder folder) : newNote = true { note = Note.newNote(folder); } JournalEditorState.fromNote(this.note) : newNote = false { _textController = TextEditingController(text: note.body); + _titleTextController = TextEditingController(text: note.title); } @override void dispose() { _textController.dispose(); + _titleTextController.dispose(); super.dispose(); } @@ -50,7 +57,8 @@ class JournalEditorState extends State { Widget build(BuildContext context) { Widget editor = Column( children: [ - JournalEditorHeader(note), + if (journalMode) JournalEditorHeader(note), + if (showTitle && !rawEditor) NoteTitleEditor(_titleTextController), NoteMarkdownEditor(_textController, false), ], ); @@ -82,11 +90,13 @@ class JournalEditorState extends State { } break; case NoteEditorDropDownChoices.SwitchEditor: + note.title = _titleTextController.text.trim(); setState(() { if (rawEditor) { rawEditor = false; note.data = serializer.decode(_textController.text); _textController.text = note.body; + _titleTextController.text = note.title; } else { rawEditor = true; var noteData = @@ -158,14 +168,15 @@ class JournalEditorState extends State { bool _noteModified() { var noteContent = _textController.text.trim(); - if (noteContent.isEmpty) { + var titleContent = _titleTextController.text.trim(); + if (noteContent.isEmpty && titleContent.isEmpty) { return false; } if (note != null) { if (rawEditor) { return serializer.encode(note.data) != noteContent; } else { - return noteContent != note.body; + return noteContent != note.body || titleContent != note.title; } } @@ -177,7 +188,8 @@ class JournalEditorState extends State { final stateContainer = StateContainer.of(context); if (rawEditor == false) { - note.body = _textController.text; + note.body = _textController.text.trim(); + note.title = _titleTextController.text.trim(); } else { note.data = serializer.decode(_textController.text); } @@ -209,6 +221,33 @@ class NoteMarkdownEditor extends StatelessWidget { decoration: InputDecoration( hintText: 'Write here', border: InputBorder.none, + isDense: true, + ), + controller: textController, + textCapitalization: TextCapitalization.sentences, + scrollPadding: const EdgeInsets.all(0.0), + ); + } +} + +class NoteTitleEditor extends StatelessWidget { + final TextEditingController textController; + + NoteTitleEditor(this.textController); + + @override + Widget build(BuildContext context) { + var style = Theme.of(context).textTheme.title; + + return TextField( + autofocus: false, + keyboardType: TextInputType.text, + maxLines: 1, + style: style, + decoration: InputDecoration( + hintText: 'Title', + border: InputBorder.none, + isDense: true, ), controller: textController, textCapitalization: TextCapitalization.sentences,