fix(player): persist shader hotkey toggles

close #1105
This commit is contained in:
edde746
2026-05-23 01:37:57 +02:00
parent 1a73fc585b
commit 3a042d79f6
3 changed files with 70 additions and 37 deletions
@@ -28,44 +28,32 @@ extension _PlexVideoControlsTrackMethods on _PlexVideoControlsState {
final shaderService = widget.shaderService;
if (shaderService == null || !shaderService.isSupported) return;
if (shaderService.currentPreset.isEnabled) {
// Currently active - disable temporarily
unawaited(
shaderService
.applyPreset(ShaderPreset.none)
.then((_) {
if (!mounted) return;
// ignore: no-empty-block - setState triggers rebuild to reflect disabled shader
_setControlsState(() {});
widget.onShaderChanged?.call();
})
.catchError((Object e, StackTrace st) {
appLogger.w('Failed to disable shader', error: e, stackTrace: st);
}),
);
} else {
// Currently off - restore saved preset
final shaderProvider = context.read<ShaderProvider>();
final saved = shaderProvider.savedPreset;
final allPresets = shaderProvider.allPresets;
final targetPreset = saved.isEnabled
? saved
: allPresets.firstWhere((p) => p.isEnabled, orElse: () => allPresets[1]);
unawaited(
shaderService
.applyPreset(targetPreset)
.then((_) {
if (!mounted) return;
shaderProvider.setCurrentPreset(targetPreset);
// ignore: no-empty-block - setState triggers rebuild to reflect restored shader
_setControlsState(() {});
widget.onShaderChanged?.call();
})
.catchError((Object e, StackTrace st) {
appLogger.w('Failed to apply shader preset', error: e, stackTrace: st);
}),
);
final shaderProvider = context.read<ShaderProvider>();
final targetPreset = resolveShaderTogglePreset(
currentPreset: shaderService.currentPreset,
savedPreset: shaderProvider.savedPreset,
allPresets: shaderProvider.allPresets,
);
if (targetPreset.isEnabled && widget.isAmbientLightingEnabled) {
widget.onToggleAmbientLighting?.call();
}
unawaited(
shaderService
.applyPreset(targetPreset)
.then((_) async {
if (!mounted) return;
await shaderProvider.setPreset(targetPreset);
if (!mounted) return;
// ignore: no-empty-block - setState triggers rebuild to reflect shader changes
_setControlsState(() {});
widget.onShaderChanged?.call();
})
.catchError((Object e, StackTrace st) {
appLogger.w('Failed to toggle shader preset', error: e, stackTrace: st);
}),
);
}
void _nextAudioTrack() {
@@ -76,6 +76,17 @@ part 'parts/playback_input.dart';
part 'parts/track_controls.dart';
part 'parts/visibility.dart';
@visibleForTesting
ShaderPreset resolveShaderTogglePreset({
required ShaderPreset currentPreset,
required ShaderPreset savedPreset,
required List<ShaderPreset> allPresets,
}) {
if (currentPreset.isEnabled) return ShaderPreset.none;
if (savedPreset.isEnabled) return savedPreset;
return allPresets.firstWhere((p) => p.isEnabled, orElse: () => ShaderPreset.nvscalerDefault);
}
@visibleForTesting
({
List<MediaVersion> availableVersions,
+34
View File
@@ -3,12 +3,46 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:plezy/media/media_source_info.dart';
import 'package:plezy/media/media_version.dart';
import 'package:plezy/models/shader_preset.dart';
import 'package:plezy/widgets/video_controls/video_controls.dart';
import 'package:plezy/widgets/video_controls/painters/buffer_range_painter.dart';
import 'package:plezy/widgets/video_controls/widgets/mobile_skip_zones.dart';
import 'package:plezy/widgets/video_controls/widgets/timeline_slider.dart';
void main() {
group('resolveShaderTogglePreset', () {
test('turns shaders off when a shader is currently active', () {
final result = resolveShaderTogglePreset(
currentPreset: ShaderPreset.nvscalerDefault,
savedPreset: ShaderPreset.nvscalerDefault,
allPresets: ShaderPreset.allPresets,
);
expect(result, ShaderPreset.none);
});
test('restores the saved preset when shaders are currently off', () {
final saved = ShaderPreset.artcnnPreset(ArtCNNModel.c4f16, ArtCNNVariant.neutral);
final result = resolveShaderTogglePreset(
currentPreset: ShaderPreset.none,
savedPreset: saved,
allPresets: ShaderPreset.allPresets,
);
expect(result, saved);
});
test('falls back to the first enabled preset when no shader is saved', () {
final result = resolveShaderTogglePreset(
currentPreset: ShaderPreset.none,
savedPreset: ShaderPreset.none,
allPresets: const [ShaderPreset.none, ShaderPreset.nvscalerDefault],
);
expect(result, ShaderPreset.nvscalerDefault);
});
});
group('effectiveVersionQualityControls', () {
test('clears switchable version and quality state during offline playback', () {
final version = MediaVersion(id: 'v1', videoResolution: '1080');