support bang additional triggers

This commit is contained in:
Fabian Freund
2025-09-30 10:59:39 +02:00
parent d278145c5b
commit 7c4662a7be
13 changed files with 1188 additions and 104 deletions
@@ -13,10 +13,12 @@ abstract class $BangDatabase extends i0.GeneratedDatabase {
$BangDatabase(i0.QueryExecutor e) : super(e); $BangDatabase(i0.QueryExecutor e) : super(e);
$BangDatabaseManager get managers => $BangDatabaseManager(this); $BangDatabaseManager get managers => $BangDatabaseManager(this);
late final i1.BangTable bang = i1.BangTable(this); late final i1.BangTable bang = i1.BangTable(this);
late final i1.BangTriggers bangTriggers = i1.BangTriggers(this);
late final i1.BangSync bangSync = i1.BangSync(this); late final i1.BangSync bangSync = i1.BangSync(this);
late final i1.BangFrequency bangFrequency = i1.BangFrequency(this); late final i1.BangFrequency bangFrequency = i1.BangFrequency(this);
late final i1.BangHistory bangHistory = i1.BangHistory(this); late final i1.BangHistory bangHistory = i1.BangHistory(this);
late final i1.BangFts bangFts = i1.BangFts(this); late final i1.BangFts bangFts = i1.BangFts(this);
late final i1.BangTriggersFts bangTriggersFts = i1.BangTriggersFts(this);
late final i1.BangDataView bangDataView = i1.BangDataView(this); late final i1.BangDataView bangDataView = i1.BangDataView(this);
late final i2.BangDao bangDao = i2.BangDao(this as i3.BangDatabase); late final i2.BangDao bangDao = i2.BangDao(this as i3.BangDatabase);
late final i4.SyncDao syncDao = i4.SyncDao(this as i3.BangDatabase); late final i4.SyncDao syncDao = i4.SyncDao(this as i3.BangDatabase);
@@ -29,49 +31,100 @@ abstract class $BangDatabase extends i0.GeneratedDatabase {
@override @override
List<i0.DatabaseSchemaEntity> get allSchemaEntities => [ List<i0.DatabaseSchemaEntity> get allSchemaEntities => [
bang, bang,
bangTriggers,
i1.idxBangTriggersLookup,
i1.bangTriggersAfterInsert,
i1.bangTriggersAfterUpdate,
bangSync, bangSync,
bangFrequency, bangFrequency,
bangHistory, bangHistory,
bangFts, bangFts,
bangTriggersFts,
bangDataView, bangDataView,
i1.bangAfterInsert, i1.bangAfterInsert,
i1.bangAfterDelete, i1.bangAfterDelete,
i1.bangAfterUpdate, i1.bangAfterUpdate,
i1.bangTriggersAfterInsertFts,
i1.bangTriggersAfterDeleteFts,
i1.bangTriggersAfterUpdateFts,
]; ];
@override @override
i0.StreamQueryUpdateRules get streamUpdateRules => i0.StreamQueryUpdateRules
const i0.StreamQueryUpdateRules([ get streamUpdateRules => const i0.StreamQueryUpdateRules([
i0.WritePropagation( i0.WritePropagation(
on: i0.TableUpdateQuery.onTableName( on: i0.TableUpdateQuery.onTableName(
'bang', 'bang',
limitUpdateKind: i0.UpdateKind.delete, limitUpdateKind: i0.UpdateKind.delete,
), ),
result: [ result: [i0.TableUpdate('bang_triggers', kind: i0.UpdateKind.delete)],
i0.TableUpdate('bang_frequency', kind: i0.UpdateKind.delete), ),
], i0.WritePropagation(
), on: i0.TableUpdateQuery.onTableName(
i0.WritePropagation( 'bang',
on: i0.TableUpdateQuery.onTableName( limitUpdateKind: i0.UpdateKind.insert,
'bang', ),
limitUpdateKind: i0.UpdateKind.insert, result: [i0.TableUpdate('bang_triggers', kind: i0.UpdateKind.insert)],
), ),
result: [i0.TableUpdate('bang_fts', kind: i0.UpdateKind.insert)], i0.WritePropagation(
), on: i0.TableUpdateQuery.onTableName(
i0.WritePropagation( 'bang',
on: i0.TableUpdateQuery.onTableName( limitUpdateKind: i0.UpdateKind.update,
'bang', ),
limitUpdateKind: i0.UpdateKind.delete, result: [
), i0.TableUpdate('bang_triggers', kind: i0.UpdateKind.delete),
result: [i0.TableUpdate('bang_fts', kind: i0.UpdateKind.insert)], i0.TableUpdate('bang_triggers', kind: i0.UpdateKind.insert),
), ],
i0.WritePropagation( ),
on: i0.TableUpdateQuery.onTableName( i0.WritePropagation(
'bang', on: i0.TableUpdateQuery.onTableName(
limitUpdateKind: i0.UpdateKind.update, 'bang',
), limitUpdateKind: i0.UpdateKind.delete,
result: [i0.TableUpdate('bang_fts', kind: i0.UpdateKind.insert)], ),
), result: [i0.TableUpdate('bang_frequency', kind: i0.UpdateKind.delete)],
]); ),
i0.WritePropagation(
on: i0.TableUpdateQuery.onTableName(
'bang',
limitUpdateKind: i0.UpdateKind.insert,
),
result: [i0.TableUpdate('bang_fts', kind: i0.UpdateKind.insert)],
),
i0.WritePropagation(
on: i0.TableUpdateQuery.onTableName(
'bang',
limitUpdateKind: i0.UpdateKind.delete,
),
result: [i0.TableUpdate('bang_fts', kind: i0.UpdateKind.insert)],
),
i0.WritePropagation(
on: i0.TableUpdateQuery.onTableName(
'bang',
limitUpdateKind: i0.UpdateKind.update,
),
result: [i0.TableUpdate('bang_fts', kind: i0.UpdateKind.insert)],
),
i0.WritePropagation(
on: i0.TableUpdateQuery.onTableName(
'bang_triggers',
limitUpdateKind: i0.UpdateKind.insert,
),
result: [i0.TableUpdate('bang_triggers_fts', kind: i0.UpdateKind.insert)],
),
i0.WritePropagation(
on: i0.TableUpdateQuery.onTableName(
'bang_triggers',
limitUpdateKind: i0.UpdateKind.delete,
),
result: [i0.TableUpdate('bang_triggers_fts', kind: i0.UpdateKind.insert)],
),
i0.WritePropagation(
on: i0.TableUpdateQuery.onTableName(
'bang_triggers',
limitUpdateKind: i0.UpdateKind.update,
),
result: [i0.TableUpdate('bang_triggers_fts', kind: i0.UpdateKind.insert)],
),
]);
} }
class $BangDatabaseManager { class $BangDatabaseManager {
@@ -79,6 +132,8 @@ class $BangDatabaseManager {
$BangDatabaseManager(this._db); $BangDatabaseManager(this._db);
i1.$BangTableTableManager get bang => i1.$BangTableTableManager get bang =>
i1.$BangTableTableManager(_db, _db.bang); i1.$BangTableTableManager(_db, _db.bang);
i1.$BangTriggersTableManager get bangTriggers =>
i1.$BangTriggersTableManager(_db, _db.bangTriggers);
i1.$BangSyncTableManager get bangSync => i1.$BangSyncTableManager get bangSync =>
i1.$BangSyncTableManager(_db, _db.bangSync); i1.$BangSyncTableManager(_db, _db.bangSync);
i1.$BangFrequencyTableManager get bangFrequency => i1.$BangFrequencyTableManager get bangFrequency =>
@@ -87,6 +142,8 @@ class $BangDatabaseManager {
i1.$BangHistoryTableManager(_db, _db.bangHistory); i1.$BangHistoryTableManager(_db, _db.bangHistory);
i1.$BangFtsTableManager get bangFts => i1.$BangFtsTableManager get bangFts =>
i1.$BangFtsTableManager(_db, _db.bangFts); i1.$BangFtsTableManager(_db, _db.bangFts);
i1.$BangTriggersFtsTableManager get bangTriggersFts =>
i1.$BangTriggersFtsTableManager(_db, _db.bangTriggersFts);
} }
extension DefineFunctions on i6.CommonDatabase { extension DefineFunctions on i6.CommonDatabase {
@@ -1,4 +1,5 @@
import 'package:weblibre/features/bangs/data/database/drift/converters/bang_format.dart'; import 'package:weblibre/features/bangs/data/database/drift/converters/bang_format.dart';
import 'package:weblibre/features/bangs/data/database/drift/converters/trigger_list.dart';
import 'package:weblibre/features/bangs/data/models/bang_data.dart'; import 'package:weblibre/features/bangs/data/models/bang_data.dart';
import 'package:weblibre/features/bangs/data/models/bang_group.dart'; import 'package:weblibre/features/bangs/data/models/bang_group.dart';
import 'package:weblibre/features/bangs/data/models/bang.dart'; import 'package:weblibre/features/bangs/data/models/bang.dart';
@@ -13,9 +14,47 @@ CREATE TABLE bang (
category TEXT, category TEXT,
sub_category TEXT, sub_category TEXT,
format TEXT MAPPED BY `const BangFormatConverter()`, format TEXT MAPPED BY `const BangFormatConverter()`,
additional_triggers TEXT MAPPED BY `const TriggerListConverter()`,
PRIMARY KEY ("trigger", "group") PRIMARY KEY ("trigger", "group")
) WITH Bang; ) WITH Bang;
CREATE TABLE bang_triggers (
"trigger" TEXT NOT NULL,
"group" ENUM(BangGroup) NOT NULL,
additional_trigger TEXT NOT NULL,
PRIMARY KEY ("trigger", "group", additional_trigger),
FOREIGN KEY ("trigger", "group") REFERENCES bang ("trigger", "group") ON DELETE CASCADE
);
CREATE INDEX idx_bang_triggers_lookup ON bang_triggers (additional_trigger, "group");
-- Trigger to populate bang_triggers when inserting a new bang
CREATE TRIGGER bang_triggers_after_insert AFTER INSERT ON bang
WHEN new.additional_triggers IS NOT NULL
BEGIN
INSERT INTO bang_triggers("trigger", "group", additional_trigger)
SELECT
new."trigger",
new."group",
json_each.value
FROM json_each(new.additional_triggers);
END;
-- Trigger to update bang_triggers when updating a bang
CREATE TRIGGER bang_triggers_after_update AFTER UPDATE ON bang BEGIN
-- Delete old additional triggers
DELETE FROM bang_triggers
WHERE "trigger" = old."trigger" AND "group" = old."group";
-- Insert new additional triggers if they exist
INSERT INTO bang_triggers("trigger", "group", additional_trigger)
SELECT
new."trigger",
new."group",
json_each.value
FROM json_each(new.additional_triggers)
WHERE new.additional_triggers IS NOT NULL;
END;
CREATE TABLE bang_sync ( CREATE TABLE bang_sync (
"group" ENUM(BangGroup) PRIMARY KEY NOT NULL, "group" ENUM(BangGroup) PRIMARY KEY NOT NULL,
last_sync DATETIME NOT NULL last_sync DATETIME NOT NULL
@@ -46,6 +85,13 @@ CREATE VIRTUAL TABLE bang_fts
prefix='2 3' prefix='2 3'
); );
CREATE VIRTUAL TABLE bang_triggers_fts
USING fts5(
additional_trigger,
content=bang_triggers,
prefix='2 3'
);
CREATE VIEW bang_data_view WITH BangData AS CREATE VIEW bang_data_view WITH BangData AS
SELECT SELECT
b.*, b.*,
@@ -76,59 +122,137 @@ CREATE TRIGGER bang_after_update AFTER UPDATE ON bang BEGIN
VALUES (new.rowid, new."trigger", new.website_name); VALUES (new.rowid, new."trigger", new.website_name);
END; END;
optimizeFtsIndex: CREATE TRIGGER bang_triggers_after_insert_fts AFTER INSERT ON bang_triggers BEGIN
INSERT INTO
bang_triggers_fts(rowid, additional_trigger)
VALUES (new.rowid, new.additional_trigger);
END;
CREATE TRIGGER bang_triggers_after_delete_fts AFTER DELETE ON bang_triggers BEGIN
INSERT INTO
bang_triggers_fts(bang_triggers_fts, rowid, additional_trigger)
VALUES('delete', old.rowid, old.additional_trigger);
END;
CREATE TRIGGER bang_triggers_after_update_fts AFTER UPDATE ON bang_triggers BEGIN
INSERT INTO
bang_triggers_fts(bang_triggers_fts, rowid, additional_trigger)
VALUES('delete', old.rowid, old.additional_trigger);
INSERT INTO
bang_triggers_fts(rowid, additional_trigger)
VALUES (new.rowid, new.additional_trigger);
END;
optimizeBangFtsIndex:
INSERT INTO bang_fts(bang_fts) VALUES ('optimize'); INSERT INTO bang_fts(bang_fts) VALUES ('optimize');
optimizeTriggerFtsIndex:
INSERT INTO bang_triggers_fts(bang_triggers_fts) VALUES ('optimize');
queryBangs WITH BangData: queryBangs WITH BangData:
WITH weights AS ( WITH weights AS (
SELECT SELECT
-- Customize these weights (higher = more important) 10.0 AS "trigger",
10.0 AS "trigger", -- Title matches are most important 8.0 AS additional_trigger,
5.0 AS website_name -- URL matches are quite important 5.0 AS website_name
),
bang_results AS (
SELECT
b.*,
bf.frequency,
bf.last_used,
bm25(bang_fts, weights."trigger", weights.website_name) AS weighted_rank
FROM
bang_fts(:query) fts
INNER JOIN
bang b ON b.rowid = fts.rowid
LEFT JOIN
bang_frequency bf ON b."trigger" = bf."trigger" AND b."group" = bf."group"
CROSS JOIN weights
),
trigger_results AS (
SELECT
b.*,
bf.frequency,
bf.last_used,
bm25(bang_triggers_fts, weights.additional_trigger) AS weighted_rank
FROM
bang_triggers_fts(:query) tfts
INNER JOIN
bang_triggers bt ON bt.rowid = tfts.rowid
INNER JOIN
bang b ON b."trigger" = bt."trigger" AND b."group" = bt."group"
LEFT JOIN
bang_frequency bf ON b."trigger" = bf."trigger" AND b."group" = bf."group"
CROSS JOIN weights
),
combined_results AS (
SELECT * FROM bang_results
UNION ALL
SELECT * FROM trigger_results
) )
SELECT SELECT
b.*, *,
bf.frequency, MIN(weighted_rank) AS weighted_rank
bf.last_used, FROM combined_results
bm25(bang_fts, weights."trigger", weights.website_name) AS weighted_rank GROUP BY "trigger", "group"
FROM
bang_fts(:query) fts
INNER JOIN
bang b ON b.rowid = fts.rowid
LEFT JOIN
bang_frequency bf ON b."trigger" = bf."trigger" AND b."group" = bf."group"
CROSS JOIN
weights
ORDER BY ORDER BY
weighted_rank ASC, weighted_rank ASC,
bf.frequency NULLS LAST; frequency NULLS LAST;
queryBangsBasic WITH BangData: queryBangsBasic WITH BangData:
WITH weights AS ( WITH weights AS (
SELECT SELECT
-- Customize these weights (higher = more important) 10.0 AS "trigger",
10.0 AS "trigger", -- Title matches are most important 8.0 AS additional_trigger,
5.0 AS website_name -- URL matches are quite important 5.0 AS website_name
),
bang_results AS (
SELECT
b.*,
bf.frequency,
bf.last_used,
bm25(bang_fts, weights."trigger", weights.website_name) AS weighted_rank
FROM
bang_fts fts
INNER JOIN
bang b ON b.rowid = fts.rowid
LEFT JOIN
bang_frequency bf ON b."trigger" = bf."trigger" AND b."group" = bf."group"
CROSS JOIN weights
WHERE
fts."trigger" LIKE :query OR
fts.website_name LIKE :query
),
trigger_results AS (
SELECT
b.*,
bf.frequency,
bf.last_used,
bm25(bang_triggers_fts, weights.additional_trigger) AS weighted_rank
FROM
bang_triggers_fts tfts
INNER JOIN
bang_triggers bt ON bt.rowid = tfts.rowid
INNER JOIN
bang b ON b."trigger" = bt."trigger" AND b."group" = bt."group"
LEFT JOIN
bang_frequency bf ON b."trigger" = bf."trigger" AND b."group" = bf."group"
CROSS JOIN weights
WHERE
tfts.additional_trigger LIKE :query
),
combined_results AS (
SELECT * FROM bang_results
UNION ALL
SELECT * FROM trigger_results
) )
SELECT SELECT
b.*, *,
bf.frequency, MIN(weighted_rank) AS weighted_rank
bf.last_used, FROM combined_results
bm25(bang_fts, weights."trigger", weights.website_name) AS weighted_rank GROUP BY "trigger", "group"
FROM
bang_fts fts
INNER JOIN
bang b ON b.rowid = fts.rowid
LEFT JOIN
bang_frequency bf ON b."trigger" = bf."trigger" AND b."group" = bf."group"
CROSS JOIN
weights
WHERE
fts."trigger" LIKE :query OR
fts.website_name LIKE :query
ORDER BY ORDER BY
weighted_rank ASC, weighted_rank ASC,
bf.frequency NULLS LAST; frequency NULLS LAST;
categoriesJson: categoriesJson:
WITH categories AS ( WITH categories AS (
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,20 @@
import 'dart:convert';
import 'package:drift/drift.dart';
import 'package:nullability/nullability.dart';
class TriggerListConverter extends TypeConverter<Set<String>?, String?> {
const TriggerListConverter();
@override
Set<String>? fromSql(String? fromDb) {
return fromDb.mapNotNull(
(value) => (jsonDecode(value) as List).cast<String>().toSet(),
);
}
@override
String? toSql(Set<String>? value) {
return value.mapNotNull((value) => jsonEncode(value.toList()));
}
}
@@ -79,6 +79,10 @@ class Bang with FastEquatable implements Insertable<Bang> {
@JsonKey(name: 'fmt') @JsonKey(name: 'fmt')
final Set<BangFormat>? format; final Set<BangFormat>? format;
///Additional triggers that invoke this bang
@JsonKey(name: 'ts')
final Set<String>? additionalTriggers;
String formatQuery(String input) { String formatQuery(String input) {
return (format == null || return (format == null ||
format!.contains(BangFormat.urlEncodePlaceholder) == true) format!.contains(BangFormat.urlEncodePlaceholder) == true)
@@ -121,6 +125,7 @@ class Bang with FastEquatable implements Insertable<Bang> {
this.category, this.category,
this.subCategory, this.subCategory,
this.format, this.format,
this.additionalTriggers,
}); });
factory Bang.fromJson(Map<String, dynamic> json) => _$BangFromJson(json); factory Bang.fromJson(Map<String, dynamic> json) => _$BangFromJson(json);
@@ -137,6 +142,7 @@ class Bang with FastEquatable implements Insertable<Bang> {
category, category,
subCategory, subCategory,
format, format,
additionalTriggers,
]; ];
@override @override
@@ -150,6 +156,7 @@ class Bang with FastEquatable implements Insertable<Bang> {
category: Value.absentIfNull(category), category: Value.absentIfNull(category),
subCategory: Value.absentIfNull(subCategory), subCategory: Value.absentIfNull(subCategory),
format: Value.absentIfNull(format), format: Value.absentIfNull(format),
additionalTriggers: Value.absentIfNull(additionalTriggers),
).toColumns(nullToAbsent); ).toColumns(nullToAbsent);
} }
} }
@@ -23,6 +23,8 @@ abstract class _$BangCWProxy {
Bang format(Set<BangFormat>? format); Bang format(Set<BangFormat>? format);
Bang additionalTriggers(Set<String>? additionalTriggers);
/// Creates a new instance with the provided field values. /// Creates a new instance with the provided field values.
/// Passing `null` to a nullable field nullifies it, while `null` for a non-nullable field is ignored. To update a single field use `Bang(...).copyWith.fieldName(value)`. /// Passing `null` to a nullable field nullifies it, while `null` for a non-nullable field is ignored. To update a single field use `Bang(...).copyWith.fieldName(value)`.
/// ///
@@ -39,6 +41,7 @@ abstract class _$BangCWProxy {
String? category, String? category,
String? subCategory, String? subCategory,
Set<BangFormat>? format, Set<BangFormat>? format,
Set<String>? additionalTriggers,
}); });
} }
@@ -73,6 +76,10 @@ class _$BangCWProxyImpl implements _$BangCWProxy {
@override @override
Bang format(Set<BangFormat>? format) => call(format: format); Bang format(Set<BangFormat>? format) => call(format: format);
@override
Bang additionalTriggers(Set<String>? additionalTriggers) =>
call(additionalTriggers: additionalTriggers);
@override @override
/// Creates a new instance with the provided field values. /// Creates a new instance with the provided field values.
/// Passing `null` to a nullable field nullifies it, while `null` for a non-nullable field is ignored. To update a single field use `Bang(...).copyWith.fieldName(value)`. /// Passing `null` to a nullable field nullifies it, while `null` for a non-nullable field is ignored. To update a single field use `Bang(...).copyWith.fieldName(value)`.
@@ -90,6 +97,7 @@ class _$BangCWProxyImpl implements _$BangCWProxy {
Object? category = const $CopyWithPlaceholder(), Object? category = const $CopyWithPlaceholder(),
Object? subCategory = const $CopyWithPlaceholder(), Object? subCategory = const $CopyWithPlaceholder(),
Object? format = const $CopyWithPlaceholder(), Object? format = const $CopyWithPlaceholder(),
Object? additionalTriggers = const $CopyWithPlaceholder(),
}) { }) {
return Bang( return Bang(
websiteName: websiteName:
@@ -126,6 +134,10 @@ class _$BangCWProxyImpl implements _$BangCWProxy {
? _value.format ? _value.format
// ignore: cast_nullable_to_non_nullable // ignore: cast_nullable_to_non_nullable
: format as Set<BangFormat>?, : format as Set<BangFormat>?,
additionalTriggers: additionalTriggers == const $CopyWithPlaceholder()
? _value.additionalTriggers
// ignore: cast_nullable_to_non_nullable
: additionalTriggers as Set<String>?,
); );
} }
} }
@@ -151,6 +163,9 @@ Bang _$BangFromJson(Map<String, dynamic> json) => Bang(
format: (json['fmt'] as List<dynamic>?) format: (json['fmt'] as List<dynamic>?)
?.map((e) => $enumDecode(_$BangFormatEnumMap, e)) ?.map((e) => $enumDecode(_$BangFormatEnumMap, e))
.toSet(), .toSet(),
additionalTriggers: (json['ts'] as List<dynamic>?)
?.map((e) => e as String)
.toSet(),
); );
Map<String, dynamic> _$BangToJson(Bang instance) => <String, dynamic>{ Map<String, dynamic> _$BangToJson(Bang instance) => <String, dynamic>{
@@ -161,6 +176,7 @@ Map<String, dynamic> _$BangToJson(Bang instance) => <String, dynamic>{
'c': instance.category, 'c': instance.category,
'sc': instance.subCategory, 'sc': instance.subCategory,
'fmt': instance.format?.map((e) => _$BangFormatEnumMap[e]!).toList(), 'fmt': instance.format?.map((e) => _$BangFormatEnumMap[e]!).toList(),
'ts': instance.additionalTriggers?.toList(),
}; };
const _$BangFormatEnumMap = { const _$BangFormatEnumMap = {
@@ -44,6 +44,7 @@ class BangData extends Bang {
super.category, super.category,
super.subCategory, super.subCategory,
super.format, super.format,
super.additionalTriggers,
int? frequency, int? frequency,
this.lastUsed, this.lastUsed,
this.icon, this.icon,
@@ -58,6 +59,7 @@ class BangData extends Bang {
super.category, super.category,
super.subCategory, super.subCategory,
super.format, super.format,
super.additionalTriggers,
int? frequency, int? frequency,
this.lastUsed, this.lastUsed,
this.icon, this.icon,
@@ -21,6 +21,8 @@ abstract class _$BangDataCWProxy {
BangData format(Set<BangFormat>? format); BangData format(Set<BangFormat>? format);
BangData additionalTriggers(Set<String>? additionalTriggers);
BangData frequency(int? frequency); BangData frequency(int? frequency);
BangData lastUsed(DateTime? lastUsed); BangData lastUsed(DateTime? lastUsed);
@@ -42,6 +44,7 @@ abstract class _$BangDataCWProxy {
String? category, String? category,
String? subCategory, String? subCategory,
Set<BangFormat>? format, Set<BangFormat>? format,
Set<String>? additionalTriggers,
int? frequency, int? frequency,
DateTime? lastUsed, DateTime? lastUsed,
BrowserIcon? icon, BrowserIcon? icon,
@@ -76,6 +79,10 @@ class _$BangDataCWProxyImpl implements _$BangDataCWProxy {
@override @override
BangData format(Set<BangFormat>? format) => call(format: format); BangData format(Set<BangFormat>? format) => call(format: format);
@override
BangData additionalTriggers(Set<String>? additionalTriggers) =>
call(additionalTriggers: additionalTriggers);
@override @override
BangData frequency(int? frequency) => call(frequency: frequency); BangData frequency(int? frequency) => call(frequency: frequency);
@@ -101,6 +108,7 @@ class _$BangDataCWProxyImpl implements _$BangDataCWProxy {
Object? category = const $CopyWithPlaceholder(), Object? category = const $CopyWithPlaceholder(),
Object? subCategory = const $CopyWithPlaceholder(), Object? subCategory = const $CopyWithPlaceholder(),
Object? format = const $CopyWithPlaceholder(), Object? format = const $CopyWithPlaceholder(),
Object? additionalTriggers = const $CopyWithPlaceholder(),
Object? frequency = const $CopyWithPlaceholder(), Object? frequency = const $CopyWithPlaceholder(),
Object? lastUsed = const $CopyWithPlaceholder(), Object? lastUsed = const $CopyWithPlaceholder(),
Object? icon = const $CopyWithPlaceholder(), Object? icon = const $CopyWithPlaceholder(),
@@ -136,6 +144,10 @@ class _$BangDataCWProxyImpl implements _$BangDataCWProxy {
? _value.format ? _value.format
// ignore: cast_nullable_to_non_nullable // ignore: cast_nullable_to_non_nullable
: format as Set<BangFormat>?, : format as Set<BangFormat>?,
additionalTriggers: additionalTriggers == const $CopyWithPlaceholder()
? _value.additionalTriggers
// ignore: cast_nullable_to_non_nullable
: additionalTriggers as Set<String>?,
frequency: frequency == const $CopyWithPlaceholder() frequency: frequency == const $CopyWithPlaceholder()
? _value.frequency ? _value.frequency
// ignore: cast_nullable_to_non_nullable // ignore: cast_nullable_to_non_nullable
+1 -1
View File
@@ -36,7 +36,7 @@ BangDatabase bangDatabase(Ref ref) {
// put the database file, called db.sqlite here, into the documents folder // put the database file, called db.sqlite here, into the documents folder
// for your app. // for your app.
final dbFolder = await path_provider.getApplicationDocumentsDirectory(); final dbFolder = await path_provider.getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'bang2.db')); final file = File(p.join(dbFolder.path, 'bang3.db'));
// Also work around limitations on old Android versions // Also work around limitations on old Android versions
if (Platform.isAndroid) { if (Platform.isAndroid) {
+1 -1
View File
@@ -48,4 +48,4 @@ final class BangDatabaseProvider
} }
} }
String _$bangDatabaseHash() => r'35142ef6c747e7c65c3417a2b6fc1c6f41d0411b'; String _$bangDatabaseHash() => r'e46ec1582f1a21337a302bef1b7963c2e11468d9';
@@ -54,7 +54,8 @@ class BangSyncRepository extends _$BangSyncRepository {
remoteBangs: remoteBangs, remoteBangs: remoteBangs,
syncTime: DateTime.now(), syncTime: DateTime.now(),
); );
await db.definitionsDrift.optimizeFtsIndex(); await db.definitionsDrift.optimizeBangFtsIndex();
await db.definitionsDrift.optimizeTriggerFtsIndex();
}); });
} }
@@ -84,7 +85,8 @@ class BangSyncRepository extends _$BangSyncRepository {
remoteBangs: remoteBangs, remoteBangs: remoteBangs,
syncTime: sourceDate, syncTime: sourceDate,
); );
await db.definitionsDrift.optimizeFtsIndex(); await db.definitionsDrift.optimizeBangFtsIndex();
await db.definitionsDrift.optimizeTriggerFtsIndex();
}); });
} }
@@ -42,7 +42,7 @@ final class BangSyncRepositoryProvider
} }
String _$bangSyncRepositoryHash() => String _$bangSyncRepositoryHash() =>
r'bb977652087d2ff2cb75b093adcfc45dafa21d2a'; r'e3ce355e5332ff1fe7ac8ecaa277a431b74f2da0';
abstract class _$BangSyncRepository extends $Notifier<void> { abstract class _$BangSyncRepository extends $Notifier<void> {
void build(); void build();
@@ -19,6 +19,7 @@
*/ */
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:nullability/nullability.dart';
import 'package:weblibre/core/routing/routes.dart'; import 'package:weblibre/core/routing/routes.dart';
import 'package:weblibre/features/bangs/data/models/bang_data.dart'; import 'package:weblibre/features/bangs/data/models/bang_data.dart';
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart'; import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
@@ -106,12 +107,16 @@ class BangDetails extends HookConsumerWidget {
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded( Expanded(
child: Text( child: Tooltip(
'!${bangData.trigger}', message:
style: theme.textTheme.titleSmall, 'Triggers: ${bangData.trigger}${bangData.additionalTriggers.mapNotNull((triggers) => ', ${triggers.map((trigger) => '!$trigger').join(', ')}') ?? ''}',
textAlign: TextAlign.right, child: Text(
maxLines: 2, '!${bangData.trigger}',
overflow: TextOverflow.ellipsis, style: theme.textTheme.titleSmall,
textAlign: TextAlign.right,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
), ),
), ),
], ],