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/repositories/settings_repository.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/presentation/hooks/listenable_callback.dart';
|
||||
import 'package:bang_navigator/utils/ui_helper.dart' as ui_helper;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
class SettingsScreen extends HookConsumerWidget {
|
||||
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
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
final kagiSessionTextController = useTextEditingController(
|
||||
text: ref.read(
|
||||
settingsRepositoryProvider
|
||||
@@ -74,11 +95,12 @@ class SettingsScreen extends HookConsumerWidget {
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: ListView(
|
||||
children: [
|
||||
_buildSection(theme, 'Kagi'),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16,
|
||||
right: 16,
|
||||
bottom: 16,
|
||||
bottom: 8,
|
||||
),
|
||||
child: TextField(
|
||||
controller: kagiSessionTextController,
|
||||
@@ -129,6 +151,10 @@ class SettingsScreen extends HookConsumerWidget {
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
_buildSection(theme, 'General'),
|
||||
SwitchListTile.adaptive(
|
||||
title: const Text('Incognito Mode'),
|
||||
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"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -25,6 +25,7 @@ dependencies:
|
||||
flutter_secure_storage: ^9.0.0
|
||||
flutter_sharing_intent: ^1.1.1
|
||||
go_router: ^14.1.1
|
||||
google_fonts: ^6.2.1
|
||||
home_widget: ^0.6.0
|
||||
hooks_riverpod: ^2.5.1
|
||||
html: ^0.15.4
|
||||
@@ -70,6 +71,7 @@ flutter:
|
||||
assets:
|
||||
- assets/icon/icon.png
|
||||
- assets/landing/
|
||||
- assets/fonts/
|
||||
|
||||
flutter_launcher_icons:
|
||||
android: "launcher_icon"
|
||||
|
||||
Reference in New Issue
Block a user