mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-28 01:45:55 +08:00
@ -269,6 +269,7 @@ widgets:
|
|||||||
failed: Purchase Failed
|
failed: Purchase Failed
|
||||||
NoteViewer:
|
NoteViewer:
|
||||||
linkNotFound: Link '{}' not found
|
linkNotFound: Link '{}' not found
|
||||||
|
linkInvalid: Link '{}' is invalid.
|
||||||
FolderSelectionDialog:
|
FolderSelectionDialog:
|
||||||
title: Select a Folder
|
title: Select a Folder
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
- text: "Add Shortcuts support in iOS - #262"
|
- text: "Add Shortcuts support in iOS - #262"
|
||||||
image: ios_shortcuts.png
|
image: ios_shortcuts.png
|
||||||
- text: "Custom SSH keys with passwords can now be used - #227"
|
- text: "Custom SSH keys with passwords can now be used - #227"
|
||||||
|
- text: "Create new note when clicking on non existing Wiki Link - #240"
|
||||||
bugs:
|
bugs:
|
||||||
- text: "Fix notes not always showing up - #270"
|
- text: "Fix notes not always showing up - #270"
|
||||||
|
|
||||||
|
@ -104,7 +104,11 @@ class Note with NotesNotifier {
|
|||||||
noteSerializer = NoteSerializer.fromConfig(parent.config);
|
noteSerializer = NoteSerializer.fromConfig(parent.config);
|
||||||
}
|
}
|
||||||
|
|
||||||
Note.newNote(this.parent, {Map<String, dynamic> extraProps = const {}}) {
|
Note.newNote(
|
||||||
|
this.parent, {
|
||||||
|
Map<String, dynamic> extraProps = const {},
|
||||||
|
String fileName = "",
|
||||||
|
}) {
|
||||||
created = DateTime.now();
|
created = DateTime.now();
|
||||||
_loadState = NoteLoadState.Loaded;
|
_loadState = NoteLoadState.Loaded;
|
||||||
_fileFormat = NoteFileFormat.Markdown;
|
_fileFormat = NoteFileFormat.Markdown;
|
||||||
@ -116,6 +120,17 @@ class Note with NotesNotifier {
|
|||||||
});
|
});
|
||||||
noteSerializer.decode(_data, this);
|
noteSerializer.decode(_data, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fileName.isNotEmpty) {
|
||||||
|
// FIXME: We should ensure a note with this fileName does not already
|
||||||
|
// exist
|
||||||
|
if (!NoteFileFormatInfo.isAllowedFileName(fileName)) {
|
||||||
|
fileName +=
|
||||||
|
NoteFileFormatInfo.defaultExtension(NoteFileFormat.Markdown);
|
||||||
|
}
|
||||||
|
_filePath = p.join(parent.folderPath, fileName);
|
||||||
|
Log.i("Constructing new note with path $_filePath");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String get filePath {
|
String get filePath {
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:path/path.dart' as p;
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import 'package:gitjournal/core/note.dart';
|
import 'package:gitjournal/core/note.dart';
|
||||||
import 'package:gitjournal/core/notes_folder.dart';
|
import 'package:gitjournal/core/notes_folder.dart';
|
||||||
|
import 'package:gitjournal/core/notes_folder_fs.dart';
|
||||||
import 'package:gitjournal/folder_views/card_view.dart';
|
import 'package:gitjournal/folder_views/card_view.dart';
|
||||||
import 'package:gitjournal/folder_views/grid_view.dart';
|
import 'package:gitjournal/folder_views/grid_view.dart';
|
||||||
import 'package:gitjournal/folder_views/journal_view.dart';
|
import 'package:gitjournal/folder_views/journal_view.dart';
|
||||||
import 'package:gitjournal/screens/note_editor.dart';
|
import 'package:gitjournal/screens/note_editor.dart';
|
||||||
|
import 'package:gitjournal/settings.dart';
|
||||||
import 'package:gitjournal/state_container.dart';
|
import 'package:gitjournal/state_container.dart';
|
||||||
import 'package:gitjournal/utils.dart';
|
import 'package:gitjournal/utils.dart';
|
||||||
import 'package:gitjournal/utils/logger.dart';
|
import 'package:gitjournal/utils/logger.dart';
|
||||||
@ -83,7 +86,8 @@ void openNoteEditor(
|
|||||||
bool editMode = false,
|
bool editMode = false,
|
||||||
}) async {
|
}) async {
|
||||||
var route = MaterialPageRoute(
|
var route = MaterialPageRoute(
|
||||||
builder: (context) => NoteEditor.fromNote(note, parentFolder, editMode: editMode),
|
builder: (context) =>
|
||||||
|
NoteEditor.fromNote(note, parentFolder, editMode: editMode),
|
||||||
settings: const RouteSettings(name: '/note/'),
|
settings: const RouteSettings(name: '/note/'),
|
||||||
);
|
);
|
||||||
var showUndoSnackBar = await Navigator.of(context).push(route);
|
var showUndoSnackBar = await Navigator.of(context).push(route);
|
||||||
@ -97,3 +101,33 @@ void openNoteEditor(
|
|||||||
..showSnackBar(snackBar);
|
..showSnackBar(snackBar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool openNewNoteEditor(BuildContext context, String term) {
|
||||||
|
var rootFolder = Provider.of<NotesFolderFS>(context, listen: false);
|
||||||
|
var parentFolder = rootFolder;
|
||||||
|
var settings = Provider.of<Settings>(context, listen: false);
|
||||||
|
var defaultEditor = settings.defaultEditor.toEditorType();
|
||||||
|
|
||||||
|
var fileName = term;
|
||||||
|
if (fileName.contains(p.separator)) {
|
||||||
|
parentFolder = rootFolder.getFolderWithSpec(p.dirname(fileName));
|
||||||
|
if (parentFolder == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Log.i("New Note Parent Folder: ${parentFolder.folderPath}");
|
||||||
|
|
||||||
|
fileName = p.basename(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
var route = MaterialPageRoute(
|
||||||
|
builder: (context) => NoteEditor.newNote(
|
||||||
|
parentFolder,
|
||||||
|
parentFolder,
|
||||||
|
defaultEditor,
|
||||||
|
newNoteFileName: fileName,
|
||||||
|
),
|
||||||
|
settings: const RouteSettings(name: '/newNote/'),
|
||||||
|
);
|
||||||
|
Navigator.of(context).push(route);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -37,6 +37,7 @@ class NoteEditor extends StatefulWidget {
|
|||||||
final List<String> existingImages;
|
final List<String> existingImages;
|
||||||
|
|
||||||
final Map<String, dynamic> newNoteExtraProps;
|
final Map<String, dynamic> newNoteExtraProps;
|
||||||
|
final String newNoteFileName;
|
||||||
final bool editMode;
|
final bool editMode;
|
||||||
|
|
||||||
NoteEditor.fromNote(
|
NoteEditor.fromNote(
|
||||||
@ -47,6 +48,7 @@ class NoteEditor extends StatefulWidget {
|
|||||||
defaultEditorType = null,
|
defaultEditorType = null,
|
||||||
existingText = null,
|
existingText = null,
|
||||||
existingImages = null,
|
existingImages = null,
|
||||||
|
newNoteFileName = "",
|
||||||
newNoteExtraProps = null;
|
newNoteExtraProps = null;
|
||||||
|
|
||||||
NoteEditor.newNote(
|
NoteEditor.newNote(
|
||||||
@ -56,6 +58,7 @@ class NoteEditor extends StatefulWidget {
|
|||||||
this.existingText,
|
this.existingText,
|
||||||
this.existingImages,
|
this.existingImages,
|
||||||
this.newNoteExtraProps = const {},
|
this.newNoteExtraProps = const {},
|
||||||
|
this.newNoteFileName = "",
|
||||||
}) : note = null,
|
}) : note = null,
|
||||||
editMode = true;
|
editMode = true;
|
||||||
|
|
||||||
@ -67,6 +70,7 @@ class NoteEditor extends StatefulWidget {
|
|||||||
existingText,
|
existingText,
|
||||||
existingImages,
|
existingImages,
|
||||||
newNoteExtraProps,
|
newNoteExtraProps,
|
||||||
|
newNoteFileName,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return NoteEditorState.fromNote(note);
|
return NoteEditorState.fromNote(note);
|
||||||
@ -95,8 +99,9 @@ class NoteEditorState extends State<NoteEditor> with WidgetsBindingObserver {
|
|||||||
String existingText,
|
String existingText,
|
||||||
List<String> existingImages,
|
List<String> existingImages,
|
||||||
Map<String, dynamic> extraProps,
|
Map<String, dynamic> extraProps,
|
||||||
|
String fileName,
|
||||||
) {
|
) {
|
||||||
note = Note.newNote(folder, extraProps: extraProps);
|
note = Note.newNote(folder, extraProps: extraProps, fileName: fileName);
|
||||||
if (existingText != null) {
|
if (existingText != null) {
|
||||||
note.body = existingText;
|
note.body = existingText;
|
||||||
}
|
}
|
||||||
|
@ -22,15 +22,22 @@ class LinkResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Note resolve(String link) {
|
Note resolve(String link) {
|
||||||
if (link.startsWith('[[') && link.endsWith(']]') && link.length > 4) {
|
if (isWikiLink(link)) {
|
||||||
// FIXME: What if the case is different?
|
// FIXME: What if the case is different?
|
||||||
var wikiLinkTerm = link.substring(2, link.length - 2).trim();
|
return resolveWikiLink(stripWikiSyntax(link));
|
||||||
return resolveWikiLink(wikiLinkTerm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _getNoteWithSpec(inputNote.parent, link);
|
return _getNoteWithSpec(inputNote.parent, link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isWikiLink(String link) {
|
||||||
|
return link.startsWith('[[') && link.endsWith(']]') && link.length > 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String stripWikiSyntax(String link) {
|
||||||
|
return link.substring(2, link.length - 2).trim();
|
||||||
|
}
|
||||||
|
|
||||||
Note resolveWikiLink(String term) {
|
Note resolveWikiLink(String term) {
|
||||||
if (term.contains(p.separator)) {
|
if (term.contains(p.separator)) {
|
||||||
var spec = p.normalize(term);
|
var spec = p.normalize(term);
|
||||||
|
@ -89,6 +89,18 @@ class NoteViewer extends StatelessWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LinkResolver.isWikiLink(link)) {
|
||||||
|
var opened = openNewNoteEditor(
|
||||||
|
context, LinkResolver.stripWikiSyntax(link));
|
||||||
|
if (!opened) {
|
||||||
|
showSnackbar(
|
||||||
|
context,
|
||||||
|
tr('wigets.NoteViewer.linkInvalid', args: [link]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// External Link
|
// External Link
|
||||||
try {
|
try {
|
||||||
await launch(link);
|
await launch(link);
|
||||||
|
Reference in New Issue
Block a user