feat(views)!: set DNS, NTP, sniffer and TUN key by key

BREAKING CHANGE: DNS and NTP override toggles are removed; picked keys apply to every profile
Changelog: Per-key DNS, NTP, sniffer and TUN settings
This commit is contained in:
chen08209
2026-10-08 17:58:43 +08:00
parent 3abda78af4
commit 491fae10f5
165 changed files with 12012 additions and 4717 deletions
+21
View File
@@ -588,6 +588,21 @@ void main() {
expect(await database.disabledRules.count.getSingle(), 0);
});
test('a custom proxy keeps the options added without a value', () async {
const proxy = CustomProxy(
id: 30,
definition: {'name': 'Home', 'type': 'trojan'},
emptyOptions: {ProxyField.sni, ProxyField.alpn},
);
await database.customProxiesDao.order(proxy: proxy, order: 'a0');
expect(
await database.customProxiesDao.query().getSingle(),
proxy.copyWith(order: 'a0'),
);
});
test(
'dialers follow their profile and proxy and survive a restore',
() async {
@@ -662,7 +677,9 @@ void main() {
id: id,
name: 'Group',
type: GroupType.Selector,
proxies: const ['DIRECT'],
use: const [oldName, 'Old', 'Kept'],
usePosition: const {oldName: 0, 'Kept': 0},
).toCompanion(id),
);
await database.rulesDao.putRule(
@@ -698,8 +715,12 @@ void main() {
(await database.rulesDao.queryProfileRules(id).get())
.single
.ruleProvider;
Future<Map<String, int>?> usePosition(int id) async =>
(await database.proxyGroupsDao.query(id).get()).single.usePosition;
expect(await use(1), [newName, 'Old', 'Kept']);
expect(await use(2), [oldName, 'Old', 'Kept']);
expect(await usePosition(1), {newName: 0, 'Kept': 0});
expect(await usePosition(2), {oldName: 0, 'Kept': 0});
expect(await ruleSet(1), newName);
expect(await ruleSet(2), oldName);
});
+45 -20
View File
@@ -85,8 +85,15 @@ void _downgradeToV7(Database raw) {
raw.execute('PRAGMA user_version = 7');
}
/// Schema version 19 had no `empty_options` on `custom_proxies`.
void _downgradeToV19(Database raw) {
raw.execute('ALTER TABLE custom_proxies DROP COLUMN empty_options');
raw.execute('PRAGMA user_version = 19');
}
/// Schema version 18 had no `age_secret_key` on `profiles`.
void _downgradeToV18(Database raw) {
_downgradeToV19(raw);
raw.execute('ALTER TABLE profiles DROP COLUMN age_secret_key');
raw.execute('PRAGMA user_version = 18');
}
@@ -267,7 +274,7 @@ void main() {
await openAndMigrate();
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
});
test('the v3 upgrade adds match_target to profiles', () async {
@@ -277,7 +284,7 @@ void main() {
await openAndMigrate();
expect(_columnsOf(raw, 'profiles'), contains('match_target'));
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
});
test('the v4 upgrade adds url to scripts', () async {
@@ -291,7 +298,7 @@ void main() {
final database = await openAndMigrate();
expect(_columnsOf(raw, 'scripts'), contains('url'));
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
final scripts = await database.scriptsDao.query().get();
expect(scripts.single.label, 'Local');
expect(scripts.single.url, isNull);
@@ -308,7 +315,7 @@ void main() {
final database = await openAndMigrate();
expect(_columnsOf(raw, 'scripts'), contains('order'));
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
final scripts = await database.scriptsDao.query().get();
expect(scripts.map((item) => item.label), ['First', 'Second']);
expect(scripts.map((item) => item.order), [null, null]);
@@ -323,7 +330,7 @@ void main() {
await openAndMigrate();
expect(_columnsOf(raw, 'profiles'), contains('match_target'));
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
},
);
@@ -334,7 +341,7 @@ void main() {
final database = await openAndMigrate();
expect(_hasTable(raw, 'clash_providers'), isTrue);
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
expect(await database.clashProvidersDao.query().get(), isEmpty);
});
@@ -347,7 +354,7 @@ void main() {
await openAndMigrate();
expect(_hasTable(raw, 'clash_providers'), isTrue);
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
},
);
@@ -358,7 +365,7 @@ void main() {
await openAndMigrate();
expect(_columnsOf(raw, 'proxy_groups'), contains('definition'));
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
});
test('a v6 user_version on the current proxy_groups still opens', () async {
@@ -368,7 +375,7 @@ void main() {
await openAndMigrate();
expect(_columnsOf(raw, 'proxy_groups'), contains('definition'));
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
});
test(
@@ -392,7 +399,7 @@ void main() {
_columnsOf(raw, 'clash_providers'),
isNot(anyOf(contains('interval'), contains('filter'))),
);
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
expect(
(await database.clashProvidersDao.query().get()).single.label,
'Kept',
@@ -499,7 +506,7 @@ void main() {
final database = await openAndMigrate();
expect(_hasTable(raw, 'custom_proxies'), isTrue);
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
expect(await database.customProxiesDao.query().get(), isEmpty);
});
@@ -510,7 +517,7 @@ void main() {
expect(_columnsOf(raw, 'proxy_groups'), contains('definition'));
expect(_columnsOf(raw, 'proxy_groups'), isNot(contains('url')));
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
});
test('the v17 upgrade renames overwrite_type and adds overrides', () async {
@@ -580,7 +587,7 @@ void main() {
final database = await openAndMigrate();
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
expect(_hasTable(raw, 'profile_rule_mapping'), isFalse);
expect(
{
@@ -741,7 +748,7 @@ void main() {
final database = await openAndMigrate();
expect(_hasTable(raw, 'proxy_dialers'), isTrue);
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
expect(await database.proxyDialersDao.query(1).get(), isEmpty);
});
@@ -753,7 +760,7 @@ void main() {
expect(_hasTable(raw, 'icon_sets'), isTrue);
expect(_columnsOf(raw, 'icon_sets'), contains('last_update_time'));
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
expect(await database.iconSetsDao.query().get(), isEmpty);
});
@@ -766,7 +773,7 @@ void main() {
final database = await openAndMigrate();
expect(_columnsOf(raw, 'icon_sets'), contains('last_update_time'));
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
expect(await database.iconSetsDao.query().get(), isEmpty);
},
);
@@ -847,13 +854,31 @@ void main() {
final database = await openAndMigrate();
expect(_columnsOf(raw, 'profiles'), contains('age_secret_key'));
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
expect(
(await database.profilesDao.query().get()).single.ageSecretKey,
isEmpty,
);
});
test('the v20 upgrade adds empty_options to custom_proxies', () async {
_downgradeToV19(raw);
raw.execute(
'INSERT INTO custom_proxies (id, definition) '
'''VALUES (1, '{"name":"App","type":"ss"}')''',
);
expect(_columnsOf(raw, 'custom_proxies'), isNot(contains('empty_options')));
final database = await openAndMigrate();
expect(_columnsOf(raw, 'custom_proxies'), contains('empty_options'));
expect(_userVersion(raw), 20);
expect(
(await database.customProxiesDao.query().get()).single.emptyOptions,
isEmpty,
);
});
test(
'a v17 user_version with definition already present still opens',
() async {
@@ -870,7 +895,7 @@ void main() {
final database = await openAndMigrate();
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
expect(
(await database.proxyGroupsDao.query(3).get()).single.hidden,
isTrue,
@@ -883,7 +908,7 @@ void main() {
final database = await openAndMigrate();
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
expect(await database.customSelect('SELECT * FROM rules').get(), isEmpty);
});
@@ -893,7 +918,7 @@ void main() {
await openAndMigrate();
expect(_columnsOf(raw, 'rules'), before);
expect(_userVersion(raw), 19);
expect(_userVersion(raw), 20);
expect(_hasTable(raw, 'proxy_groups'), isTrue);
});
}