mirror of
https://github.com/Dr-Blank/Vaani.git
synced 2026-01-14 22:29:32 +00:00
chore: run dart format
Some checks are pending
Flutter CI & Release / Test (push) Waiting to run
Flutter CI & Release / Build Android APKs (push) Blocked by required conditions
Flutter CI & Release / build_linux (push) Blocked by required conditions
Flutter CI & Release / Create GitHub Release (push) Blocked by required conditions
Some checks are pending
Flutter CI & Release / Test (push) Waiting to run
Flutter CI & Release / Build Android APKs (push) Blocked by required conditions
Flutter CI & Release / build_linux (push) Blocked by required conditions
Flutter CI & Release / Create GitHub Release (push) Blocked by required conditions
This commit is contained in:
parent
a520136e01
commit
e23c0b6c5f
84 changed files with 1565 additions and 1945 deletions
|
|
@ -19,8 +19,10 @@ model.AppSettings loadOrCreateAppSettings() {
|
|||
settings = _box.getAt(0);
|
||||
_logger.fine('found settings in box: $settings');
|
||||
} catch (e) {
|
||||
_logger.warning('error reading settings from box: $e'
|
||||
'\nclearing box');
|
||||
_logger.warning(
|
||||
'error reading settings from box: $e'
|
||||
'\nclearing box',
|
||||
);
|
||||
_box.clear();
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -12,19 +12,19 @@ Future<String> deviceName(Ref ref) async {
|
|||
|
||||
// try different keys to get the device name
|
||||
return
|
||||
// android
|
||||
data['product'] ??
|
||||
// ios
|
||||
data['name'] ??
|
||||
// linux
|
||||
data['name'] ??
|
||||
// windows
|
||||
data['computerName'] ??
|
||||
// macos
|
||||
data['model'] ??
|
||||
// web
|
||||
data['browserName'] ??
|
||||
'Unknown name';
|
||||
// android
|
||||
data['product'] ??
|
||||
// ios
|
||||
data['name'] ??
|
||||
// linux
|
||||
data['name'] ??
|
||||
// windows
|
||||
data['computerName'] ??
|
||||
// macos
|
||||
data['model'] ??
|
||||
// web
|
||||
data['browserName'] ??
|
||||
'Unknown name';
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
|
|
@ -33,19 +33,19 @@ Future<String> deviceModel(Ref ref) async {
|
|||
|
||||
// try different keys to get the device model
|
||||
return
|
||||
// android, eg: Google Pixel 4
|
||||
// android, eg: Google Pixel 4
|
||||
data['model'] ??
|
||||
// ios, eg: iPhone 12 Pro
|
||||
data['name'] ??
|
||||
// linux, eg: Linux Mint 20.1
|
||||
data['name'] ??
|
||||
// windows, eg: Surface Pro 7
|
||||
data['productId'] ??
|
||||
// macos, eg: MacBook Pro (13-inch, M1, 2020)
|
||||
data['model'] ??
|
||||
// ios, eg: iPhone 12 Pro
|
||||
data['name'] ??
|
||||
// linux, eg: Linux Mint 20.1
|
||||
data['name'] ??
|
||||
// windows, eg: Surface Pro 7
|
||||
data['productId'] ??
|
||||
// macos, eg: MacBook Pro (13-inch, M1, 2020)
|
||||
data['model'] ??
|
||||
// web, eg: Chrome 87.0.4280.88
|
||||
data['browserName'] ??
|
||||
'Unknown model';
|
||||
// web, eg: Chrome 87.0.4280.88
|
||||
data['browserName'] ??
|
||||
'Unknown model';
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
|
|
@ -54,19 +54,19 @@ Future<String> deviceSdkVersion(Ref ref) async {
|
|||
|
||||
// try different keys to get the device sdk version
|
||||
return
|
||||
// android, eg: 30
|
||||
data['version.sdkInt']?.toString() ??
|
||||
// ios, eg: 14.4
|
||||
data['systemVersion'] ??
|
||||
// linux, eg: 5.4.0-66-generic
|
||||
data['version'] ??
|
||||
// windows, eg: 10.0.19042
|
||||
data['displayVersion'] ??
|
||||
// macos, eg: 11.2.1
|
||||
data['osRelease'] ??
|
||||
// web, eg: 87.0.4280.88
|
||||
data['appVersion'] ??
|
||||
'Unknown sdk version';
|
||||
// android, eg: 30
|
||||
data['version.sdkInt']?.toString() ??
|
||||
// ios, eg: 14.4
|
||||
data['systemVersion'] ??
|
||||
// linux, eg: 5.4.0-66-generic
|
||||
data['version'] ??
|
||||
// windows, eg: 10.0.19042
|
||||
data['displayVersion'] ??
|
||||
// macos, eg: 11.2.1
|
||||
data['osRelease'] ??
|
||||
// web, eg: 87.0.4280.88
|
||||
data['appVersion'] ??
|
||||
'Unknown sdk version';
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
|
|
@ -75,19 +75,19 @@ Future<String> deviceManufacturer(Ref ref) async {
|
|||
|
||||
// try different keys to get the device manufacturer
|
||||
return
|
||||
// android, eg: Google
|
||||
// android, eg: Google
|
||||
data['manufacturer'] ??
|
||||
// ios, eg: Apple
|
||||
data['manufacturer'] ??
|
||||
// ios, eg: Apple
|
||||
data['manufacturer'] ??
|
||||
// linux, eg: Linux
|
||||
data['idLike'] ??
|
||||
// windows, eg: Microsoft
|
||||
data['productName'] ??
|
||||
// macos, eg: Apple
|
||||
data['manufacturer'] ??
|
||||
// web, eg: Google Inc.
|
||||
data['vendor'] ??
|
||||
'Unknown manufacturer';
|
||||
// linux, eg: Linux
|
||||
data['idLike'] ??
|
||||
// windows, eg: Microsoft
|
||||
data['productName'] ??
|
||||
// macos, eg: Apple
|
||||
data['manufacturer'] ??
|
||||
// web, eg: Google Inc.
|
||||
data['vendor'] ??
|
||||
'Unknown manufacturer';
|
||||
}
|
||||
|
||||
// copied from https://pub.dev/packages/device_info_plus/example
|
||||
|
|
@ -234,25 +234,28 @@ Future<Map<String, dynamic>> _getDeviceData(
|
|||
deviceData = _readWebBrowserInfo(await deviceInfoPlugin.webBrowserInfo);
|
||||
} else {
|
||||
deviceData = switch (defaultTargetPlatform) {
|
||||
TargetPlatform.android =>
|
||||
_readAndroidBuildData(await deviceInfoPlugin.androidInfo),
|
||||
TargetPlatform.iOS =>
|
||||
_readIosDeviceInfo(await deviceInfoPlugin.iosInfo),
|
||||
TargetPlatform.linux =>
|
||||
_readLinuxDeviceInfo(await deviceInfoPlugin.linuxInfo),
|
||||
TargetPlatform.windows =>
|
||||
_readWindowsDeviceInfo(await deviceInfoPlugin.windowsInfo),
|
||||
TargetPlatform.macOS =>
|
||||
_readMacOsDeviceInfo(await deviceInfoPlugin.macOsInfo),
|
||||
TargetPlatform.android => _readAndroidBuildData(
|
||||
await deviceInfoPlugin.androidInfo,
|
||||
),
|
||||
TargetPlatform.iOS => _readIosDeviceInfo(
|
||||
await deviceInfoPlugin.iosInfo,
|
||||
),
|
||||
TargetPlatform.linux => _readLinuxDeviceInfo(
|
||||
await deviceInfoPlugin.linuxInfo,
|
||||
),
|
||||
TargetPlatform.windows => _readWindowsDeviceInfo(
|
||||
await deviceInfoPlugin.windowsInfo,
|
||||
),
|
||||
TargetPlatform.macOS => _readMacOsDeviceInfo(
|
||||
await deviceInfoPlugin.macOsInfo,
|
||||
),
|
||||
TargetPlatform.fuchsia => <String, dynamic>{
|
||||
errorKey: 'Fuchsia platform isn\'t supported',
|
||||
},
|
||||
errorKey: 'Fuchsia platform isn\'t supported',
|
||||
},
|
||||
};
|
||||
}
|
||||
} on PlatformException {
|
||||
deviceData = <String, dynamic>{
|
||||
errorKey: 'Failed to get platform version.',
|
||||
};
|
||||
deviceData = <String, dynamic>{errorKey: 'Failed to get platform version.'};
|
||||
}
|
||||
return deviceData;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,7 @@ import 'package:vaani/settings/view/simple_settings_page.dart';
|
|||
import 'package:vaani/settings/view/widgets/navigation_with_switch_tile.dart';
|
||||
|
||||
class AppSettingsPage extends HookConsumerWidget {
|
||||
const AppSettingsPage({
|
||||
super.key,
|
||||
});
|
||||
const AppSettingsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
|
@ -33,17 +31,12 @@ class AppSettingsPage extends HookConsumerWidget {
|
|||
horizontal: 16.0,
|
||||
vertical: 8.0,
|
||||
),
|
||||
title: Text(
|
||||
'General',
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
title: Text('General', style: Theme.of(context).textTheme.titleLarge),
|
||||
tiles: [
|
||||
SettingsTile(
|
||||
title: const Text('Player Settings'),
|
||||
leading: const Icon(Icons.play_arrow),
|
||||
description: const Text(
|
||||
'Customize the player settings',
|
||||
),
|
||||
description: const Text('Customize the player settings'),
|
||||
onPressed: (context) {
|
||||
context.pushNamed(Routes.playerSettings.name);
|
||||
},
|
||||
|
|
@ -61,7 +54,9 @@ class AppSettingsPage extends HookConsumerWidget {
|
|||
},
|
||||
value: sleepTimerSettings.autoTurnOnTimer,
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.sleepTimerSettings(
|
||||
autoTurnOnTimer: value,
|
||||
),
|
||||
|
|
@ -71,15 +66,15 @@ class AppSettingsPage extends HookConsumerWidget {
|
|||
NavigationWithSwitchTile(
|
||||
title: const Text('Shake Detector'),
|
||||
leading: const Icon(Icons.vibration),
|
||||
description: const Text(
|
||||
'Customize the shake detector settings',
|
||||
),
|
||||
description: const Text('Customize the shake detector settings'),
|
||||
value: appSettings.shakeDetectionSettings.isEnabled,
|
||||
onPressed: (context) {
|
||||
context.pushNamed(Routes.shakeDetectorSettings.name);
|
||||
},
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.shakeDetectionSettings(
|
||||
isEnabled: value,
|
||||
),
|
||||
|
|
@ -103,9 +98,7 @@ class AppSettingsPage extends HookConsumerWidget {
|
|||
SettingsTile.navigation(
|
||||
leading: const Icon(Icons.color_lens),
|
||||
title: const Text('Theme Settings'),
|
||||
description: const Text(
|
||||
'Customize the app theme',
|
||||
),
|
||||
description: const Text('Customize the app theme'),
|
||||
onPressed: (context) {
|
||||
context.pushNamed(Routes.themeSettings.name);
|
||||
},
|
||||
|
|
@ -123,9 +116,7 @@ class AppSettingsPage extends HookConsumerWidget {
|
|||
SettingsTile.navigation(
|
||||
leading: const Icon(Icons.home_filled),
|
||||
title: const Text('Home Page Settings'),
|
||||
description: const Text(
|
||||
'Customize the home page',
|
||||
),
|
||||
description: const Text('Customize the home page'),
|
||||
onPressed: (context) {
|
||||
context.pushNamed(Routes.homePageSettings.name);
|
||||
},
|
||||
|
|
@ -147,21 +138,15 @@ class AppSettingsPage extends HookConsumerWidget {
|
|||
SettingsTile(
|
||||
title: const Text('Copy to Clipboard'),
|
||||
leading: const Icon(Icons.copy),
|
||||
description: const Text(
|
||||
'Copy the app settings to the clipboard',
|
||||
),
|
||||
description: const Text('Copy the app settings to the clipboard'),
|
||||
onPressed: (context) async {
|
||||
// copy to clipboard
|
||||
await Clipboard.setData(
|
||||
ClipboardData(
|
||||
text: jsonEncode(appSettings.toJson()),
|
||||
),
|
||||
ClipboardData(text: jsonEncode(appSettings.toJson())),
|
||||
);
|
||||
// show toast
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Settings copied to clipboard'),
|
||||
),
|
||||
const SnackBar(content: Text('Settings copied to clipboard')),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
@ -231,9 +216,7 @@ class AppSettingsPage extends HookConsumerWidget {
|
|||
}
|
||||
|
||||
class RestoreDialogue extends HookConsumerWidget {
|
||||
const RestoreDialogue({
|
||||
super.key,
|
||||
});
|
||||
const RestoreDialogue({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
|
@ -264,9 +247,7 @@ class RestoreDialogue extends HookConsumerWidget {
|
|||
}
|
||||
try {
|
||||
// try to decode the backup
|
||||
settings.value = model.AppSettings.fromJson(
|
||||
jsonDecode(value),
|
||||
);
|
||||
settings.value = model.AppSettings.fromJson(jsonDecode(value));
|
||||
} catch (e) {
|
||||
return 'Invalid backup';
|
||||
}
|
||||
|
|
@ -280,27 +261,21 @@ class RestoreDialogue extends HookConsumerWidget {
|
|||
onPressed: () {
|
||||
if (formKey.currentState!.validate()) {
|
||||
if (settings.value == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Invalid backup'),
|
||||
),
|
||||
);
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(const SnackBar(content: Text('Invalid backup')));
|
||||
return;
|
||||
}
|
||||
ref.read(appSettingsProvider.notifier).update(settings.value!);
|
||||
settingsInputController.clear();
|
||||
Navigator.of(context).pop();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Settings restored'),
|
||||
),
|
||||
const SnackBar(content: Text('Settings restored')),
|
||||
);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Invalid backup'),
|
||||
),
|
||||
);
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(const SnackBar(content: Text('Invalid backup')));
|
||||
}
|
||||
},
|
||||
child: const Text('Restore'),
|
||||
|
|
|
|||
|
|
@ -7,16 +7,15 @@ import 'package:vaani/settings/view/simple_settings_page.dart';
|
|||
import 'package:vaani/shared/extensions/time_of_day.dart';
|
||||
|
||||
class AutoSleepTimerSettingsPage extends HookConsumerWidget {
|
||||
const AutoSleepTimerSettingsPage({
|
||||
super.key,
|
||||
});
|
||||
const AutoSleepTimerSettingsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final appSettings = ref.watch(appSettingsProvider);
|
||||
final sleepTimerSettings = appSettings.sleepTimerSettings;
|
||||
|
||||
var enabled = sleepTimerSettings.autoTurnOnTimer &&
|
||||
var enabled =
|
||||
sleepTimerSettings.autoTurnOnTimer &&
|
||||
!sleepTimerSettings.alwaysAutoTurnOnTimer;
|
||||
final selectedValueColor = enabled
|
||||
? Theme.of(context).colorScheme.primary
|
||||
|
|
@ -40,7 +39,9 @@ class AutoSleepTimerSettingsPage extends HookConsumerWidget {
|
|||
? const Icon(Symbols.time_auto)
|
||||
: const Icon(Symbols.timer_off),
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.sleepTimerSettings(
|
||||
autoTurnOnTimer: value,
|
||||
),
|
||||
|
|
@ -63,7 +64,9 @@ class AutoSleepTimerSettingsPage extends HookConsumerWidget {
|
|||
initialTime: sleepTimerSettings.autoTurnOnTime.toTimeOfDay(),
|
||||
);
|
||||
if (selected != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.sleepTimerSettings(
|
||||
autoTurnOnTime: selected.toDuration(),
|
||||
),
|
||||
|
|
@ -89,7 +92,9 @@ class AutoSleepTimerSettingsPage extends HookConsumerWidget {
|
|||
initialTime: sleepTimerSettings.autoTurnOffTime.toTimeOfDay(),
|
||||
);
|
||||
if (selected != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.sleepTimerSettings(
|
||||
autoTurnOffTime: selected.toDuration(),
|
||||
),
|
||||
|
|
@ -97,9 +102,9 @@ class AutoSleepTimerSettingsPage extends HookConsumerWidget {
|
|||
}
|
||||
},
|
||||
trailing: Text(
|
||||
sleepTimerSettings.autoTurnOffTime
|
||||
.toTimeOfDay()
|
||||
.format(context),
|
||||
sleepTimerSettings.autoTurnOffTime.toTimeOfDay().format(
|
||||
context,
|
||||
),
|
||||
style: TextStyle(color: selectedValueColor),
|
||||
),
|
||||
),
|
||||
|
|
@ -112,7 +117,9 @@ class AutoSleepTimerSettingsPage extends HookConsumerWidget {
|
|||
'Always turn on the sleep timer, no matter what',
|
||||
),
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.sleepTimerSettings(
|
||||
alwaysAutoTurnOnTimer: value,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,27 +1,18 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class OkButton<T> extends StatelessWidget {
|
||||
const OkButton({
|
||||
super.key,
|
||||
this.onPressed,
|
||||
});
|
||||
const OkButton({super.key, this.onPressed});
|
||||
|
||||
final void Function()? onPressed;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextButton(
|
||||
onPressed: onPressed,
|
||||
child: const Text('OK'),
|
||||
);
|
||||
return TextButton(onPressed: onPressed, child: const Text('OK'));
|
||||
}
|
||||
}
|
||||
|
||||
class CancelButton extends StatelessWidget {
|
||||
const CancelButton({
|
||||
super.key,
|
||||
this.onPressed,
|
||||
});
|
||||
const CancelButton({super.key, this.onPressed});
|
||||
|
||||
final void Function()? onPressed;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ class HomePageSettingsPage extends HookConsumerWidget {
|
|||
tiles: [
|
||||
SettingsTile.switchTile(
|
||||
initialValue: appSettings
|
||||
.homePageSettings.showPlayButtonOnContinueListeningShelf,
|
||||
.homePageSettings
|
||||
.showPlayButtonOnContinueListeningShelf,
|
||||
title: const Text('Continue Listening'),
|
||||
leading: const Icon(Icons.play_arrow),
|
||||
description: const Text(
|
||||
|
|
@ -48,7 +49,8 @@ class HomePageSettingsPage extends HookConsumerWidget {
|
|||
'Show play button for books in continue series shelf',
|
||||
),
|
||||
initialValue: appSettings
|
||||
.homePageSettings.showPlayButtonOnContinueSeriesShelf,
|
||||
.homePageSettings
|
||||
.showPlayButtonOnContinueSeriesShelf,
|
||||
onToggle: (value) {
|
||||
appSettingsNotifier.update(
|
||||
appSettings.copyWith(
|
||||
|
|
@ -66,7 +68,8 @@ class HomePageSettingsPage extends HookConsumerWidget {
|
|||
'Show play button for all books in all remaining shelves',
|
||||
),
|
||||
initialValue: appSettings
|
||||
.homePageSettings.showPlayButtonOnAllRemainingShelves,
|
||||
.homePageSettings
|
||||
.showPlayButtonOnAllRemainingShelves,
|
||||
onToggle: (value) {
|
||||
appSettingsNotifier.update(
|
||||
appSettings.copyWith(
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ import 'package:vaani/settings/view/simple_settings_page.dart';
|
|||
import 'package:vaani/shared/extensions/enum.dart';
|
||||
|
||||
class NotificationSettingsPage extends HookConsumerWidget {
|
||||
const NotificationSettingsPage({
|
||||
super.key,
|
||||
});
|
||||
const NotificationSettingsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
|
@ -59,7 +57,9 @@ class NotificationSettingsPage extends HookConsumerWidget {
|
|||
},
|
||||
);
|
||||
if (selectedTitle != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.notificationSettings(
|
||||
primaryTitle: selectedTitle,
|
||||
),
|
||||
|
|
@ -97,7 +97,9 @@ class NotificationSettingsPage extends HookConsumerWidget {
|
|||
},
|
||||
);
|
||||
if (selectedTitle != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.notificationSettings(
|
||||
secondaryTitle: selectedTitle,
|
||||
),
|
||||
|
|
@ -118,7 +120,9 @@ class NotificationSettingsPage extends HookConsumerWidget {
|
|||
child: TimeIntervalSlider(
|
||||
defaultValue: notificationSettings.fastForwardInterval,
|
||||
onChangedEnd: (interval) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.notificationSettings(
|
||||
fastForwardInterval: interval,
|
||||
),
|
||||
|
|
@ -141,7 +145,9 @@ class NotificationSettingsPage extends HookConsumerWidget {
|
|||
child: TimeIntervalSlider(
|
||||
defaultValue: notificationSettings.rewindInterval,
|
||||
onChangedEnd: (interval) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.notificationSettings(
|
||||
rewindInterval: interval,
|
||||
),
|
||||
|
|
@ -162,26 +168,23 @@ class NotificationSettingsPage extends HookConsumerWidget {
|
|||
trailing: Wrap(
|
||||
spacing: 8.0,
|
||||
children: notificationSettings.mediaControls
|
||||
.map(
|
||||
(control) => Icon(
|
||||
control.icon,
|
||||
color: primaryColor,
|
||||
),
|
||||
)
|
||||
.map((control) => Icon(control.icon, color: primaryColor))
|
||||
.toList(),
|
||||
),
|
||||
onPressed: (context) async {
|
||||
final selectedControls =
|
||||
await showDialog<List<NotificationMediaControl>>(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return MediaControlsPicker(
|
||||
selectedControls: notificationSettings.mediaControls,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return MediaControlsPicker(
|
||||
selectedControls: notificationSettings.mediaControls,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
if (selectedControls != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.notificationSettings(
|
||||
mediaControls: selectedControls,
|
||||
),
|
||||
|
|
@ -194,11 +197,14 @@ class NotificationSettingsPage extends HookConsumerWidget {
|
|||
SettingsTile.switchTile(
|
||||
title: const Text('Show Chapter Progress'),
|
||||
leading: const Icon(Icons.book),
|
||||
description:
|
||||
const Text('instead of the overall progress of the book'),
|
||||
description: const Text(
|
||||
'instead of the overall progress of the book',
|
||||
),
|
||||
initialValue: notificationSettings.progressBarIsChapterProgress,
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.notificationSettings(
|
||||
progressBarIsChapterProgress: value,
|
||||
),
|
||||
|
|
@ -213,10 +219,7 @@ class NotificationSettingsPage extends HookConsumerWidget {
|
|||
}
|
||||
|
||||
class MediaControlsPicker extends HookConsumerWidget {
|
||||
const MediaControlsPicker({
|
||||
super.key,
|
||||
required this.selectedControls,
|
||||
});
|
||||
const MediaControlsPicker({super.key, required this.selectedControls});
|
||||
|
||||
final List<NotificationMediaControl> selectedControls;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ import 'package:vaani/settings/view/simple_settings_page.dart';
|
|||
import 'package:vaani/shared/extensions/duration_format.dart';
|
||||
|
||||
class PlayerSettingsPage extends HookConsumerWidget {
|
||||
const PlayerSettingsPage({
|
||||
super.key,
|
||||
});
|
||||
const PlayerSettingsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
|
@ -37,7 +35,9 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
),
|
||||
initialValue: playerSettings.configurePlayerForEveryBook,
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.playerSettings(
|
||||
configurePlayerForEveryBook: value,
|
||||
),
|
||||
|
|
@ -50,8 +50,10 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
title: const Text('Default Speed'),
|
||||
trailing: Text(
|
||||
'${playerSettings.preferredDefaultSpeed}x',
|
||||
style:
|
||||
TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
leading: const Icon(Icons.speed),
|
||||
onPressed: (context) async {
|
||||
|
|
@ -62,7 +64,9 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
),
|
||||
);
|
||||
if (newSpeed != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.playerSettings(
|
||||
preferredDefaultSpeed: newSpeed,
|
||||
),
|
||||
|
|
@ -75,8 +79,10 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
title: const Text('Speed Options'),
|
||||
description: Text(
|
||||
playerSettings.speedOptions.map((e) => '${e}x').join(', '),
|
||||
style:
|
||||
TextStyle(fontWeight: FontWeight.bold, color: primaryColor),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
leading: const Icon(Icons.speed),
|
||||
onPressed: (context) async {
|
||||
|
|
@ -87,7 +93,9 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
),
|
||||
);
|
||||
if (newSpeedOptions != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.playerSettings(
|
||||
speedOptions: newSpeedOptions..sort(),
|
||||
),
|
||||
|
|
@ -110,7 +118,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
children: [
|
||||
TextSpan(
|
||||
text: playerSettings
|
||||
.minimumPositionForReporting.smartBinaryFormat,
|
||||
.minimumPositionForReporting
|
||||
.smartBinaryFormat,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: primaryColor,
|
||||
|
|
@ -133,7 +142,9 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
},
|
||||
);
|
||||
if (newDuration != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.playerSettings(
|
||||
minimumPositionForReporting: newDuration,
|
||||
),
|
||||
|
|
@ -150,7 +161,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
children: [
|
||||
TextSpan(
|
||||
text: playerSettings
|
||||
.markCompleteWhenTimeLeft.smartBinaryFormat,
|
||||
.markCompleteWhenTimeLeft
|
||||
.smartBinaryFormat,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: primaryColor,
|
||||
|
|
@ -173,7 +185,9 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
},
|
||||
);
|
||||
if (newDuration != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.playerSettings(
|
||||
markCompleteWhenTimeLeft: newDuration,
|
||||
),
|
||||
|
|
@ -190,7 +204,8 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
children: [
|
||||
TextSpan(
|
||||
text: playerSettings
|
||||
.playbackReportInterval.smartBinaryFormat,
|
||||
.playbackReportInterval
|
||||
.smartBinaryFormat,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: primaryColor,
|
||||
|
|
@ -213,7 +228,9 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
},
|
||||
);
|
||||
if (newDuration != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.playerSettings(
|
||||
playbackReportInterval: newDuration,
|
||||
),
|
||||
|
|
@ -237,7 +254,9 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
initialValue:
|
||||
playerSettings.expandedPlayerSettings.showTotalProgress,
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.playerSettings
|
||||
.expandedPlayerSettings(showTotalProgress: value),
|
||||
);
|
||||
|
|
@ -253,7 +272,9 @@ class PlayerSettingsPage extends HookConsumerWidget {
|
|||
initialValue:
|
||||
playerSettings.expandedPlayerSettings.showChapterProgress,
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.playerSettings(
|
||||
expandedPlayerSettings: playerSettings
|
||||
.expandedPlayerSettings
|
||||
|
|
@ -306,17 +327,15 @@ class TimeDurationSelector extends HookConsumerWidget {
|
|||
}
|
||||
|
||||
class SpeedPicker extends HookConsumerWidget {
|
||||
const SpeedPicker({
|
||||
super.key,
|
||||
this.initialValue = 1,
|
||||
});
|
||||
const SpeedPicker({super.key, this.initialValue = 1});
|
||||
|
||||
final double initialValue;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final speedController =
|
||||
useTextEditingController(text: initialValue.toString());
|
||||
final speedController = useTextEditingController(
|
||||
text: initialValue.toString(),
|
||||
);
|
||||
final speed = useState<double?>(initialValue);
|
||||
return AlertDialog(
|
||||
title: const Text('Select Speed'),
|
||||
|
|
@ -368,30 +387,32 @@ class SpeedOptionsPicker extends HookConsumerWidget {
|
|||
Wrap(
|
||||
spacing: 8.0,
|
||||
runSpacing: 8.0,
|
||||
children: speedOptions.value
|
||||
.map(
|
||||
(speed) => Chip(
|
||||
label: Text('${speed}x'),
|
||||
onDeleted: speed == 1
|
||||
? null
|
||||
: () {
|
||||
speedOptions.value =
|
||||
speedOptions.value.where((element) {
|
||||
// speed option 1 can't be removed
|
||||
return element != speed;
|
||||
}).toList();
|
||||
},
|
||||
),
|
||||
)
|
||||
.toList()
|
||||
..sort((a, b) {
|
||||
// if (a.label == const Text('1x')) {
|
||||
// return -1;
|
||||
// } else if (b.label == const Text('1x')) {
|
||||
// return 1;
|
||||
// }
|
||||
return a.label.toString().compareTo(b.label.toString());
|
||||
}),
|
||||
children:
|
||||
speedOptions.value
|
||||
.map(
|
||||
(speed) => Chip(
|
||||
label: Text('${speed}x'),
|
||||
onDeleted: speed == 1
|
||||
? null
|
||||
: () {
|
||||
speedOptions.value = speedOptions.value.where((
|
||||
element,
|
||||
) {
|
||||
// speed option 1 can't be removed
|
||||
return element != speed;
|
||||
}).toList();
|
||||
},
|
||||
),
|
||||
)
|
||||
.toList()
|
||||
..sort((a, b) {
|
||||
// if (a.label == const Text('1x')) {
|
||||
// return -1;
|
||||
// } else if (b.label == const Text('1x')) {
|
||||
// return 1;
|
||||
// }
|
||||
return a.label.toString().compareTo(b.label.toString());
|
||||
}),
|
||||
),
|
||||
TextField(
|
||||
focusNode: focusNode,
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ import 'package:vaani/settings/view/simple_settings_page.dart';
|
|||
import 'package:vaani/shared/extensions/enum.dart';
|
||||
|
||||
class ShakeDetectorSettingsPage extends HookConsumerWidget {
|
||||
const ShakeDetectorSettingsPage({
|
||||
super.key,
|
||||
});
|
||||
const ShakeDetectorSettingsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
|
@ -41,7 +39,9 @@ class ShakeDetectorSettingsPage extends HookConsumerWidget {
|
|||
),
|
||||
initialValue: shakeDetectionSettings.isEnabled,
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.shakeDetectionSettings(
|
||||
isEnabled: value,
|
||||
),
|
||||
|
|
@ -77,7 +77,9 @@ class ShakeDetectorSettingsPage extends HookConsumerWidget {
|
|||
);
|
||||
|
||||
if (newThreshold != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.shakeDetectionSettings(
|
||||
threshold: newThreshold,
|
||||
),
|
||||
|
|
@ -107,7 +109,9 @@ class ShakeDetectorSettingsPage extends HookConsumerWidget {
|
|||
);
|
||||
|
||||
if (newShakeAction != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.shakeDetectionSettings(
|
||||
shakeAction: newShakeAction,
|
||||
),
|
||||
|
|
@ -131,26 +135,23 @@ class ShakeDetectorSettingsPage extends HookConsumerWidget {
|
|||
)
|
||||
: Wrap(
|
||||
spacing: 8.0,
|
||||
children: shakeDetectionSettings.feedback.map(
|
||||
(feedback) {
|
||||
return Icon(
|
||||
feedback.icon,
|
||||
color: selectedValueColor,
|
||||
);
|
||||
},
|
||||
).toList(),
|
||||
children: shakeDetectionSettings.feedback.map((feedback) {
|
||||
return Icon(feedback.icon, color: selectedValueColor);
|
||||
}).toList(),
|
||||
),
|
||||
onPressed: (context) async {
|
||||
final newFeedback =
|
||||
await showDialog<Set<ShakeDetectedFeedback>>(
|
||||
context: context,
|
||||
builder: (context) => ShakeFeedbackSelector(
|
||||
initialValue: shakeDetectionSettings.feedback,
|
||||
),
|
||||
);
|
||||
context: context,
|
||||
builder: (context) => ShakeFeedbackSelector(
|
||||
initialValue: shakeDetectionSettings.feedback,
|
||||
),
|
||||
);
|
||||
|
||||
if (newFeedback != null) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.shakeDetectionSettings(
|
||||
feedback: newFeedback,
|
||||
),
|
||||
|
|
@ -256,10 +257,7 @@ class ShakeActionSelector extends HookConsumerWidget {
|
|||
}
|
||||
|
||||
class ShakeForceSelector extends HookConsumerWidget {
|
||||
const ShakeForceSelector({
|
||||
super.key,
|
||||
this.initialValue = 6,
|
||||
});
|
||||
const ShakeForceSelector({super.key, this.initialValue = 6});
|
||||
|
||||
final double initialValue;
|
||||
|
||||
|
|
@ -291,9 +289,7 @@ class ShakeForceSelector extends HookConsumerWidget {
|
|||
shakeForce.value = 0;
|
||||
},
|
||||
),
|
||||
helper: const Text(
|
||||
'Enter a number to set the threshold in m/s²',
|
||||
),
|
||||
helper: const Text('Enter a number to set the threshold in m/s²'),
|
||||
),
|
||||
),
|
||||
Wrap(
|
||||
|
|
|
|||
|
|
@ -4,11 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||
import 'package:vaani/features/player/view/mini_player_bottom_padding.dart';
|
||||
|
||||
class SimpleSettingsPage extends HookConsumerWidget {
|
||||
const SimpleSettingsPage({
|
||||
super.key,
|
||||
this.title,
|
||||
this.sections,
|
||||
});
|
||||
const SimpleSettingsPage({super.key, this.title, this.sections});
|
||||
|
||||
final Widget? title;
|
||||
final List<AbstractSettingsSection>? sections;
|
||||
|
|
@ -34,18 +30,16 @@ class SimpleSettingsPage extends HookConsumerWidget {
|
|||
),
|
||||
if (sections != null)
|
||||
SliverList(
|
||||
delegate: SliverChildListDelegate(
|
||||
[
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||
child: SettingsList(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
sections: sections!,
|
||||
),
|
||||
delegate: SliverChildListDelegate([
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||
child: SettingsList(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
sections: sections!,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
// some padding at the bottom
|
||||
const SliverPadding(padding: EdgeInsets.only(bottom: 20)),
|
||||
|
|
|
|||
|
|
@ -10,9 +10,7 @@ import 'package:vaani/settings/view/simple_settings_page.dart';
|
|||
import 'package:vaani/shared/extensions/enum.dart';
|
||||
|
||||
class ThemeSettingsPage extends HookConsumerWidget {
|
||||
const ThemeSettingsPage({
|
||||
super.key,
|
||||
});
|
||||
const ThemeSettingsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
|
@ -38,7 +36,9 @@ class ThemeSettingsPage extends HookConsumerWidget {
|
|||
selectedIcon: const Icon(Icons.check),
|
||||
selected: {themeSettings.themeMode},
|
||||
onSelectionChanged: (newSelection) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.themeSettings(
|
||||
themeMode: newSelection.first,
|
||||
),
|
||||
|
|
@ -66,8 +66,8 @@ class ThemeSettingsPage extends HookConsumerWidget {
|
|||
themeSettings.themeMode == ThemeMode.light
|
||||
? Icons.light_mode
|
||||
: themeSettings.themeMode == ThemeMode.dark
|
||||
? Icons.dark_mode
|
||||
: Icons.auto_awesome,
|
||||
? Icons.dark_mode
|
||||
: Icons.auto_awesome,
|
||||
),
|
||||
),
|
||||
|
||||
|
|
@ -82,10 +82,10 @@ class ThemeSettingsPage extends HookConsumerWidget {
|
|||
'Increase the contrast between the background and the text',
|
||||
),
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
appSettings.copyWith.themeSettings(
|
||||
highContrast: value,
|
||||
),
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.themeSettings(highContrast: value),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
@ -103,7 +103,9 @@ class ThemeSettingsPage extends HookConsumerWidget {
|
|||
? const Icon(Icons.auto_awesome)
|
||||
: const Icon(Icons.auto_fix_off),
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.themeSettings(
|
||||
useMaterialThemeFromSystem: value,
|
||||
),
|
||||
|
|
@ -164,7 +166,9 @@ class ThemeSettingsPage extends HookConsumerWidget {
|
|||
? const Icon(Icons.auto_fix_high)
|
||||
: const Icon(Icons.auto_fix_off),
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.themeSettings(
|
||||
useCurrentPlayerThemeThroughoutApp: value,
|
||||
),
|
||||
|
|
@ -182,7 +186,9 @@ class ThemeSettingsPage extends HookConsumerWidget {
|
|||
? const Icon(Icons.auto_fix_high)
|
||||
: const Icon(Icons.auto_fix_off),
|
||||
onToggle: (value) {
|
||||
ref.read(appSettingsProvider.notifier).update(
|
||||
ref
|
||||
.read(appSettingsProvider.notifier)
|
||||
.update(
|
||||
appSettings.copyWith.themeSettings(
|
||||
useMaterialThemeOnItemPage: value,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -44,10 +44,7 @@ class NavigationWithSwitchTile extends AbstractSettingsTile {
|
|||
indent: 8.0,
|
||||
endIndent: 8.0,
|
||||
),
|
||||
Switch.adaptive(
|
||||
value: value,
|
||||
onChanged: onToggle,
|
||||
),
|
||||
Switch.adaptive(value: value, onChanged: onToggle),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue