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.
This commit is contained in:
Vishesh Handa
2019-12-27 11:04:19 +01:00
parent 046c08cb67
commit 895d2f4f1b
3 changed files with 90 additions and 9 deletions

View File

@ -20,6 +20,7 @@ class Note with ChangeNotifier implements Comparable<Note> {
NotesFolder parent; NotesFolder parent;
String _filePath; String _filePath;
String _title = "";
DateTime _created; DateTime _created;
DateTime _modified; DateTime _modified;
NoteData _data = NoteData(); NoteData _data = NoteData();
@ -86,6 +87,21 @@ class Note with ChangeNotifier implements Comparable<Note> {
notifyListeners(); 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 { NoteData get data {
return _data; return _data;
} }
@ -99,6 +115,9 @@ class Note with ChangeNotifier implements Comparable<Note> {
if (data.props.containsKey("modified")) { if (data.props.containsKey("modified")) {
_modified = parseDateTime(data.props['modified'].toString()); _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); _created ??= DateTime(0, 0, 0, 0, 0, 0, 0, 0);
notifyListeners(); notifyListeners();

View File

@ -49,7 +49,7 @@ class JournalBrowsingScreenState extends State<JournalBrowsingScreen> {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('TIMELINE'), title: const Text('BROWSE'),
actions: <Widget>[ actions: <Widget>[
IconButton( IconButton(
icon: Icon(Icons.delete), icon: Icon(Icons.delete),
@ -124,6 +124,9 @@ class NoteViewer extends StatelessWidget {
final Note note; final Note note;
const NoteViewer({Key key, @required this.note}) : super(key: key); const NoteViewer({Key key, @required this.note}) : super(key: key);
final bool showJournalHeader = false;
final bool showTitle = true;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
ThemeData theme = Theme.of(context); ThemeData theme = Theme.of(context);
@ -137,10 +140,16 @@ class NoteViewer extends StatelessWidget {
var view = SingleChildScrollView( var view = SingleChildScrollView(
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
note.hasValidDate() ? JournalEditorHeader(note) : Container(), if (note.hasValidDate() && showJournalHeader)
MarkdownBody( JournalEditorHeader(note),
data: note.body, if (showTitle && note.title.isNotEmpty)
styleSheet: MarkdownStyleSheet.fromTheme(theme), 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), const SizedBox(height: 64.0),
// _buildFooter(context), // _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),
);
}
}

View File

@ -29,20 +29,27 @@ class JournalEditorState extends State<JournalEditor> {
Note note; Note note;
final bool newNote; final bool newNote;
TextEditingController _textController = TextEditingController(); TextEditingController _textController = TextEditingController();
TextEditingController _titleTextController = TextEditingController();
bool rawEditor = false; bool rawEditor = false;
final serializer = MarkdownYAMLSerializer(); final serializer = MarkdownYAMLSerializer();
final bool journalMode = false;
final bool showTitle = true;
JournalEditorState.newNote(NotesFolder folder) : newNote = true { JournalEditorState.newNote(NotesFolder folder) : newNote = true {
note = Note.newNote(folder); note = Note.newNote(folder);
} }
JournalEditorState.fromNote(this.note) : newNote = false { JournalEditorState.fromNote(this.note) : newNote = false {
_textController = TextEditingController(text: note.body); _textController = TextEditingController(text: note.body);
_titleTextController = TextEditingController(text: note.title);
} }
@override @override
void dispose() { void dispose() {
_textController.dispose(); _textController.dispose();
_titleTextController.dispose();
super.dispose(); super.dispose();
} }
@ -50,7 +57,8 @@ class JournalEditorState extends State<JournalEditor> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget editor = Column( Widget editor = Column(
children: <Widget>[ children: <Widget>[
JournalEditorHeader(note), if (journalMode) JournalEditorHeader(note),
if (showTitle && !rawEditor) NoteTitleEditor(_titleTextController),
NoteMarkdownEditor(_textController, false), NoteMarkdownEditor(_textController, false),
], ],
); );
@ -82,11 +90,13 @@ class JournalEditorState extends State<JournalEditor> {
} }
break; break;
case NoteEditorDropDownChoices.SwitchEditor: case NoteEditorDropDownChoices.SwitchEditor:
note.title = _titleTextController.text.trim();
setState(() { setState(() {
if (rawEditor) { if (rawEditor) {
rawEditor = false; rawEditor = false;
note.data = serializer.decode(_textController.text); note.data = serializer.decode(_textController.text);
_textController.text = note.body; _textController.text = note.body;
_titleTextController.text = note.title;
} else { } else {
rawEditor = true; rawEditor = true;
var noteData = var noteData =
@ -158,14 +168,15 @@ class JournalEditorState extends State<JournalEditor> {
bool _noteModified() { bool _noteModified() {
var noteContent = _textController.text.trim(); var noteContent = _textController.text.trim();
if (noteContent.isEmpty) { var titleContent = _titleTextController.text.trim();
if (noteContent.isEmpty && titleContent.isEmpty) {
return false; return false;
} }
if (note != null) { if (note != null) {
if (rawEditor) { if (rawEditor) {
return serializer.encode(note.data) != noteContent; return serializer.encode(note.data) != noteContent;
} else { } else {
return noteContent != note.body; return noteContent != note.body || titleContent != note.title;
} }
} }
@ -177,7 +188,8 @@ class JournalEditorState extends State<JournalEditor> {
final stateContainer = StateContainer.of(context); final stateContainer = StateContainer.of(context);
if (rawEditor == false) { if (rawEditor == false) {
note.body = _textController.text; note.body = _textController.text.trim();
note.title = _titleTextController.text.trim();
} else { } else {
note.data = serializer.decode(_textController.text); note.data = serializer.decode(_textController.text);
} }
@ -209,6 +221,33 @@ class NoteMarkdownEditor extends StatelessWidget {
decoration: InputDecoration( decoration: InputDecoration(
hintText: 'Write here', hintText: 'Write here',
border: InputBorder.none, 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, controller: textController,
textCapitalization: TextCapitalization.sentences, textCapitalization: TextCapitalization.sentences,