better tag search

This commit is contained in:
randogoth 2025-02-22 15:58:17 +02:00
parent f77a66d5d8
commit 004d2d9e82

View file

@ -194,45 +194,74 @@ class _NoteListScreenState extends State<NoteListScreen> {
}
void _filterNotes() {
final query = searchController.text.trim().toLowerCase();
final query = searchController.text.trim();
if (query.isEmpty) {
setState(() {
filteredNotes = notes;
});
return;
}
final List<String> words = query.split(RegExp(r'\s+')); // Split by spaces
final List<String> terms = [];
final List<String> tags = [];
for (final word in words) {
if (word.startsWith('#') || word.startsWith('+') || word.startsWith('@')) {
tags.add(word.toLowerCase());
} else {
terms.add(word.toLowerCase());
}
}
setState(() {
if (query.startsWith('/')) {
// Extract subfolder path and search term
final parts = query.split('/');
final subfolderPath = parts.sublist(1, parts.length - 1).join('/');
final searchTerm = parts.last;
filteredNotes = notes.where((note) {
final relativePath = path.relative(note.path, from: notesDirectoryPath!);
return relativePath.startsWith(subfolderPath) &&
(relativePath.contains(searchTerm) || note.readAsStringSync().toLowerCase().contains(searchTerm));
}).toList();
} else {
// Default search across all notes
filteredNotes = notes.where((note) {
final content = note.readAsStringSync().toLowerCase();
return note.uri.pathSegments.last.toLowerCase().contains(query) || content.contains(query);
final filename = note.uri.pathSegments.last.toLowerCase();
// Check if all terms are found in filename or content
final bool matchesTerms = terms.isEmpty ||
terms.every((term) => filename.contains(term) || content.contains(term));
// Check if all tags are found in content
final bool matchesTags = tags.isEmpty ||
tags.every((tag) => content.contains(tag));
return matchesTerms && matchesTags;
}).toList();
}
});
}
List<InlineSpan> _formatTags(String content) {
final tagPattern = RegExp(r'([#@+][a-zA-Z0-9_]+)');
final List<InlineSpan> spans = [];
final Set<String> tagSet = {}; // Avoid duplicate tags
for (final match in tagPattern.allMatches(content)) {
final tag = match.group(0)!;
tagSet.add(match.group(0)!);
}
// Sort tags: +tags before @tags before #tags
final sortedTags = tagSet.toList()
..sort((a, b) {
if (a.startsWith('+') && !b.startsWith('+')) return -1;
if (b.startsWith('+') && !a.startsWith('+')) return 1;
if (a.startsWith('@') && !b.startsWith('@')) return -1;
if (b.startsWith('@') && !a.startsWith('@')) return 1;
return a.compareTo(b); // Default alphabetical order
});
return sortedTags.map((tag) {
Color tagColor = Colors.white;
if (tag.startsWith('#')) tagColor = Colors.pinkAccent;
if (tag.startsWith('+')) tagColor = Colors.cyan;
if (tag.startsWith('@')) tagColor = Colors.orange;
spans.add(TextSpan(
text: tag + ' ',
style: TextStyle(color: tagColor, fontWeight: FontWeight.bold)));
}
return spans;
return TextSpan(
text: "$tag ",
style: TextStyle(color: tagColor, fontWeight: FontWeight.bold),
);
}).toList();
}
void _createNewNote(String title) async {
@ -591,22 +620,33 @@ class _NoteListScreenState extends State<NoteListScreen> {
child: ListTile(
title:
Text(noteFile.uri.pathSegments.last.replaceAll('.md', '')),
subtitle: Row(
subtitle: LayoutBuilder(
builder: (context, constraints) {
final bool hasEnoughSpace = constraints.maxWidth > 200; // Adjust as needed
return Row(
children: [
path.relative(path.dirname(noteFile.path), from: notesDirectoryPath!) != "."
? Text(
if (path.relative(path.dirname(noteFile.path), from: notesDirectoryPath!) != ".")
Padding(
padding: EdgeInsets.only(right: 8),
child: Text(
path.relative(path.dirname(noteFile.path), from: notesDirectoryPath!),
style: TextStyle(color: Colors.blueGrey),
)
: Text(""),
widget.showTags && tagSpans.isNotEmpty
? RichText(
),
),
if (widget.showTags && hasEnoughSpace && tagSpans.isNotEmpty)
Expanded(
child: RichText(
text: TextSpan(
style: DefaultTextStyle.of(context).style,
children: tagSpans)
)
: Text("")
children: tagSpans,
),
overflow: TextOverflow.ellipsis, // Prevents overflow errors
),
),
],
);
},
),
onTap: () async {
if (_useExternalEditor) {