2024-05-08 05:03:49 -04:00
|
|
|
// a freezed class to store the settings of the app
|
|
|
|
|
|
2024-09-25 03:13:42 -04:00
|
|
|
import 'package:flutter/material.dart';
|
2024-05-08 05:03:49 -04:00
|
|
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
|
|
|
|
|
|
|
|
part 'app_settings.freezed.dart';
|
|
|
|
|
part 'app_settings.g.dart';
|
|
|
|
|
|
|
|
|
|
/// stores the settings of the app
|
|
|
|
|
///
|
|
|
|
|
/// only the visual settings are stored here
|
|
|
|
|
@freezed
|
|
|
|
|
class AppSettings with _$AppSettings {
|
|
|
|
|
const factory AppSettings({
|
2024-08-20 11:39:26 -04:00
|
|
|
@Default(ThemeSettings()) ThemeSettings themeSettings,
|
2024-05-17 11:04:20 -04:00
|
|
|
@Default(PlayerSettings()) PlayerSettings playerSettings,
|
2024-08-20 08:36:39 -04:00
|
|
|
@Default(DownloadSettings()) DownloadSettings downloadSettings,
|
2024-09-25 03:13:42 -04:00
|
|
|
@Default(NotificationSettings()) NotificationSettings notificationSettings,
|
2024-09-28 01:27:56 -04:00
|
|
|
@Default(ShakeDetectionSettings())
|
|
|
|
|
ShakeDetectionSettings shakeDetectionSettings,
|
2024-05-08 05:03:49 -04:00
|
|
|
}) = _AppSettings;
|
|
|
|
|
|
|
|
|
|
factory AppSettings.fromJson(Map<String, dynamic> json) =>
|
|
|
|
|
_$AppSettingsFromJson(json);
|
|
|
|
|
}
|
2024-05-17 11:04:20 -04:00
|
|
|
|
2024-08-20 11:39:26 -04:00
|
|
|
@freezed
|
|
|
|
|
class ThemeSettings with _$ThemeSettings {
|
|
|
|
|
const factory ThemeSettings({
|
|
|
|
|
@Default(true) bool isDarkMode,
|
|
|
|
|
@Default(true) bool useMaterialThemeOnItemPage,
|
2024-08-20 11:52:35 -04:00
|
|
|
@Default(true) bool useCurrentPlayerThemeThroughoutApp,
|
2024-08-20 11:39:26 -04:00
|
|
|
}) = _ThemeSettings;
|
|
|
|
|
|
|
|
|
|
factory ThemeSettings.fromJson(Map<String, dynamic> json) =>
|
|
|
|
|
_$ThemeSettingsFromJson(json);
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-17 11:04:20 -04:00
|
|
|
@freezed
|
|
|
|
|
class PlayerSettings with _$PlayerSettings {
|
|
|
|
|
const factory PlayerSettings({
|
|
|
|
|
@Default(MinimizedPlayerSettings())
|
|
|
|
|
MinimizedPlayerSettings miniPlayerSettings,
|
2024-05-19 08:53:21 -04:00
|
|
|
@Default(ExpandedPlayerSettings())
|
|
|
|
|
ExpandedPlayerSettings expandedPlayerSettings,
|
2024-05-21 10:50:02 -04:00
|
|
|
@Default(1) double preferredDefaultVolume,
|
|
|
|
|
@Default(1) double preferredDefaultSpeed,
|
2024-05-22 02:13:01 -04:00
|
|
|
@Default([0.75, 1, 1.25, 1.5, 1.75, 2]) List<double> speedOptions,
|
2024-09-26 04:30:51 -04:00
|
|
|
@Default(0.05) double speedIncrement,
|
|
|
|
|
@Default(0.1) double minSpeed,
|
|
|
|
|
@Default(4) double maxSpeed,
|
2024-06-06 15:35:30 -04:00
|
|
|
@Default(SleepTimerSettings()) SleepTimerSettings sleepTimerSettings,
|
2024-09-26 01:39:43 -04:00
|
|
|
@Default(Duration(seconds: 10)) Duration minimumPositionForReporting,
|
2024-06-15 23:43:08 -04:00
|
|
|
@Default(Duration(seconds: 10)) Duration playbackReportInterval,
|
2024-09-26 01:39:43 -04:00
|
|
|
@Default(Duration(seconds: 15)) Duration markCompleteWhenTimeLeft,
|
2024-09-17 23:19:05 -04:00
|
|
|
@Default(true) bool configurePlayerForEveryBook,
|
2024-05-17 11:04:20 -04:00
|
|
|
}) = _PlayerSettings;
|
|
|
|
|
|
|
|
|
|
factory PlayerSettings.fromJson(Map<String, dynamic> json) =>
|
|
|
|
|
_$PlayerSettingsFromJson(json);
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-19 08:53:21 -04:00
|
|
|
@freezed
|
|
|
|
|
class ExpandedPlayerSettings with _$ExpandedPlayerSettings {
|
|
|
|
|
const factory ExpandedPlayerSettings({
|
|
|
|
|
@Default(false) bool showTotalProgress,
|
|
|
|
|
@Default(true) bool showChapterProgress,
|
|
|
|
|
}) = _ExpandedPlayerSettings;
|
|
|
|
|
|
|
|
|
|
factory ExpandedPlayerSettings.fromJson(Map<String, dynamic> json) =>
|
|
|
|
|
_$ExpandedPlayerSettingsFromJson(json);
|
|
|
|
|
}
|
2024-05-21 10:50:02 -04:00
|
|
|
|
2024-05-17 11:04:20 -04:00
|
|
|
@freezed
|
|
|
|
|
class MinimizedPlayerSettings with _$MinimizedPlayerSettings {
|
|
|
|
|
const factory MinimizedPlayerSettings({
|
|
|
|
|
@Default(false) bool useChapterInfo,
|
2024-05-19 08:53:21 -04:00
|
|
|
}) = _MinimizedPlayerSettings;
|
2024-05-17 11:04:20 -04:00
|
|
|
|
|
|
|
|
factory MinimizedPlayerSettings.fromJson(Map<String, dynamic> json) =>
|
|
|
|
|
_$MinimizedPlayerSettingsFromJson(json);
|
|
|
|
|
}
|
2024-06-06 15:35:30 -04:00
|
|
|
|
|
|
|
|
enum SleepTimerShakeSenseMode { never, always, nearEnds }
|
|
|
|
|
|
|
|
|
|
@freezed
|
|
|
|
|
class SleepTimerSettings with _$SleepTimerSettings {
|
|
|
|
|
const factory SleepTimerSettings({
|
|
|
|
|
@Default(Duration(minutes: 15)) Duration defaultDuration,
|
|
|
|
|
@Default(SleepTimerShakeSenseMode.always)
|
|
|
|
|
SleepTimerShakeSenseMode shakeSenseMode,
|
|
|
|
|
|
|
|
|
|
/// the duration in which the shake is detected before the end of the timer and after the timer ends
|
|
|
|
|
/// only used if [shakeSenseMode] is [SleepTimerShakeSenseMode.nearEnds]
|
|
|
|
|
@Default(Duration(seconds: 30)) Duration shakeSenseDuration,
|
|
|
|
|
@Default(true) bool vibrateWhenReset,
|
|
|
|
|
@Default(false) bool beepWhenReset,
|
|
|
|
|
@Default(false) bool fadeOutAudio,
|
|
|
|
|
@Default(0.5) double shakeDetectThreshold,
|
|
|
|
|
|
|
|
|
|
/// if true, the player will automatically rewind the audio when the sleep timer is stopped
|
|
|
|
|
@Default(false) bool autoRewindWhenStopped,
|
|
|
|
|
|
|
|
|
|
/// the key is the duration in minutes
|
|
|
|
|
@Default({
|
|
|
|
|
5: Duration(seconds: 10),
|
|
|
|
|
15: Duration(seconds: 30),
|
|
|
|
|
45: Duration(seconds: 45),
|
|
|
|
|
60: Duration(minutes: 1),
|
|
|
|
|
120: Duration(minutes: 2),
|
|
|
|
|
})
|
|
|
|
|
Map<int, Duration> autoRewindDurations,
|
|
|
|
|
|
|
|
|
|
/// auto turn on timer settings
|
|
|
|
|
@Default(false) bool autoTurnOnTimer,
|
|
|
|
|
|
|
|
|
|
/// always auto turn on timer settings or during specific times
|
|
|
|
|
@Default(true) bool alwaysAutoTurnOnTimer,
|
|
|
|
|
|
|
|
|
|
/// auto timer settings, only used if [alwaysAutoTurnOnTimer] is false
|
|
|
|
|
///
|
|
|
|
|
/// duration is the time from 00:00
|
|
|
|
|
@Default(Duration(hours: 22, minutes: 0)) Duration autoTurnOnTime,
|
|
|
|
|
@Default(Duration(hours: 6, minutes: 0)) Duration autoTurnOffTime,
|
|
|
|
|
}) = _SleepTimerSettings;
|
|
|
|
|
|
|
|
|
|
factory SleepTimerSettings.fromJson(Map<String, dynamic> json) =>
|
|
|
|
|
_$SleepTimerSettingsFromJson(json);
|
|
|
|
|
}
|
2024-08-20 08:36:39 -04:00
|
|
|
|
|
|
|
|
@freezed
|
|
|
|
|
class DownloadSettings with _$DownloadSettings {
|
|
|
|
|
const factory DownloadSettings({
|
|
|
|
|
@Default(true) bool requiresWiFi,
|
|
|
|
|
@Default(3) int retries,
|
|
|
|
|
@Default(true) bool allowPause,
|
|
|
|
|
@Default(3) int maxConcurrent,
|
|
|
|
|
@Default(3) int maxConcurrentByHost,
|
|
|
|
|
@Default(3) int maxConcurrentByGroup,
|
|
|
|
|
}) = _DownloadSettings;
|
|
|
|
|
|
|
|
|
|
factory DownloadSettings.fromJson(Map<String, dynamic> json) =>
|
|
|
|
|
_$DownloadSettingsFromJson(json);
|
|
|
|
|
}
|
2024-09-25 03:13:42 -04:00
|
|
|
|
|
|
|
|
@freezed
|
|
|
|
|
class NotificationSettings with _$NotificationSettings {
|
|
|
|
|
const factory NotificationSettings({
|
|
|
|
|
@Default(Duration(seconds: 30)) Duration fastForwardInterval,
|
|
|
|
|
@Default(Duration(seconds: 10)) Duration rewindInterval,
|
|
|
|
|
@Default(true) bool progressBarIsChapterProgress,
|
|
|
|
|
@Default('\$bookTitle') String primaryTitle,
|
|
|
|
|
@Default('\$author') String secondaryTitle,
|
|
|
|
|
@Default(
|
|
|
|
|
[
|
|
|
|
|
NotificationMediaControl.rewind,
|
|
|
|
|
NotificationMediaControl.fastForward,
|
|
|
|
|
NotificationMediaControl.skipToPreviousChapter,
|
|
|
|
|
NotificationMediaControl.skipToNextChapter,
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
List<NotificationMediaControl> mediaControls,
|
|
|
|
|
}) = _NotificationSettings;
|
|
|
|
|
|
|
|
|
|
factory NotificationSettings.fromJson(Map<String, dynamic> json) =>
|
|
|
|
|
_$NotificationSettingsFromJson(json);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum NotificationTitleType {
|
2024-09-28 01:27:56 -04:00
|
|
|
chapterTitle,
|
|
|
|
|
bookTitle,
|
|
|
|
|
author,
|
|
|
|
|
subtitle,
|
|
|
|
|
series,
|
|
|
|
|
narrator,
|
|
|
|
|
year,
|
2024-09-25 03:13:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum NotificationMediaControl {
|
|
|
|
|
fastForward(Icons.fast_forward),
|
|
|
|
|
rewind(Icons.fast_rewind),
|
|
|
|
|
speedToggle(Icons.speed),
|
|
|
|
|
stop(Icons.stop),
|
|
|
|
|
skipToNextChapter(Icons.skip_next),
|
|
|
|
|
skipToPreviousChapter(Icons.skip_previous);
|
|
|
|
|
|
|
|
|
|
const NotificationMediaControl(this.icon);
|
|
|
|
|
|
|
|
|
|
final IconData icon;
|
|
|
|
|
}
|
2024-09-28 01:27:56 -04:00
|
|
|
|
|
|
|
|
/// Shake Detection Settings
|
|
|
|
|
@freezed
|
|
|
|
|
class ShakeDetectionSettings with _$ShakeDetectionSettings {
|
|
|
|
|
const factory ShakeDetectionSettings({
|
|
|
|
|
@Default(true) bool isEnabled,
|
|
|
|
|
@Default(ShakeDirection.horizontal) ShakeDirection direction,
|
|
|
|
|
@Default(5) double threshold,
|
|
|
|
|
@Default(ShakeAction.resetSleepTimer) ShakeAction shakeAction,
|
|
|
|
|
@Default({ShakeDetectedFeedback.vibrate, ShakeDetectedFeedback.beep})
|
|
|
|
|
Set<ShakeDetectedFeedback> feedback,
|
|
|
|
|
@Default(0.5) double beepVolume,
|
|
|
|
|
|
|
|
|
|
/// the duration to wait before the shake detection is enabled again
|
|
|
|
|
@Default(Duration(seconds: 5)) Duration shakeTriggerCoolDown,
|
|
|
|
|
|
|
|
|
|
/// the number of shakes required to trigger the action
|
|
|
|
|
@Default(2) int shakeTriggerCount,
|
|
|
|
|
|
|
|
|
|
/// acceleration sampling interval
|
|
|
|
|
@Default(Duration(milliseconds: 100)) Duration samplingPeriod,
|
|
|
|
|
}) = _ShakeDetectionSettings;
|
|
|
|
|
|
|
|
|
|
factory ShakeDetectionSettings.fromJson(Map<String, dynamic> json) =>
|
|
|
|
|
_$ShakeDetectionSettingsFromJson(json);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum ShakeDirection { horizontal, vertical }
|
|
|
|
|
|
|
|
|
|
enum ShakeAction {
|
|
|
|
|
none,
|
|
|
|
|
playPause,
|
|
|
|
|
resetSleepTimer,
|
|
|
|
|
fastForward,
|
|
|
|
|
rewind,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum ShakeDetectedFeedback { vibrate, beep }
|