mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-29 10:17:16 +08:00
InlineTags: Add settings page
And support multiple prefixes. This is disabled for now as it hasn't been fully integrated.
This commit is contained in:
@ -90,6 +90,11 @@ settings:
|
||||
remoteSync:
|
||||
auto: Automatic
|
||||
manual: Manual
|
||||
tags:
|
||||
title: Tags Settings
|
||||
subtitle: Configure how inline tags are parsed
|
||||
enable: Parse Inline Tags
|
||||
prefixes: Inline Tags Prefixes
|
||||
|
||||
editors:
|
||||
checklist:
|
||||
|
@ -1,16 +1,21 @@
|
||||
import 'package:gitjournal/core/note.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
class InlineTagsProcessor {
|
||||
// FIXME: Make me configurable
|
||||
final List<String> tagPrefixes = ['#'];
|
||||
final Set<String> tagPrefixes;
|
||||
|
||||
void process(Note note) {}
|
||||
InlineTagsProcessor({@required this.tagPrefixes});
|
||||
|
||||
Set<String> extractTags(String text) {
|
||||
var tags = <String>{};
|
||||
|
||||
for (var prefix in tagPrefixes) {
|
||||
var regexp = RegExp(r'(^|\s)' + prefix + r'([^ ]+)(\s|$)');
|
||||
// FIXME: Do not hardcode this
|
||||
var p = prefix;
|
||||
if (p == '+') {
|
||||
p = '\\+';
|
||||
}
|
||||
|
||||
var regexp = RegExp(r'(^|\s)' + p + r'([^ ]+)(\s|$)');
|
||||
var matches = regexp.allMatches(text);
|
||||
for (var match in matches) {
|
||||
var tag = match.group(2);
|
||||
@ -19,7 +24,7 @@ class InlineTagsProcessor {
|
||||
tag = tag.substring(0, tag.length - 1);
|
||||
}
|
||||
|
||||
var all = tag.split('#');
|
||||
var all = tag.split(prefix);
|
||||
for (var t in all) {
|
||||
tags.add(t.trim());
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
class Features {
|
||||
static bool perFolderConfig = false;
|
||||
static bool inlineTags = false;
|
||||
|
||||
static final all = <Feature>[
|
||||
Feature.basicSearch,
|
||||
|
@ -14,6 +14,7 @@ import 'package:gitjournal/screens/settings_experimental.dart';
|
||||
import 'package:gitjournal/screens/settings_git_remote.dart';
|
||||
import 'package:gitjournal/screens/settings_images.dart';
|
||||
import 'package:gitjournal/screens/settings_note_metadata.dart';
|
||||
import 'package:gitjournal/screens/settings_tags.dart';
|
||||
import 'package:gitjournal/screens/settings_widgets.dart';
|
||||
import 'package:gitjournal/settings.dart';
|
||||
import 'package:gitjournal/state_container.dart';
|
||||
@ -241,6 +242,18 @@ class SettingsListState extends State<SettingsList> {
|
||||
Navigator.of(context).push(route);
|
||||
},
|
||||
),
|
||||
if (Features.inlineTags)
|
||||
ListTile(
|
||||
title: Text(tr("settings.tags.title")),
|
||||
subtitle: Text(tr("settings.tags.subtitle")),
|
||||
onTap: () {
|
||||
var route = MaterialPageRoute(
|
||||
builder: (context) => SettingsTagsScreen(),
|
||||
settings: const RouteSettings(name: '/settings/tags'),
|
||||
);
|
||||
Navigator.of(context).push(route);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text(tr('settings.images.title')),
|
||||
subtitle: Text(tr('settings.images.subtitle')),
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
@ -66,6 +67,8 @@ class Settings extends ChangeNotifier {
|
||||
bool zenMode = false;
|
||||
bool saveTitleInH1 = true;
|
||||
|
||||
Set<String> inlineTagPrefixes = {'#'};
|
||||
|
||||
void load(SharedPreferences pref) {
|
||||
onBoardingCompleted = pref.getBool("onBoardingCompleted") ?? false;
|
||||
|
||||
@ -142,6 +145,8 @@ class Settings extends ChangeNotifier {
|
||||
|
||||
zenMode = pref.getBool("zenMode") ?? zenMode;
|
||||
saveTitleInH1 = pref.getBool("saveTitleInH1") ?? saveTitleInH1;
|
||||
inlineTagPrefixes =
|
||||
pref.getStringList("inlineTagPrefixes")?.toSet() ?? inlineTagPrefixes;
|
||||
}
|
||||
|
||||
Future save() async {
|
||||
@ -220,6 +225,8 @@ class Settings extends ChangeNotifier {
|
||||
defaultSet.experimentalMarkdownToolbar);
|
||||
_setBool(pref, "zenMode", zenMode, defaultSet.zenMode);
|
||||
_setBool(pref, "saveTitleInH1", saveTitleInH1, defaultSet.saveTitleInH1);
|
||||
_setStringSet(pref, "inlineTagPrefixes", inlineTagPrefixes,
|
||||
defaultSet.inlineTagPrefixes);
|
||||
|
||||
pref.setInt("settingsVersion", version);
|
||||
|
||||
@ -252,6 +259,21 @@ class Settings extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _setStringSet(
|
||||
SharedPreferences pref,
|
||||
String key,
|
||||
Set<String> value,
|
||||
Set<String> defaultValue,
|
||||
) async {
|
||||
final eq = const SetEquality().equals;
|
||||
|
||||
if (eq(value, defaultValue)) {
|
||||
await pref.remove(key);
|
||||
} else {
|
||||
await pref.setStringList(key, value.toList());
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> toMap() {
|
||||
return <String, String>{
|
||||
"onBoardingCompleted": onBoardingCompleted.toString(),
|
||||
@ -289,6 +311,7 @@ class Settings extends ChangeNotifier {
|
||||
'experimentalMarkdownToolbar': experimentalMarkdownToolbar.toString(),
|
||||
'zenMode': zenMode.toString(),
|
||||
'saveTitleInH1': saveTitleInH1.toString(),
|
||||
'inlineTagPrefixes': inlineTagPrefixes.join(' '),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ void main() {
|
||||
test('Should parse simple tags', () {
|
||||
var body = "#hello Hi\nthere how#are you #doing now? #dog";
|
||||
|
||||
var p = InlineTagsProcessor();
|
||||
var p = InlineTagsProcessor(tagPrefixes: {'#'});
|
||||
var tags = p.extractTags(body);
|
||||
|
||||
expect(tags, {'hello', 'doing', 'dog'});
|
||||
@ -15,7 +15,7 @@ void main() {
|
||||
test('Ignore . at the end of a tag', () {
|
||||
var body = "Hi there #tag.";
|
||||
|
||||
var p = InlineTagsProcessor();
|
||||
var p = InlineTagsProcessor(tagPrefixes: {'#'});
|
||||
var tags = p.extractTags(body);
|
||||
|
||||
expect(tags, {'tag'});
|
||||
@ -24,7 +24,7 @@ void main() {
|
||||
test('#a#b should be counted as two tags', () {
|
||||
var body = "Hi there #a#b";
|
||||
|
||||
var p = InlineTagsProcessor();
|
||||
var p = InlineTagsProcessor(tagPrefixes: {'#'});
|
||||
var tags = p.extractTags(body);
|
||||
|
||||
expect(tags, {'a', 'b'});
|
||||
@ -33,7 +33,7 @@ void main() {
|
||||
test('Non Ascii tags', () {
|
||||
var body = "Hi #fíre gone";
|
||||
|
||||
var p = InlineTagsProcessor();
|
||||
var p = InlineTagsProcessor(tagPrefixes: {'#'});
|
||||
var tags = p.extractTags(body);
|
||||
|
||||
expect(tags, {'fíre'});
|
||||
@ -42,12 +42,18 @@ void main() {
|
||||
test('Tags with a -', () {
|
||||
var body = "Hi #future-me. How are you?";
|
||||
|
||||
var p = InlineTagsProcessor();
|
||||
var p = InlineTagsProcessor(tagPrefixes: {'#'});
|
||||
var tags = p.extractTags(body);
|
||||
|
||||
expect(tags, {'future-me'});
|
||||
});
|
||||
|
||||
// + should work as a prefix
|
||||
// @ should work as a prefix
|
||||
test('Multiple Prefixes', () {
|
||||
var body = "Hi +one+two @foo #doo";
|
||||
|
||||
var p = InlineTagsProcessor(tagPrefixes: {'#', '+', '@'});
|
||||
var tags = p.extractTags(body);
|
||||
|
||||
expect(tags, {'one', 'two', 'foo', 'doo'});
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user