Add Supa account and search changes
This commit is contained in:
+157
-130
@@ -22,6 +22,7 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:nullability/nullability.dart';
|
||||
import 'package:weblibre/features/settings/presentation/controllers/save_settings.dart';
|
||||
import 'package:weblibre/features/settings/presentation/widgets/settings_detail.dart';
|
||||
import 'package:weblibre/features/user/data/models/engine_settings.dart';
|
||||
import 'package:weblibre/features/user/domain/entities/fingerprint_overrides.dart';
|
||||
import 'package:weblibre/features/user/domain/providers.dart';
|
||||
@@ -35,146 +36,172 @@ class FingerprintSettingsScreen extends HookConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final targetsAsync = ref.watch(fingerprintTargetsProvider);
|
||||
final settingsAsync = ref.watch(fingerprintOverrideSettingsProvider);
|
||||
final search = useSettingsSearch();
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Fingerprint Protection'),
|
||||
actions: [
|
||||
MenuAnchor(
|
||||
builder: (context, controller, child) {
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
if (controller.isOpen) {
|
||||
controller.close();
|
||||
} else {
|
||||
controller.open();
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.more_vert),
|
||||
);
|
||||
},
|
||||
menuChildren: [
|
||||
MenuItemButton(
|
||||
leadingIcon: const Icon(MdiIcons.restore),
|
||||
child: const Text('Load Defaults'),
|
||||
onPressed: () async {
|
||||
await ref
|
||||
.read(saveEngineSettingsControllerProvider.notifier)
|
||||
.save(
|
||||
(currentSettings) => currentSettings.copyWith
|
||||
.fingerprintingProtectionOverrides(
|
||||
FingerprintOverrides.defaults().toString(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
MenuItemButton(
|
||||
leadingIcon: const Icon(MdiIcons.restore),
|
||||
child: const Text('Load Hardened Defaults'),
|
||||
onPressed: () async {
|
||||
await ref
|
||||
.read(saveEngineSettingsControllerProvider.notifier)
|
||||
.save(
|
||||
(currentSettings) => currentSettings.copyWith
|
||||
.fingerprintingProtectionOverrides(
|
||||
FingerprintOverrides.hardenedDefaults()
|
||||
.toString(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
body: SafeArea(
|
||||
child: settingsAsync.when(
|
||||
skipLoadingOnReload: true,
|
||||
data: (result) {
|
||||
return result.fold(
|
||||
(overrides) {
|
||||
return targetsAsync.when(
|
||||
skipLoadingOnReload: true,
|
||||
data: (targets) {
|
||||
return ListView.builder(
|
||||
itemCount: targets.length,
|
||||
itemBuilder: (context, index) {
|
||||
final target = targets[index];
|
||||
final state = overrides.targets[target.name];
|
||||
|
||||
return CheckboxListTile.adaptive(
|
||||
value:
|
||||
(overrides.allTargets == true &&
|
||||
state != false) ||
|
||||
state == true,
|
||||
onChanged: (value) async {
|
||||
if (value != null) {
|
||||
final newOverrides = overrides
|
||||
.copyWithTarget(target.name, value)
|
||||
.toString();
|
||||
|
||||
await ref
|
||||
.read(
|
||||
saveEngineSettingsControllerProvider
|
||||
.notifier,
|
||||
)
|
||||
.save(
|
||||
(currentSettings) => currentSettings
|
||||
.copyWith
|
||||
.fingerprintingProtectionOverrides(
|
||||
newOverrides,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
title: Text(target.name),
|
||||
subtitle: target.description.mapNotNull(
|
||||
(desc) => Text(desc),
|
||||
return SettingsCustomScrollScaffold(
|
||||
title: 'Fingerprint Protection',
|
||||
searchController: search.controller,
|
||||
searchHintText: 'Search fingerprint override targets',
|
||||
actions: [
|
||||
MenuAnchor(
|
||||
builder: (context, controller, child) {
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
if (controller.isOpen) {
|
||||
controller.close();
|
||||
} else {
|
||||
controller.open();
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.more_vert),
|
||||
);
|
||||
},
|
||||
menuChildren: [
|
||||
MenuItemButton(
|
||||
leadingIcon: const Icon(MdiIcons.restore),
|
||||
child: const Text('Load Defaults'),
|
||||
onPressed: () async {
|
||||
await ref
|
||||
.read(saveEngineSettingsControllerProvider.notifier)
|
||||
.save(
|
||||
(currentSettings) => currentSettings.copyWith
|
||||
.fingerprintingProtectionOverrides(
|
||||
FingerprintOverrides.defaults().toString(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
MenuItemButton(
|
||||
leadingIcon: const Icon(MdiIcons.restore),
|
||||
child: const Text('Load Hardened Defaults'),
|
||||
onPressed: () async {
|
||||
await ref
|
||||
.read(saveEngineSettingsControllerProvider.notifier)
|
||||
.save(
|
||||
(currentSettings) => currentSettings.copyWith
|
||||
.fingerprintingProtectionOverrides(
|
||||
FingerprintOverrides.hardenedDefaults().toString(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
slivers: [
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 24, 16, 20),
|
||||
sliver: SliverToBoxAdapter(
|
||||
child: settingsAsync.when(
|
||||
skipLoadingOnReload: true,
|
||||
data: (result) {
|
||||
return result.fold(
|
||||
(overrides) {
|
||||
return targetsAsync.when(
|
||||
skipLoadingOnReload: true,
|
||||
data: (targets) {
|
||||
final filteredTargets = targets.where((target) {
|
||||
if (search.normalizedQuery.isEmpty) return true;
|
||||
return matchesSettingsSearch(search.normalizedQuery, [
|
||||
target.name,
|
||||
if (target.description != null) target.description!,
|
||||
]);
|
||||
}).toList();
|
||||
|
||||
return SettingsSectionList(
|
||||
sections: filteredTargets.isEmpty
|
||||
? const []
|
||||
: [
|
||||
SettingsSectionDefinition(
|
||||
title: 'Override Targets',
|
||||
entries: [
|
||||
for (final target in filteredTargets)
|
||||
SettingsEntryDefinition(
|
||||
title: target.name,
|
||||
subtitle: target.description,
|
||||
child: CheckboxListTile.adaptive(
|
||||
value:
|
||||
(overrides.allTargets == true &&
|
||||
overrides.targets[target
|
||||
.name] !=
|
||||
false) ||
|
||||
overrides.targets[target
|
||||
.name] ==
|
||||
true,
|
||||
onChanged: (value) async {
|
||||
if (value != null) {
|
||||
final newOverrides = overrides
|
||||
.copyWithTarget(
|
||||
target.name,
|
||||
value,
|
||||
)
|
||||
.toString();
|
||||
|
||||
await ref
|
||||
.read(
|
||||
saveEngineSettingsControllerProvider
|
||||
.notifier,
|
||||
)
|
||||
.save(
|
||||
(
|
||||
currentSettings,
|
||||
) => currentSettings
|
||||
.copyWith
|
||||
.fingerprintingProtectionOverrides(
|
||||
newOverrides,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
title: Text(target.name),
|
||||
subtitle: target.description
|
||||
.mapNotNull(
|
||||
(desc) => Text(desc),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
query: search.rawQuery,
|
||||
);
|
||||
},
|
||||
error: (error, stackTrace) {
|
||||
return FailureWidget(
|
||||
exception: error,
|
||||
onRetry: () {
|
||||
ref.invalidate(fingerprintTargetsProvider);
|
||||
},
|
||||
);
|
||||
},
|
||||
loading: () =>
|
||||
const Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
},
|
||||
onFailure: (errorMessage) {
|
||||
return FailureWidget(
|
||||
title: errorMessage.message,
|
||||
exception: errorMessage.details,
|
||||
onRetry: () {
|
||||
ref.invalidate(fingerprintOverrideSettingsProvider);
|
||||
},
|
||||
);
|
||||
},
|
||||
error: (error, stackTrace) {
|
||||
return Center(
|
||||
child: FailureWidget(
|
||||
exception: error,
|
||||
onRetry: () {
|
||||
ref.invalidate(fingerprintTargetsProvider);
|
||||
},
|
||||
),
|
||||
);
|
||||
);
|
||||
},
|
||||
error: (error, stackTrace) {
|
||||
return FailureWidget(
|
||||
exception: error,
|
||||
onRetry: () {
|
||||
ref.invalidate(fingerprintOverrideSettingsProvider);
|
||||
},
|
||||
loading: () =>
|
||||
const Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
},
|
||||
onFailure: (errorMessage) {
|
||||
return Center(
|
||||
child: FailureWidget(
|
||||
title: errorMessage.message,
|
||||
exception: errorMessage.details,
|
||||
onRetry: () {
|
||||
ref.invalidate(fingerprintOverrideSettingsProvider);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
error: (error, stackTrace) {
|
||||
return Center(
|
||||
child: FailureWidget(
|
||||
exception: error,
|
||||
onRetry: () {
|
||||
ref.invalidate(fingerprintOverrideSettingsProvider);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user