added feature to configure contextual tab bar buttons

This commit is contained in:
Fabian Freund
2026-03-11 10:44:56 +01:00
parent 7121b1c236
commit 4f2145dfc2
34 changed files with 4331 additions and 313 deletions
@@ -0,0 +1,298 @@
{
"_meta": {
"description": "This file contains a serialized version of schema entities for drift.",
"version": "1.3.0"
},
"options": {
"store_date_time_values_as_text": false
},
"entities": [
{
"id": 0,
"references": [],
"type": "table",
"data": {
"name": "setting",
"was_declared_in_moor": true,
"columns": [
{
"name": "key",
"getter_name": "key",
"moor_type": "string",
"nullable": false,
"customConstraints": "PRIMARY KEY NOT NULL",
"default_dart": null,
"default_client_dart": null,
"dsl_features": [
"primary-key"
]
},
{
"name": "partition_key",
"getter_name": "partitionKey",
"moor_type": "string",
"nullable": true,
"customConstraints": "",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "value",
"getter_name": "value",
"moor_type": "any",
"nullable": true,
"customConstraints": "",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
}
],
"is_virtual": false,
"without_rowid": false,
"constraints": [],
"strict": true
}
},
{
"id": 1,
"references": [],
"type": "table",
"data": {
"name": "icon_cache",
"was_declared_in_moor": true,
"columns": [
{
"name": "origin",
"getter_name": "origin",
"moor_type": "string",
"nullable": false,
"customConstraints": "PRIMARY KEY NOT NULL",
"default_dart": null,
"default_client_dart": null,
"dsl_features": [
"primary-key"
]
},
{
"name": "icon_data",
"getter_name": "iconData",
"moor_type": "blob",
"nullable": false,
"customConstraints": "NOT NULL",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "fetch_date",
"getter_name": "fetchDate",
"moor_type": "dateTime",
"nullable": false,
"customConstraints": "NOT NULL",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
}
],
"is_virtual": false,
"without_rowid": false,
"constraints": []
}
},
{
"id": 2,
"references": [],
"type": "table",
"data": {
"name": "onboarding",
"was_declared_in_moor": true,
"columns": [
{
"name": "revision",
"getter_name": "revision",
"moor_type": "int",
"nullable": false,
"customConstraints": "NOT NULL",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "completion_date",
"getter_name": "completionDate",
"moor_type": "dateTime",
"nullable": false,
"customConstraints": "NOT NULL",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
}
],
"is_virtual": false,
"without_rowid": false,
"constraints": []
}
},
{
"id": 3,
"references": [],
"type": "table",
"data": {
"name": "riverpod",
"was_declared_in_moor": true,
"columns": [
{
"name": "key",
"getter_name": "key",
"moor_type": "string",
"nullable": false,
"customConstraints": "PRIMARY KEY NOT NULL",
"default_dart": null,
"default_client_dart": null,
"dsl_features": [
"primary-key"
]
},
{
"name": "json",
"getter_name": "json",
"moor_type": "string",
"nullable": false,
"customConstraints": "NOT NULL",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "expireAt",
"getter_name": "expireAt",
"moor_type": "dateTime",
"nullable": true,
"customConstraints": "",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "destroyKey",
"getter_name": "destroyKey",
"moor_type": "string",
"nullable": true,
"customConstraints": "",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
}
],
"is_virtual": false,
"without_rowid": true,
"constraints": []
}
},
{
"id": 4,
"references": [],
"type": "table",
"data": {
"name": "toolbar_button_configs",
"was_declared_in_moor": true,
"columns": [
{
"name": "button_id",
"getter_name": "buttonId",
"moor_type": "string",
"nullable": false,
"customConstraints": "NOT NULL PRIMARY KEY",
"default_dart": null,
"default_client_dart": null,
"dsl_features": [
"primary-key"
]
},
{
"name": "order_key",
"getter_name": "orderKey",
"moor_type": "string",
"nullable": false,
"customConstraints": "NOT NULL",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "is_visible",
"getter_name": "isVisible",
"moor_type": "int",
"nullable": false,
"customConstraints": "NOT NULL DEFAULT 1",
"default_dart": "const CustomExpression('1')",
"default_client_dart": null,
"dsl_features": []
},
{
"name": "fallback_id",
"getter_name": "fallbackId",
"moor_type": "string",
"nullable": true,
"customConstraints": "",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
}
],
"is_virtual": false,
"without_rowid": false,
"constraints": [],
"strict": true
}
}
],
"fixed_sql": [
{
"name": "setting",
"sql": [
{
"dialect": "sqlite",
"sql": "CREATE TABLE IF NOT EXISTS \"setting\" (\"key\" TEXT PRIMARY KEY NOT NULL, \"partition_key\" TEXT, \"value\" ANY) STRICT;"
}
]
},
{
"name": "icon_cache",
"sql": [
{
"dialect": "sqlite",
"sql": "CREATE TABLE IF NOT EXISTS \"icon_cache\" (\"origin\" TEXT PRIMARY KEY NOT NULL, \"icon_data\" BLOB NOT NULL, \"fetch_date\" INTEGER NOT NULL);"
}
]
},
{
"name": "onboarding",
"sql": [
{
"dialect": "sqlite",
"sql": "CREATE TABLE IF NOT EXISTS \"onboarding\" (\"revision\" INTEGER NOT NULL, \"completion_date\" INTEGER NOT NULL);"
}
]
},
{
"name": "riverpod",
"sql": [
{
"dialect": "sqlite",
"sql": "CREATE TABLE IF NOT EXISTS \"riverpod\" (\"key\" TEXT PRIMARY KEY NOT NULL, \"json\" TEXT NOT NULL, \"expireAt\" INTEGER, \"destroyKey\" TEXT) WITHOUT ROWID;"
}
]
},
{
"name": "toolbar_button_configs",
"sql": [
{
"dialect": "sqlite",
"sql": "CREATE TABLE IF NOT EXISTS \"toolbar_button_configs\" (\"button_id\" TEXT NOT NULL PRIMARY KEY, \"order_key\" TEXT NOT NULL, \"is_visible\" INTEGER NOT NULL DEFAULT 1, \"fallback_id\" TEXT) STRICT;"
}
]
}
]
}
+4 -1
View File
@@ -6,6 +6,7 @@ import 'package:drift/drift.dart';
import 'package:drift/internal/migrations.dart';
import 'schema_v1.dart' as v1;
import 'schema_v2.dart' as v2;
import 'schema_v3.dart' as v3;
class GeneratedHelper implements SchemaInstantiationHelper {
@override
@@ -15,10 +16,12 @@ class GeneratedHelper implements SchemaInstantiationHelper {
return v1.DatabaseAtV1(db);
case 2:
return v2.DatabaseAtV2(db);
case 3:
return v3.DatabaseAtV3(db);
default:
throw MissingSchemaException(version, versions);
}
}
static const versions = const [1, 2];
static const versions = const [1, 2, 3];
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,69 @@
import 'package:drift/native.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:weblibre/data/database/functions/lexo_rank_functions.dart';
import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/data/providers/toolbar_button_configs.dart';
import 'package:weblibre/features/user/data/database/database.dart';
void main() {
late UserDatabase db;
setUp(() {
db = UserDatabase(
NativeDatabase.memory(
setup: (database) {
registerLexorankFunctions(database);
},
),
);
});
tearDown(() async {
await db.close();
});
group('ToolbarButtonConfigDao', () {
test(
'seedMissing inserts self-referential fallback rows in two phases',
() async {
await db.toolbarButtonConfigDao.seedMissing([
(
buttonId: 'back',
defaultVisible: true,
defaultFallback: 'bookmarks',
),
(buttonId: 'bookmarks', defaultVisible: false, defaultFallback: null),
(buttonId: 'forward', defaultVisible: true, defaultFallback: 'share'),
(buttonId: 'share', defaultVisible: false, defaultFallback: null),
]);
final configs = await db.toolbarButtonConfigDao.getAll();
final configsById = {
for (final config in configs) config.buttonId: config,
};
expect(configsById['back']?.fallbackId, 'bookmarks');
expect(configsById['forward']?.fallbackId, 'share');
},
);
test(
'replaceAll persists default toolbar fallbacks without FK failures',
() async {
await expectLater(
db.toolbarButtonConfigDao.replaceAll(
buildDefaultToolbarButtonConfigs(),
),
completes,
);
final configs = await db.toolbarButtonConfigDao.getAll();
final configsById = {
for (final config in configs) config.buttonId: config,
};
expect(configsById['back']?.fallbackId, 'bookmarks');
expect(configsById['forward']?.fallbackId, 'share');
},
);
});
}
+1
View File
@@ -34,6 +34,7 @@ void main() {
);
test('forces animations off when the app setting is enabled', () {
// ignore: avoid_redundant_argument_values
const mediaQuery = MediaQueryData(disableAnimations: false);
final result = applyAppMediaQueryOverrides(