mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-28 01:45:55 +08:00
Show the backlinks of a Note
This is the initial proof of concept and doesn't look very pretty. It's also not very efficient. Related to #141
This commit is contained in:
@ -437,6 +437,11 @@ class Link {
|
||||
other is Note &&
|
||||
runtimeType == other.runtimeType &&
|
||||
filePath == other.filePath;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Link{term: $term, filePath: $filePath}';
|
||||
}
|
||||
}
|
||||
|
||||
class LinkExtractor implements md.NodeVisitor {
|
||||
|
@ -458,8 +458,33 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
|
||||
Set<String> getNoteTagsRecursively() {
|
||||
return _fetchTags(this, {});
|
||||
}
|
||||
|
||||
Future<List<Note>> matchNotes(NoteMatcherAsync pred) async {
|
||||
var matchedNotes = <Note>[];
|
||||
await _matchNotes(matchedNotes, pred);
|
||||
return matchedNotes;
|
||||
}
|
||||
|
||||
Future<List<Note>> _matchNotes(
|
||||
List<Note> matchedNotes,
|
||||
NoteMatcherAsync pred,
|
||||
) async {
|
||||
for (var note in _notes) {
|
||||
var matches = await pred(note);
|
||||
if (matches) {
|
||||
matchedNotes.add(note);
|
||||
}
|
||||
}
|
||||
|
||||
for (var folder in _folders) {
|
||||
await folder._matchNotes(matchedNotes, pred);
|
||||
}
|
||||
return matchedNotes;
|
||||
}
|
||||
}
|
||||
|
||||
typedef NoteMatcherAsync = Future<bool> Function(Note n);
|
||||
|
||||
Set<String> _fetchTags(NotesFolder folder, Set<String> tags) {
|
||||
for (var note in folder.notes) {
|
||||
tags.addAll(note.tags);
|
||||
|
@ -47,6 +47,7 @@ class NoteViewer extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
|
||||
final rootFolder = Provider.of<NotesFolderFS>(context);
|
||||
var view = EditorScrollView(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
@ -58,7 +59,6 @@ class NoteViewer extends StatelessWidget {
|
||||
styleSheet: markdownStyleSheet,
|
||||
onTapLink: (String link) {
|
||||
if (link.startsWith('./')) {
|
||||
final rootFolder = Provider.of<NotesFolderFS>(context);
|
||||
var spec = link.substring(2);
|
||||
var note = rootFolder.getNoteWithSpec(spec);
|
||||
if (note != null) {
|
||||
@ -75,6 +75,7 @@ class NoteViewer extends StatelessWidget {
|
||||
url, note.parent.folderPath + p.separator, null, null),
|
||||
),
|
||||
),
|
||||
NoteBacklinkRenderer(note: note, rootFolder: rootFolder),
|
||||
// _buildFooter(context),
|
||||
],
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -181,3 +182,86 @@ Widget _handleDataSchemeUri(Uri uri, final double width, final double height) {
|
||||
}
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
class NoteBacklinkRenderer extends StatefulWidget {
|
||||
final Note note;
|
||||
final NotesFolderFS rootFolder;
|
||||
|
||||
NoteBacklinkRenderer({
|
||||
@required this.note,
|
||||
@required this.rootFolder,
|
||||
});
|
||||
|
||||
@override
|
||||
_NoteBacklinkRendererState createState() => _NoteBacklinkRendererState();
|
||||
}
|
||||
|
||||
class _NoteBacklinkRendererState extends State<NoteBacklinkRenderer> {
|
||||
List<Note> linkedNotes = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_initStateAsync();
|
||||
}
|
||||
|
||||
Future<void> _initStateAsync() async {
|
||||
var predicate = (Note n) async {
|
||||
var links = await n.fetchLinks();
|
||||
var matchedLink = links.firstWhere(
|
||||
(l) => l.filePath == widget.note.filePath,
|
||||
orElse: () => null,
|
||||
);
|
||||
return matchedLink != null;
|
||||
};
|
||||
|
||||
var l = await widget.rootFolder.matchNotes(predicate);
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
linkedNotes = l;
|
||||
print("linkedNote $linkedNotes");
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (linkedNotes.isEmpty) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
var textTheme = Theme.of(context).textTheme;
|
||||
var c = Column(
|
||||
children: <Widget>[
|
||||
Text('BackLinks', style: textTheme.headline5),
|
||||
const SizedBox(height: 8.0),
|
||||
for (var n in linkedNotes) _buildNoteLink(n),
|
||||
],
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0.0, 16.0, 0.0, 16.0),
|
||||
child: c,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildNoteLink(Note note) {
|
||||
var textTheme = Theme.of(context).textTheme;
|
||||
var title = note.title;
|
||||
if (title.isEmpty) {
|
||||
title = note.fileName;
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0.0, 8.0, 0, 8.0),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
openNoteEditor(context, note);
|
||||
},
|
||||
child: Text('- $title', style: textTheme.bodyText1),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user