Files
plezy/lib/services/settings_service.dart
T
2025-11-05 13:29:45 +01:00

730 lines
25 KiB
Dart

import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/services.dart';
import 'package:hotkey_manager/hotkey_manager.dart';
import 'package:plezy/utils/app_logger.dart';
enum ThemeMode { system, light, dark }
enum LibraryDensity { compact, normal, comfortable }
enum ViewMode { grid, list }
class SettingsService {
static const String _keyThemeMode = 'theme_mode';
static const String _keyEnableDebugLogging = 'enable_debug_logging';
static const String _keyBufferSize = 'buffer_size';
static const String _keyKeyboardShortcuts = 'keyboard_shortcuts';
static const String _keyKeyboardHotkeys = 'keyboard_hotkeys';
static const String _keyEnableHardwareDecoding = 'enable_hardware_decoding';
static const String _keyPreferredVideoCodec = 'preferred_video_codec';
static const String _keyPreferredAudioCodec = 'preferred_audio_codec';
static const String _keyLibraryDensity = 'library_density';
static const String _keyViewMode = 'view_mode';
static const String _keyUseSeasonPoster = 'use_season_poster';
static const String _keySeekTimeSmall = 'seek_time_small';
static const String _keySeekTimeLarge = 'seek_time_large';
static const String _keyMediaVersionPreferences = 'media_version_preferences';
static const String _keyShowHeroSection = 'show_hero_section';
static const String _keySleepTimerDuration = 'sleep_timer_duration';
static SettingsService? _instance;
late SharedPreferences _prefs;
SettingsService._();
static Future<SettingsService> getInstance() async {
if (_instance == null) {
_instance = SettingsService._();
await _instance!._init();
}
return _instance!;
}
Future<void> _init() async {
_prefs = await SharedPreferences.getInstance();
}
// Theme Mode
Future<void> setThemeMode(ThemeMode mode) async {
await _prefs.setString(_keyThemeMode, mode.name);
}
ThemeMode getThemeMode() {
final modeString = _prefs.getString(_keyThemeMode);
return ThemeMode.values.firstWhere(
(mode) => mode.name == modeString,
orElse: () => ThemeMode.system,
);
}
// Debug Logging
Future<void> setEnableDebugLogging(bool enabled) async {
await _prefs.setBool(_keyEnableDebugLogging, enabled);
// Update logger level immediately when setting changes
setLoggerLevel(enabled);
}
bool getEnableDebugLogging() {
return _prefs.getBool(_keyEnableDebugLogging) ?? false;
}
// Buffer Size (in MB)
Future<void> setBufferSize(int sizeInMB) async {
await _prefs.setInt(_keyBufferSize, sizeInMB);
}
int getBufferSize() {
return _prefs.getInt(_keyBufferSize) ?? 128; // Default 128MB
}
// Hardware Decoding
Future<void> setEnableHardwareDecoding(bool enabled) async {
await _prefs.setBool(_keyEnableHardwareDecoding, enabled);
}
bool getEnableHardwareDecoding() {
return _prefs.getBool(_keyEnableHardwareDecoding) ??
true; // Default enabled
}
// Preferred Video Codec
Future<void> setPreferredVideoCodec(String codec) async {
await _prefs.setString(_keyPreferredVideoCodec, codec);
}
String getPreferredVideoCodec() {
return _prefs.getString(_keyPreferredVideoCodec) ?? 'auto';
}
// Preferred Audio Codec
Future<void> setPreferredAudioCodec(String codec) async {
await _prefs.setString(_keyPreferredAudioCodec, codec);
}
String getPreferredAudioCodec() {
return _prefs.getString(_keyPreferredAudioCodec) ?? 'auto';
}
// Library Density
Future<void> setLibraryDensity(LibraryDensity density) async {
await _prefs.setString(_keyLibraryDensity, density.name);
}
LibraryDensity getLibraryDensity() {
final densityString = _prefs.getString(_keyLibraryDensity);
return LibraryDensity.values.firstWhere(
(density) => density.name == densityString,
orElse: () => LibraryDensity.normal,
);
}
// View Mode
Future<void> setViewMode(ViewMode mode) async {
await _prefs.setString(_keyViewMode, mode.name);
}
ViewMode getViewMode() {
final modeString = _prefs.getString(_keyViewMode);
return ViewMode.values.firstWhere(
(mode) => mode.name == modeString,
orElse: () => ViewMode.grid,
);
}
// Use Season Poster
Future<void> setUseSeasonPoster(bool enabled) async {
await _prefs.setBool(_keyUseSeasonPoster, enabled);
}
bool getUseSeasonPoster() {
return _prefs.getBool(_keyUseSeasonPoster) ??
false; // Default: false (use series poster)
}
// Show Hero Section
Future<void> setShowHeroSection(bool enabled) async {
await _prefs.setBool(_keyShowHeroSection, enabled);
}
bool getShowHeroSection() {
return _prefs.getBool(_keyShowHeroSection) ??
true; // Default: true (show hero section)
}
// Seek Time Small (in seconds)
Future<void> setSeekTimeSmall(int seconds) async {
await _prefs.setInt(_keySeekTimeSmall, seconds);
}
int getSeekTimeSmall() {
return _prefs.getInt(_keySeekTimeSmall) ?? 10; // Default: 10 seconds
}
// Seek Time Large (in seconds)
Future<void> setSeekTimeLarge(int seconds) async {
await _prefs.setInt(_keySeekTimeLarge, seconds);
}
int getSeekTimeLarge() {
return _prefs.getInt(_keySeekTimeLarge) ?? 30; // Default: 30 seconds
}
// Sleep Timer Duration (in minutes)
Future<void> setSleepTimerDuration(int minutes) async {
await _prefs.setInt(_keySleepTimerDuration, minutes);
}
int getSleepTimerDuration() {
return _prefs.getInt(_keySleepTimerDuration) ?? 30; // Default: 30 minutes
}
// Keyboard Shortcuts (Legacy String-based)
Map<String, String> getDefaultKeyboardShortcuts() {
return {
'play_pause': 'Space',
'volume_up': 'Arrow Up',
'volume_down': 'Arrow Down',
'seek_forward': 'Arrow Right',
'seek_backward': 'Arrow Left',
'seek_forward_large': 'Shift+Arrow Right',
'seek_backward_large': 'Shift+Arrow Left',
'fullscreen_toggle': 'F',
'mute_toggle': 'M',
'subtitle_toggle': 'S',
'audio_track_next': 'A',
'subtitle_track_next': 'Shift+S',
'chapter_next': 'N',
'chapter_previous': 'P',
'speed_increase': 'Plus',
'speed_decrease': 'Minus',
'speed_reset': 'R',
};
}
// HotKey Objects (New implementation)
Map<String, HotKey> getDefaultKeyboardHotkeys() {
return {
'play_pause': HotKey(key: PhysicalKeyboardKey.space),
'volume_up': HotKey(key: PhysicalKeyboardKey.arrowUp),
'volume_down': HotKey(key: PhysicalKeyboardKey.arrowDown),
'seek_forward': HotKey(key: PhysicalKeyboardKey.arrowRight),
'seek_backward': HotKey(key: PhysicalKeyboardKey.arrowLeft),
'seek_forward_large': HotKey(
key: PhysicalKeyboardKey.arrowRight,
modifiers: [HotKeyModifier.shift],
),
'seek_backward_large': HotKey(
key: PhysicalKeyboardKey.arrowLeft,
modifiers: [HotKeyModifier.shift],
),
'fullscreen_toggle': HotKey(key: PhysicalKeyboardKey.keyF),
'mute_toggle': HotKey(key: PhysicalKeyboardKey.keyM),
'subtitle_toggle': HotKey(key: PhysicalKeyboardKey.keyS),
'audio_track_next': HotKey(key: PhysicalKeyboardKey.keyA),
'subtitle_track_next': HotKey(
key: PhysicalKeyboardKey.keyS,
modifiers: [HotKeyModifier.shift],
),
'chapter_next': HotKey(key: PhysicalKeyboardKey.keyN),
'chapter_previous': HotKey(key: PhysicalKeyboardKey.keyP),
'speed_increase': HotKey(key: PhysicalKeyboardKey.equal),
'speed_decrease': HotKey(key: PhysicalKeyboardKey.minus),
'speed_reset': HotKey(key: PhysicalKeyboardKey.keyR),
};
}
Future<void> setKeyboardShortcuts(Map<String, String> shortcuts) async {
final jsonString = json.encode(shortcuts);
await _prefs.setString(_keyKeyboardShortcuts, jsonString);
}
Map<String, String> getKeyboardShortcuts() {
final jsonString = _prefs.getString(_keyKeyboardShortcuts);
if (jsonString == null) return getDefaultKeyboardShortcuts();
try {
final decoded = json.decode(jsonString) as Map<String, dynamic>;
final shortcuts = decoded.map(
(key, value) => MapEntry(key, value.toString()),
);
// Merge with defaults to ensure all keys exist
final defaults = getDefaultKeyboardShortcuts();
defaults.addAll(shortcuts);
return defaults;
} catch (e) {
return getDefaultKeyboardShortcuts();
}
}
Future<void> setKeyboardShortcut(String action, String key) async {
final shortcuts = getKeyboardShortcuts();
shortcuts[action] = key;
await setKeyboardShortcuts(shortcuts);
}
String getKeyboardShortcut(String action) {
final shortcuts = getKeyboardShortcuts();
return shortcuts[action] ?? '';
}
Future<void> resetKeyboardShortcuts() async {
await setKeyboardShortcuts(getDefaultKeyboardShortcuts());
}
// HotKey Objects Methods
Future<void> setKeyboardHotkeys(Map<String, HotKey> hotkeys) async {
final Map<String, Map<String, dynamic>> serializedHotkeys = {};
for (final entry in hotkeys.entries) {
serializedHotkeys[entry.key] = _serializeHotKey(entry.value);
}
final jsonString = json.encode(serializedHotkeys);
await _prefs.setString(_keyKeyboardHotkeys, jsonString);
}
Future<Map<String, HotKey>> getKeyboardHotkeys() async {
final jsonString = _prefs.getString(_keyKeyboardHotkeys);
if (jsonString == null) {
return getDefaultKeyboardHotkeys();
}
try {
final decoded = json.decode(jsonString) as Map<String, dynamic>;
final Map<String, HotKey> hotkeys = {};
for (final entry in decoded.entries) {
final hotKey = _deserializeHotKey(entry.value as Map<String, dynamic>);
if (hotKey != null) {
hotkeys[entry.key] = hotKey;
}
}
// Merge with defaults to ensure all keys exist, but keep saved hotkeys priority
final defaults = getDefaultKeyboardHotkeys();
final result = <String, HotKey>{};
// Start with defaults
result.addAll(defaults);
// Override with saved hotkeys (this preserves user customizations)
result.addAll(hotkeys);
return result;
} catch (e) {
return getDefaultKeyboardHotkeys();
}
}
Future<void> setKeyboardHotkey(String action, HotKey hotKey) async {
final hotkeys = await getKeyboardHotkeys();
hotkeys[action] = hotKey;
await setKeyboardHotkeys(hotkeys);
}
Future<HotKey?> getKeyboardHotkey(String action) async {
final hotkeys = await getKeyboardHotkeys();
return hotkeys[action];
}
Future<void> resetKeyboardHotkeys() async {
await setKeyboardHotkeys(getDefaultKeyboardHotkeys());
}
// Helper methods for HotKey serialization
Map<String, dynamic> _serializeHotKey(HotKey hotKey) {
return {
'key': hotKey.key.toString(),
'modifiers': hotKey.modifiers?.map((m) => m.name).toList() ?? [],
};
}
HotKey? _deserializeHotKey(Map<String, dynamic> data) {
try {
final keyString = data['key'] as String;
final modifierNames = (data['modifiers'] as List<dynamic>).cast<String>();
final modifiers = modifierNames
.map((name) {
switch (name) {
case 'alt':
return HotKeyModifier.alt;
case 'control':
return HotKeyModifier.control;
case 'shift':
return HotKeyModifier.shift;
case 'meta':
return HotKeyModifier.meta;
case 'capsLock':
return HotKeyModifier.capsLock;
case 'fn':
return HotKeyModifier.fn;
default:
return null;
}
})
.where((m) => m != null)
.cast<HotKeyModifier>()
.toList();
final key = _findKeyByString(keyString);
if (key != null) {
return HotKey(
key: key,
modifiers: modifiers.isNotEmpty ? modifiers : null,
);
}
} catch (e) {
// Ignore deserialization errors
}
return null;
}
// Helper method to find PhysicalKeyboardKey by string representation
PhysicalKeyboardKey? _findKeyByString(String keyString) {
// Handle exact string matches first for better performance
const keyMap = {
'PhysicalKeyboardKey#0002c': PhysicalKeyboardKey.space,
'PhysicalKeyboardKey#7002a': PhysicalKeyboardKey.backspace,
'PhysicalKeyboardKey#7004c': PhysicalKeyboardKey.delete,
'PhysicalKeyboardKey#70028': PhysicalKeyboardKey.enter,
'PhysicalKeyboardKey#70029': PhysicalKeyboardKey.escape,
'PhysicalKeyboardKey#7002b': PhysicalKeyboardKey.tab,
'PhysicalKeyboardKey#7004a': PhysicalKeyboardKey.home,
'PhysicalKeyboardKey#7004d': PhysicalKeyboardKey.end,
'PhysicalKeyboardKey#7004b': PhysicalKeyboardKey.pageUp,
'PhysicalKeyboardKey#7004e': PhysicalKeyboardKey.pageDown,
'PhysicalKeyboardKey#70050': PhysicalKeyboardKey.arrowLeft,
'PhysicalKeyboardKey#70052': PhysicalKeyboardKey.arrowUp,
'PhysicalKeyboardKey#7004f': PhysicalKeyboardKey.arrowRight,
'PhysicalKeyboardKey#70051': PhysicalKeyboardKey.arrowDown,
};
// Check exact matches first
if (keyMap.containsKey(keyString)) {
return keyMap[keyString];
}
// Alternative approach: extract USB HID usage code from the toString() output
// Format: PhysicalKeyboardKey#ec9ed(usbHidUsage: "0x0007002c", debugName: "Space")
try {
final usbHidMatch = RegExp(
r'usbHidUsage: "0x([0-9a-fA-F]+)"',
).firstMatch(keyString);
if (usbHidMatch != null) {
final usbHidCode = usbHidMatch.group(1)!.toLowerCase();
// Map USB HID codes to PhysicalKeyboardKey objects
const usbHidMap = {
'0007002c': PhysicalKeyboardKey.space,
'0007002a': PhysicalKeyboardKey.backspace,
'0007004c': PhysicalKeyboardKey.delete,
'00070028': PhysicalKeyboardKey.enter,
'00070029': PhysicalKeyboardKey.escape,
'0007002b': PhysicalKeyboardKey.tab,
'00070039': PhysicalKeyboardKey.capsLock,
// Function keys
'0007003a': PhysicalKeyboardKey.f1,
'0007003b': PhysicalKeyboardKey.f2,
'0007003c': PhysicalKeyboardKey.f3,
'0007003d': PhysicalKeyboardKey.f4,
'0007003e': PhysicalKeyboardKey.f5,
'0007003f': PhysicalKeyboardKey.f6,
'00070040': PhysicalKeyboardKey.f7,
'00070041': PhysicalKeyboardKey.f8,
'00070042': PhysicalKeyboardKey.f9,
'00070043': PhysicalKeyboardKey.f10,
'00070044': PhysicalKeyboardKey.f11,
'00070045': PhysicalKeyboardKey.f12,
// Number keys
'00070027': PhysicalKeyboardKey.digit0,
'0007001e': PhysicalKeyboardKey.digit1,
'0007001f': PhysicalKeyboardKey.digit2,
'00070020': PhysicalKeyboardKey.digit3,
'00070021': PhysicalKeyboardKey.digit4,
'00070022': PhysicalKeyboardKey.digit5,
'00070023': PhysicalKeyboardKey.digit6,
'00070024': PhysicalKeyboardKey.digit7,
'00070025': PhysicalKeyboardKey.digit8,
'00070026': PhysicalKeyboardKey.digit9,
// Letter keys
'00070004': PhysicalKeyboardKey.keyA,
'00070005': PhysicalKeyboardKey.keyB,
'00070006': PhysicalKeyboardKey.keyC,
'00070007': PhysicalKeyboardKey.keyD,
'00070008': PhysicalKeyboardKey.keyE,
'00070009': PhysicalKeyboardKey.keyF,
'0007000a': PhysicalKeyboardKey.keyG,
'0007000b': PhysicalKeyboardKey.keyH,
'0007000c': PhysicalKeyboardKey.keyI,
'0007000d': PhysicalKeyboardKey.keyJ,
'0007000e': PhysicalKeyboardKey.keyK,
'0007000f': PhysicalKeyboardKey.keyL,
'00070010': PhysicalKeyboardKey.keyM,
'00070011': PhysicalKeyboardKey.keyN,
'00070012': PhysicalKeyboardKey.keyO,
'00070013': PhysicalKeyboardKey.keyP,
'00070014': PhysicalKeyboardKey.keyQ,
'00070015': PhysicalKeyboardKey.keyR,
'00070016': PhysicalKeyboardKey.keyS,
'00070017': PhysicalKeyboardKey.keyT,
'00070018': PhysicalKeyboardKey.keyU,
'00070019': PhysicalKeyboardKey.keyV,
'0007001a': PhysicalKeyboardKey.keyW,
'0007001b': PhysicalKeyboardKey.keyX,
'0007001c': PhysicalKeyboardKey.keyY,
'0007001d': PhysicalKeyboardKey.keyZ,
// Arrow keys
'00070050': PhysicalKeyboardKey.arrowLeft,
'00070052': PhysicalKeyboardKey.arrowUp,
'0007004f': PhysicalKeyboardKey.arrowRight,
'00070051': PhysicalKeyboardKey.arrowDown,
// Other common keys
'0007002d': PhysicalKeyboardKey.equal,
'0007002e': PhysicalKeyboardKey.minus,
'0007004a': PhysicalKeyboardKey.home,
'0007004d': PhysicalKeyboardKey.end,
'0007004b': PhysicalKeyboardKey.pageUp,
'0007004e': PhysicalKeyboardKey.pageDown,
};
if (usbHidMap.containsKey(usbHidCode)) {
return usbHidMap[usbHidCode];
}
}
} catch (e) {
// Ignore parsing errors
}
// Fall back to contains() checks for partial matches
if (keyString.contains('space')) {
return PhysicalKeyboardKey.space;
} else if (keyString.contains('arrowUp')) {
return PhysicalKeyboardKey.arrowUp;
} else if (keyString.contains('arrowDown')) {
return PhysicalKeyboardKey.arrowDown;
} else if (keyString.contains('arrowLeft')) {
return PhysicalKeyboardKey.arrowLeft;
} else if (keyString.contains('arrowRight')) {
return PhysicalKeyboardKey.arrowRight;
} else if (keyString.contains('equal')) {
return PhysicalKeyboardKey.equal;
} else if (keyString.contains('minus')) {
return PhysicalKeyboardKey.minus;
} else if (keyString.contains('escape')) {
return PhysicalKeyboardKey.escape;
} else if (keyString.contains('enter')) {
return PhysicalKeyboardKey.enter;
} else if (keyString.contains('tab')) {
return PhysicalKeyboardKey.tab;
} else if (keyString.contains('backspace')) {
return PhysicalKeyboardKey.backspace;
} else if (keyString.contains('delete')) {
return PhysicalKeyboardKey.delete;
} else if (keyString.contains('home')) {
return PhysicalKeyboardKey.home;
} else if (keyString.contains('end')) {
return PhysicalKeyboardKey.end;
} else if (keyString.contains('pageUp')) {
return PhysicalKeyboardKey.pageUp;
} else if (keyString.contains('pageDown')) {
return PhysicalKeyboardKey.pageDown;
} else {
// Try function keys F1-F12
for (int i = 1; i <= 12; i++) {
if (keyString.contains('f$i') || keyString.contains('F$i')) {
switch (i) {
case 1:
return PhysicalKeyboardKey.f1;
case 2:
return PhysicalKeyboardKey.f2;
case 3:
return PhysicalKeyboardKey.f3;
case 4:
return PhysicalKeyboardKey.f4;
case 5:
return PhysicalKeyboardKey.f5;
case 6:
return PhysicalKeyboardKey.f6;
case 7:
return PhysicalKeyboardKey.f7;
case 8:
return PhysicalKeyboardKey.f8;
case 9:
return PhysicalKeyboardKey.f9;
case 10:
return PhysicalKeyboardKey.f10;
case 11:
return PhysicalKeyboardKey.f11;
case 12:
return PhysicalKeyboardKey.f12;
}
}
}
// Try number keys 0-9
for (int i = 0; i <= 9; i++) {
if (keyString.contains('digit$i') || keyString.contains('Digit$i')) {
switch (i) {
case 0:
return PhysicalKeyboardKey.digit0;
case 1:
return PhysicalKeyboardKey.digit1;
case 2:
return PhysicalKeyboardKey.digit2;
case 3:
return PhysicalKeyboardKey.digit3;
case 4:
return PhysicalKeyboardKey.digit4;
case 5:
return PhysicalKeyboardKey.digit5;
case 6:
return PhysicalKeyboardKey.digit6;
case 7:
return PhysicalKeyboardKey.digit7;
case 8:
return PhysicalKeyboardKey.digit8;
case 9:
return PhysicalKeyboardKey.digit9;
}
}
}
// Try letter keys A-Z (both upper and lower case patterns)
const letterKeys = {
'A': PhysicalKeyboardKey.keyA,
'B': PhysicalKeyboardKey.keyB,
'C': PhysicalKeyboardKey.keyC,
'D': PhysicalKeyboardKey.keyD,
'E': PhysicalKeyboardKey.keyE,
'F': PhysicalKeyboardKey.keyF,
'G': PhysicalKeyboardKey.keyG,
'H': PhysicalKeyboardKey.keyH,
'I': PhysicalKeyboardKey.keyI,
'J': PhysicalKeyboardKey.keyJ,
'K': PhysicalKeyboardKey.keyK,
'L': PhysicalKeyboardKey.keyL,
'M': PhysicalKeyboardKey.keyM,
'N': PhysicalKeyboardKey.keyN,
'O': PhysicalKeyboardKey.keyO,
'P': PhysicalKeyboardKey.keyP,
'Q': PhysicalKeyboardKey.keyQ,
'R': PhysicalKeyboardKey.keyR,
'S': PhysicalKeyboardKey.keyS,
'T': PhysicalKeyboardKey.keyT,
'U': PhysicalKeyboardKey.keyU,
'V': PhysicalKeyboardKey.keyV,
'W': PhysicalKeyboardKey.keyW,
'X': PhysicalKeyboardKey.keyX,
'Y': PhysicalKeyboardKey.keyY,
'Z': PhysicalKeyboardKey.keyZ,
};
for (final entry in letterKeys.entries) {
if (keyString.contains('key${entry.key}') ||
keyString.contains('Key${entry.key}')) {
return entry.value;
}
}
return null;
}
}
// Media Version Preferences
/// Save media version preference for a series
/// [seriesRatingKey] is the grandparentRatingKey for TV series, or ratingKey for movies
/// [mediaIndex] is the index of the selected media version
Future<void> setMediaVersionPreference(
String seriesRatingKey,
int mediaIndex,
) async {
final preferences = _getMediaVersionPreferences();
preferences[seriesRatingKey] = mediaIndex;
final jsonString = json.encode(preferences);
await _prefs.setString(_keyMediaVersionPreferences, jsonString);
}
/// Get saved media version preference for a series
/// Returns null if no preference is saved
int? getMediaVersionPreference(String seriesRatingKey) {
final preferences = _getMediaVersionPreferences();
return preferences[seriesRatingKey];
}
/// Clear media version preference for a series
Future<void> clearMediaVersionPreference(String seriesRatingKey) async {
final preferences = _getMediaVersionPreferences();
preferences.remove(seriesRatingKey);
final jsonString = json.encode(preferences);
await _prefs.setString(_keyMediaVersionPreferences, jsonString);
}
/// Get all media version preferences
Map<String, int> _getMediaVersionPreferences() {
final jsonString = _prefs.getString(_keyMediaVersionPreferences);
if (jsonString == null) return {};
try {
final decoded = json.decode(jsonString) as Map<String, dynamic>;
return decoded.map((key, value) => MapEntry(key, value as int));
} catch (e) {
return {};
}
}
// Reset all settings to defaults
Future<void> resetAllSettings() async {
await Future.wait([
_prefs.remove(_keyThemeMode),
_prefs.remove(_keyEnableDebugLogging),
_prefs.remove(_keyBufferSize),
_prefs.remove(_keyKeyboardShortcuts),
_prefs.remove(_keyKeyboardHotkeys),
_prefs.remove(_keyEnableHardwareDecoding),
_prefs.remove(_keyPreferredVideoCodec),
_prefs.remove(_keyPreferredAudioCodec),
_prefs.remove(_keyLibraryDensity),
_prefs.remove(_keyViewMode),
_prefs.remove(_keyUseSeasonPoster),
_prefs.remove(_keyShowHeroSection),
_prefs.remove(_keySeekTimeSmall),
_prefs.remove(_keySeekTimeLarge),
_prefs.remove(_keyMediaVersionPreferences),
_prefs.remove(_keySleepTimerDuration),
]);
}
// Clear cache (for storage cleanup)
Future<void> clearCache() async {
// This would be expanded to clear various cache directories
// For now, we'll just clear any cache-related preferences
await Future.wait([
// Add cache clearing logic here
]);
}
// Get all settings as a map for debugging/export
Future<Map<String, dynamic>> getAllSettings() async {
final hotkeys = await getKeyboardHotkeys();
return {
'themeMode': getThemeMode().name,
'enableDebugLogging': getEnableDebugLogging(),
'bufferSize': getBufferSize(),
'enableHardwareDecoding': getEnableHardwareDecoding(),
'preferredVideoCodec': getPreferredVideoCodec(),
'preferredAudioCodec': getPreferredAudioCodec(),
'libraryDensity': getLibraryDensity().name,
'viewMode': getViewMode().name,
'useSeasonPoster': getUseSeasonPoster(),
'seekTimeSmall': getSeekTimeSmall(),
'seekTimeLarge': getSeekTimeLarge(),
'keyboardShortcuts': getKeyboardShortcuts(),
'keyboardHotkeys': hotkeys.map(
(key, value) => MapEntry(key, _serializeHotKey(value)),
),
};
}
}