mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-27 09:06:43 +08:00
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:
@ -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();
|
||||
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user