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:
Vishesh Handa
2020-08-21 12:18:55 +02:00
parent 36fa1e3f80
commit aabeb57fc0
6 changed files with 66 additions and 13 deletions

View File

@ -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:

View File

@ -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());
}

View File

@ -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,

View File

@ -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')),

View File

@ -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(' '),
};
}

View File

@ -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'});
});
}