@@ -1106,6 +1106,8 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
|
||||
player: player!,
|
||||
availableVersions: _availableVersions,
|
||||
selectedMediaIndex: widget.selectedMediaIndex,
|
||||
initialBoxFitMode: settingsService.getDefaultBoxFitMode(),
|
||||
onBoxFitModeChanged: (mode) => settingsService.setDefaultBoxFitMode(mode),
|
||||
);
|
||||
// Update video filter once dimensions are available
|
||||
_videoFilterManager!.updateVideoFilter();
|
||||
@@ -1265,15 +1267,18 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply the saved shader preset on playback start
|
||||
/// Apply the saved shader preset on playback start.
|
||||
/// Reads directly from SettingsService (synchronous SharedPreferences) to
|
||||
/// avoid a race with ShaderProvider's async initialization.
|
||||
Future<void> _applySavedShaderPreset() async {
|
||||
if (_shaderService == null || !_shaderService!.isSupported) return;
|
||||
|
||||
try {
|
||||
final shaderProvider = context.read<ShaderProvider>();
|
||||
final preset = shaderProvider.savedPreset;
|
||||
final settings = await SettingsService.getInstance();
|
||||
final presetId = settings.getGlobalShaderPreset();
|
||||
final preset = ShaderPreset.fromId(presetId) ?? ShaderPreset.none;
|
||||
await _shaderService!.applyPreset(preset);
|
||||
shaderProvider.setCurrentPreset(preset);
|
||||
context.read<ShaderProvider>().setCurrentPreset(preset);
|
||||
} catch (e) {
|
||||
appLogger.d('Could not apply shader preset', error: e);
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ class SettingsService extends BaseSharedPreferencesService {
|
||||
static const String _keyMatchContentFrameRate = 'match_content_frame_rate';
|
||||
static const String _keyTunneledPlayback = 'tunneled_playback';
|
||||
static const String _keyDefaultPlaybackSpeed = 'default_playback_speed';
|
||||
static const String _keyDefaultBoxFitMode = 'default_box_fit_mode';
|
||||
static const String _keyAutoPlayNextEpisode = 'auto_play_next_episode';
|
||||
static const String _keyUseExoPlayer = 'use_exoplayer';
|
||||
static const String _keyAlwaysKeepSidebarOpen = 'always_keep_sidebar_open';
|
||||
@@ -1041,6 +1042,15 @@ class SettingsService extends BaseSharedPreferencesService {
|
||||
return prefs.getDouble(_keyDefaultPlaybackSpeed) ?? 1.0; // Default: normal speed
|
||||
}
|
||||
|
||||
// Default BoxFit Mode (0=contain, 1=cover, 2=fill)
|
||||
Future<void> setDefaultBoxFitMode(int mode) async {
|
||||
await prefs.setInt(_keyDefaultBoxFitMode, mode.clamp(0, 2));
|
||||
}
|
||||
|
||||
int getDefaultBoxFitMode() {
|
||||
return prefs.getInt(_keyDefaultBoxFitMode) ?? 0; // Default: contain
|
||||
}
|
||||
|
||||
// Auto-Play Next Episode
|
||||
Future<void> setAutoPlayNextEpisode(bool enabled) async {
|
||||
await prefs.setBool(_keyAutoPlayNextEpisode, enabled);
|
||||
@@ -1244,6 +1254,7 @@ class SettingsService extends BaseSharedPreferencesService {
|
||||
prefs.remove(_keyMatchContentFrameRate),
|
||||
prefs.remove(_keyTunneledPlayback),
|
||||
prefs.remove(_keyDefaultPlaybackSpeed),
|
||||
prefs.remove(_keyDefaultBoxFitMode),
|
||||
prefs.remove(_keyAutoPlayNextEpisode),
|
||||
prefs.remove(_keyUseExoPlayer),
|
||||
prefs.remove(_keyAlwaysKeepSidebarOpen),
|
||||
|
||||
@@ -21,7 +21,7 @@ class VideoFilterManager {
|
||||
final int selectedMediaIndex;
|
||||
|
||||
/// BoxFit mode state: 0=contain (letterbox), 1=cover (fill screen), 2=fill (stretch)
|
||||
int _boxFitMode = 0;
|
||||
int _boxFitMode;
|
||||
|
||||
/// Store the boxFitMode before entering PiP so it can be restored
|
||||
int? _prePipBoxFitMode;
|
||||
@@ -41,7 +41,10 @@ class VideoFilterManager {
|
||||
/// Debounced video filter update with leading edge execution
|
||||
late final Debounce _debouncedUpdateVideoFilter;
|
||||
|
||||
VideoFilterManager({required this.player, required this.availableVersions, required this.selectedMediaIndex}) {
|
||||
/// Callback invoked when boxFitMode changes, for external persistence
|
||||
final void Function(int mode)? onBoxFitModeChanged;
|
||||
|
||||
VideoFilterManager({required this.player, required this.availableVersions, required this.selectedMediaIndex, int initialBoxFitMode = 0, this.onBoxFitModeChanged}) : _boxFitMode = initialBoxFitMode {
|
||||
_debouncedUpdateVideoFilter = debounce(
|
||||
updateVideoFilter,
|
||||
const Duration(milliseconds: 50),
|
||||
@@ -59,6 +62,7 @@ class VideoFilterManager {
|
||||
/// Cycle through BoxFit modes: contain → cover → fill → contain (for button)
|
||||
void cycleBoxFitMode() {
|
||||
_boxFitMode = (_boxFitMode + 1) % 3;
|
||||
onBoxFitModeChanged?.call(_boxFitMode);
|
||||
updateVideoFilter();
|
||||
}
|
||||
|
||||
@@ -73,6 +77,7 @@ class VideoFilterManager {
|
||||
/// Toggle between contain and cover modes only (for pinch gesture)
|
||||
void toggleContainCover() {
|
||||
_boxFitMode = _boxFitMode == 0 ? 1 : 0;
|
||||
onBoxFitModeChanged?.call(_boxFitMode);
|
||||
updateVideoFilter();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user