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;
String _filePath;
String _title = "";
DateTime _created;
DateTime _modified;
NoteData _data = NoteData();
@ -86,6 +87,21 @@ class Note with ChangeNotifier implements Comparable<Note> {
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<Note> {
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();

View File

@ -49,7 +49,7 @@ class JournalBrowsingScreenState extends State<JournalBrowsingScreen> {
return Scaffold(
appBar: AppBar(
title: const Text('TIMELINE'),
title: const Text('BROWSE'),
actions: <Widget>[
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,11 +140,17 @@ class NoteViewer extends StatelessWidget {
var view = SingleChildScrollView(
child: Column(
children: <Widget>[
note.hasValidDate() ? JournalEditorHeader(note) : Container(),
MarkdownBody(
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),
);
}
}

View File

@ -29,20 +29,27 @@ class JournalEditorState extends State<JournalEditor> {
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<JournalEditor> {
Widget build(BuildContext context) {
Widget editor = Column(
children: <Widget>[
JournalEditorHeader(note),
if (journalMode) JournalEditorHeader(note),
if (showTitle && !rawEditor) NoteTitleEditor(_titleTextController),
NoteMarkdownEditor(_textController, false),
],
);
@ -82,11 +90,13 @@ class JournalEditorState extends State<JournalEditor> {
}
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<JournalEditor> {
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<JournalEditor> {
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,