122 lines
3.8 KiB
Dart
122 lines
3.8 KiB
Dart
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
|
|
|
||
|
|
import 'shared/settings_persistence.dart';
|
||
|
|
|
||
|
|
class RememberedAudioTrack {
|
||
|
|
final int streamIndex;
|
||
|
|
final String? language;
|
||
|
|
final String? codec;
|
||
|
|
final int? channels;
|
||
|
|
final String? displayTitle;
|
||
|
|
final DateTime updatedAt;
|
||
|
|
|
||
|
|
const RememberedAudioTrack({
|
||
|
|
required this.streamIndex,
|
||
|
|
this.language,
|
||
|
|
this.codec,
|
||
|
|
this.channels,
|
||
|
|
this.displayTitle,
|
||
|
|
required this.updatedAt,
|
||
|
|
});
|
||
|
|
|
||
|
|
Map<String, dynamic> toJson() => {
|
||
|
|
'streamIndex': streamIndex,
|
||
|
|
if (language != null) 'language': language,
|
||
|
|
if (codec != null) 'codec': codec,
|
||
|
|
if (channels != null) 'channels': channels,
|
||
|
|
if (displayTitle != null) 'displayTitle': displayTitle,
|
||
|
|
'updatedAt': updatedAt.toIso8601String(),
|
||
|
|
};
|
||
|
|
|
||
|
|
factory RememberedAudioTrack.fromJson(Map<String, dynamic> json) {
|
||
|
|
return RememberedAudioTrack(
|
||
|
|
streamIndex: json['streamIndex'] as int,
|
||
|
|
language: json['language'] as String?,
|
||
|
|
codec: json['codec'] as String?,
|
||
|
|
channels: json['channels'] as int?,
|
||
|
|
displayTitle: json['displayTitle'] as String?,
|
||
|
|
updatedAt:
|
||
|
|
DateTime.tryParse(json['updatedAt'] as String? ?? '') ??
|
||
|
|
DateTime.now(),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
class AudioSettingsState {
|
||
|
|
final bool rememberAudioTrack;
|
||
|
|
final String preferredAudioLanguage;
|
||
|
|
final bool volumeBoost;
|
||
|
|
|
||
|
|
const AudioSettingsState({
|
||
|
|
this.rememberAudioTrack = false,
|
||
|
|
this.preferredAudioLanguage = '',
|
||
|
|
this.volumeBoost = false,
|
||
|
|
});
|
||
|
|
|
||
|
|
AudioSettingsState copyWith({
|
||
|
|
bool? rememberAudioTrack,
|
||
|
|
String? preferredAudioLanguage,
|
||
|
|
bool? volumeBoost,
|
||
|
|
}) => AudioSettingsState(
|
||
|
|
rememberAudioTrack: rememberAudioTrack ?? this.rememberAudioTrack,
|
||
|
|
preferredAudioLanguage:
|
||
|
|
preferredAudioLanguage ?? this.preferredAudioLanguage,
|
||
|
|
volumeBoost: volumeBoost ?? this.volumeBoost,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
class AudioSettingsNotifier extends AsyncNotifier<AudioSettingsState>
|
||
|
|
with SettingsPersistence {
|
||
|
|
static const _keyRememberTrack = 'smplayer.audio_remember_track';
|
||
|
|
static const _keyPreferredLang = 'smplayer.audio_preferred_language';
|
||
|
|
static const _keyVolumeBoost = 'smplayer.audio_volume_boost';
|
||
|
|
static const _keyLastAudioTracks = 'smplayer.audio_last_tracks';
|
||
|
|
static const _maxRememberedTracks = 200;
|
||
|
|
|
||
|
|
@override
|
||
|
|
Future<AudioSettingsState> build() async {
|
||
|
|
final prefs = await getPrefs();
|
||
|
|
return AudioSettingsState(
|
||
|
|
rememberAudioTrack: prefs.getBool(_keyRememberTrack) ?? false,
|
||
|
|
preferredAudioLanguage: prefs.getString(_keyPreferredLang) ?? '',
|
||
|
|
volumeBoost: prefs.getBool(_keyVolumeBoost) ?? false,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> setRememberAudioTrack(bool value) async {
|
||
|
|
final current = state.value ?? const AudioSettingsState();
|
||
|
|
state = AsyncValue.data(current.copyWith(rememberAudioTrack: value));
|
||
|
|
await persistField(_keyRememberTrack, value);
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> setPreferredAudioLanguage(String language) async {
|
||
|
|
final current = state.value ?? const AudioSettingsState();
|
||
|
|
state = AsyncValue.data(current.copyWith(preferredAudioLanguage: language));
|
||
|
|
await persistField(_keyPreferredLang, language);
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> setVolumeBoost(bool value) async {
|
||
|
|
final current = state.value ?? const AudioSettingsState();
|
||
|
|
state = AsyncValue.data(current.copyWith(volumeBoost: value));
|
||
|
|
await persistField(_keyVolumeBoost, value);
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> saveLastAudioTrack(String key, RememberedAudioTrack track) =>
|
||
|
|
putRemembered(
|
||
|
|
_keyLastAudioTracks,
|
||
|
|
key,
|
||
|
|
track.toJson(),
|
||
|
|
_maxRememberedTracks,
|
||
|
|
);
|
||
|
|
|
||
|
|
Future<RememberedAudioTrack?> getLastAudioTrack(String key) async {
|
||
|
|
final entry = await readRemembered(_keyLastAudioTracks, key);
|
||
|
|
return entry == null ? null : RememberedAudioTrack.fromJson(entry);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
final audioSettingsProvider =
|
||
|
|
AsyncNotifierProvider<AudioSettingsNotifier, AudioSettingsState>(
|
||
|
|
AudioSettingsNotifier.new,
|
||
|
|
);
|