support bang additional triggers
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user