added bang settings
This commit is contained in:
Binary file not shown.
@@ -1,19 +1,40 @@
|
|||||||
|
import 'package:bang_navigator/core/extension/date_time.dart';
|
||||||
|
import 'package:bang_navigator/features/bangs/data/models/bang.dart';
|
||||||
|
import 'package:bang_navigator/features/bangs/domain/providers.dart';
|
||||||
|
import 'package:bang_navigator/features/bangs/domain/repositories/bang_data.dart';
|
||||||
|
import 'package:bang_navigator/features/bangs/domain/repositories/sync.dart';
|
||||||
import 'package:bang_navigator/features/settings/data/models/settings.dart';
|
import 'package:bang_navigator/features/settings/data/models/settings.dart';
|
||||||
import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart';
|
import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart';
|
||||||
import 'package:bang_navigator/features/settings/presentation/controllers/save_settings.dart';
|
import 'package:bang_navigator/features/settings/presentation/controllers/save_settings.dart';
|
||||||
|
import 'package:bang_navigator/features/settings/presentation/widgets/button_list_tile.dart';
|
||||||
import 'package:bang_navigator/features/settings/utils/session_link_extractor.dart';
|
import 'package:bang_navigator/features/settings/utils/session_link_extractor.dart';
|
||||||
import 'package:bang_navigator/presentation/hooks/listenable_callback.dart';
|
import 'package:bang_navigator/presentation/hooks/listenable_callback.dart';
|
||||||
import 'package:bang_navigator/utils/ui_helper.dart' as ui_helper;
|
import 'package:bang_navigator/utils/ui_helper.dart' as ui_helper;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
class SettingsScreen extends HookConsumerWidget {
|
class SettingsScreen extends HookConsumerWidget {
|
||||||
const SettingsScreen({super.key});
|
const SettingsScreen({super.key});
|
||||||
|
|
||||||
|
Widget _buildSection(ThemeData theme, String name) => Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(name, style: theme.textTheme.titleLarge),
|
||||||
|
const Divider(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
final kagiSessionTextController = useTextEditingController(
|
final kagiSessionTextController = useTextEditingController(
|
||||||
text: ref.read(
|
text: ref.read(
|
||||||
settingsRepositoryProvider
|
settingsRepositoryProvider
|
||||||
@@ -74,11 +95,12 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
|
_buildSection(theme, 'Kagi'),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: 16,
|
left: 16,
|
||||||
right: 16,
|
right: 16,
|
||||||
bottom: 16,
|
bottom: 8,
|
||||||
),
|
),
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: kagiSessionTextController,
|
controller: kagiSessionTextController,
|
||||||
@@ -129,6 +151,10 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
_buildSection(theme, 'General'),
|
||||||
SwitchListTile.adaptive(
|
SwitchListTile.adaptive(
|
||||||
title: const Text('Incognito Mode'),
|
title: const Text('Incognito Mode'),
|
||||||
subtitle: const Text(
|
subtitle: const Text(
|
||||||
@@ -168,6 +194,198 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
_buildSection(theme, 'Bangs'),
|
||||||
|
ButtonListTile(
|
||||||
|
title: 'Icon Cache',
|
||||||
|
subtitle: 'Stores favicons for Bangs',
|
||||||
|
button: FilledButton.icon(
|
||||||
|
onPressed: () async {
|
||||||
|
await ref
|
||||||
|
.read(bangDataRepositoryProvider.notifier)
|
||||||
|
.clearIconData();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.delete),
|
||||||
|
label: const Text('Clear'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ButtonListTile(
|
||||||
|
title: 'Bang Frequencies',
|
||||||
|
subtitle: 'Tracks Bang usage for recommendation history',
|
||||||
|
button: FilledButton.icon(
|
||||||
|
onPressed: () async {
|
||||||
|
await ref
|
||||||
|
.read(bangDataRepositoryProvider.notifier)
|
||||||
|
.clearFrequency();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.delete),
|
||||||
|
label: const Text('Clear'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Consumer(
|
||||||
|
builder: (context, ref, child) {
|
||||||
|
final lastSync = ref.watch(
|
||||||
|
lastSyncOfGroupProvider(BangGroup.general).select(
|
||||||
|
(value) => value.valueOrNull,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final count = ref.watch(
|
||||||
|
bangCountOfGroupProvider(BangGroup.general).select(
|
||||||
|
(value) => value.valueOrNull,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return ButtonListTile(
|
||||||
|
title: 'General Bangs',
|
||||||
|
subtitle: 'Automatically syncs every 7 days',
|
||||||
|
content: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: DefaultTextStyle(
|
||||||
|
style: GoogleFonts.robotoMono(),
|
||||||
|
child: Table(
|
||||||
|
children: [
|
||||||
|
TableRow(
|
||||||
|
children: [
|
||||||
|
const Text('Entries'),
|
||||||
|
Text(count?.toString() ?? 'N/A'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
TableRow(
|
||||||
|
children: [
|
||||||
|
const Text('Last Sync'),
|
||||||
|
Text(
|
||||||
|
lastSync?.formatWithMinutePrecision() ??
|
||||||
|
'N/A',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
button: FilledButton.icon(
|
||||||
|
onPressed: () async {
|
||||||
|
await ref
|
||||||
|
.read(bangSyncRepositoryProvider.notifier)
|
||||||
|
.syncGeneralBangs();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.sync),
|
||||||
|
label: const Text('Sync'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Consumer(
|
||||||
|
builder: (context, ref, child) {
|
||||||
|
final lastSync = ref.watch(
|
||||||
|
lastSyncOfGroupProvider(BangGroup.assistant).select(
|
||||||
|
(value) => value.valueOrNull,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final count = ref.watch(
|
||||||
|
bangCountOfGroupProvider(BangGroup.assistant).select(
|
||||||
|
(value) => value.valueOrNull,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return ButtonListTile(
|
||||||
|
title: 'Assistant Bangs',
|
||||||
|
subtitle: 'Automatically syncs every 7 days',
|
||||||
|
content: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: DefaultTextStyle(
|
||||||
|
style: GoogleFonts.robotoMono(),
|
||||||
|
child: Table(
|
||||||
|
children: [
|
||||||
|
TableRow(
|
||||||
|
children: [
|
||||||
|
const Text('Entries'),
|
||||||
|
Text(count?.toString() ?? 'N/A'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
TableRow(
|
||||||
|
children: [
|
||||||
|
const Text('Last Sync'),
|
||||||
|
Text(
|
||||||
|
lastSync?.formatWithMinutePrecision() ??
|
||||||
|
'N/A',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
button: FilledButton.icon(
|
||||||
|
onPressed: () async {
|
||||||
|
await ref
|
||||||
|
.read(bangSyncRepositoryProvider.notifier)
|
||||||
|
.syncAssistantBangs();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.sync),
|
||||||
|
label: const Text('Sync'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Consumer(
|
||||||
|
builder: (context, ref, child) {
|
||||||
|
final lastSync = ref.watch(
|
||||||
|
lastSyncOfGroupProvider(BangGroup.kagi).select(
|
||||||
|
(value) => value.valueOrNull,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final count = ref.watch(
|
||||||
|
bangCountOfGroupProvider(BangGroup.kagi).select(
|
||||||
|
(value) => value.valueOrNull,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return ButtonListTile(
|
||||||
|
title: 'Kagi Bangs',
|
||||||
|
subtitle: 'Automatically syncs every 7 days',
|
||||||
|
content: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: DefaultTextStyle(
|
||||||
|
style: GoogleFonts.robotoMono(),
|
||||||
|
child: Table(
|
||||||
|
children: [
|
||||||
|
TableRow(
|
||||||
|
children: [
|
||||||
|
const Text('Entries'),
|
||||||
|
Text(count?.toString() ?? 'N/A'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
TableRow(
|
||||||
|
children: [
|
||||||
|
const Text('Last Sync'),
|
||||||
|
Text(
|
||||||
|
lastSync?.formatWithMinutePrecision() ??
|
||||||
|
'N/A',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
button: FilledButton.icon(
|
||||||
|
onPressed: () async {
|
||||||
|
await ref
|
||||||
|
.read(bangSyncRepositoryProvider.notifier)
|
||||||
|
.syncKagiBangs();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.sync),
|
||||||
|
label: const Text('Sync'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ButtonListTile extends StatelessWidget {
|
||||||
|
final String title;
|
||||||
|
final String subtitle;
|
||||||
|
final Widget? content;
|
||||||
|
|
||||||
|
final Widget button;
|
||||||
|
|
||||||
|
const ButtonListTile({
|
||||||
|
super.key,
|
||||||
|
required this.title,
|
||||||
|
required this.subtitle,
|
||||||
|
this.content,
|
||||||
|
required this.button,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: theme.textTheme.bodyLarge,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
subtitle,
|
||||||
|
style: theme.textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
if (content != null) content!,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
button,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -579,6 +579,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.7.0"
|
version: "2.7.0"
|
||||||
|
google_fonts:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: google_fonts
|
||||||
|
sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.2.1"
|
||||||
graphs:
|
graphs:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ dependencies:
|
|||||||
flutter_secure_storage: ^9.0.0
|
flutter_secure_storage: ^9.0.0
|
||||||
flutter_sharing_intent: ^1.1.1
|
flutter_sharing_intent: ^1.1.1
|
||||||
go_router: ^14.1.1
|
go_router: ^14.1.1
|
||||||
|
google_fonts: ^6.2.1
|
||||||
home_widget: ^0.6.0
|
home_widget: ^0.6.0
|
||||||
hooks_riverpod: ^2.5.1
|
hooks_riverpod: ^2.5.1
|
||||||
html: ^0.15.4
|
html: ^0.15.4
|
||||||
@@ -70,6 +71,7 @@ flutter:
|
|||||||
assets:
|
assets:
|
||||||
- assets/icon/icon.png
|
- assets/icon/icon.png
|
||||||
- assets/landing/
|
- assets/landing/
|
||||||
|
- assets/fonts/
|
||||||
|
|
||||||
flutter_launcher_icons:
|
flutter_launcher_icons:
|
||||||
android: "launcher_icon"
|
android: "launcher_icon"
|
||||||
|
|||||||
Reference in New Issue
Block a user