feat: persist ambient lighting and make it mutually exclusive with shaders

close #499
This commit is contained in:
edde746
2026-02-20 22:33:00 +01:00
parent d307f8c99d
commit 3bfc24bf9b
3 changed files with 61 additions and 0 deletions
+46
View File
@@ -40,6 +40,7 @@ import '../services/ambient_lighting_service.dart';
import '../services/video_filter_manager.dart';
import '../services/video_pip_manager.dart';
import '../services/pip_service.dart';
import '../models/shader_preset.dart';
import '../services/shader_service.dart';
import '../providers/shader_provider.dart';
import '../providers/user_profile_provider.dart';
@@ -1032,6 +1033,7 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
_videoFilterManager?.ambientLightingService = _ambientLightingService;
await _applySavedShaderPreset();
await _restoreAmbientLighting();
}
}
@@ -1147,6 +1149,39 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
}
}
/// Restore ambient lighting from persisted setting
Future<void> _restoreAmbientLighting() async {
final settings = await SettingsService.getInstance();
if (!settings.getAmbientLighting()) return;
final ambientLighting = _ambientLightingService;
if (ambientLighting == null || !ambientLighting.isSupported) return;
// Same enable logic as _toggleAmbientLighting
final dwidth = await player?.getProperty('dwidth');
final dheight = await player?.getProperty('dheight');
if (dwidth == null || dheight == null) return;
final w = double.tryParse(dwidth);
final h = double.tryParse(dheight);
if (w == null || h == null || h == 0) return;
final videoAspect = w / h;
final playerSize = _videoFilterManager?.playerSize;
if (playerSize == null || playerSize.height == 0) return;
final outputAspect = playerSize.width / playerSize.height;
// Clear shaders — ambient lighting and shaders are mutually exclusive
final shaderProvider = context.read<ShaderProvider>();
if (shaderProvider.isShaderEnabled) {
await _shaderService!.applyPreset(ShaderPreset.none);
shaderProvider.setCurrentPreset(ShaderPreset.none);
}
_videoFilterManager?.resetToContain();
await ambientLighting.enable(videoAspect, outputAspect);
if (mounted) setState(() {});
}
/// Cycle through BoxFit modes: contain → cover → fill → contain (for button)
void _cycleBoxFitMode() {
// Disable ambient lighting when switching boxfit modes
@@ -1190,12 +1225,23 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
if (playerSize == null || playerSize.height == 0) return;
final outputAspect = playerSize.width / playerSize.height;
// Clear shaders — ambient lighting and shaders are mutually exclusive
final shaderProvider = context.read<ShaderProvider>();
if (shaderProvider.isShaderEnabled) {
await _shaderService!.applyPreset(ShaderPreset.none);
shaderProvider.setCurrentPreset(ShaderPreset.none);
}
// Force contain mode when enabling ambient lighting
_videoFilterManager?.resetToContain();
await ambientLighting.enable(videoAspect, outputAspect);
}
// Persist ambient lighting state
final settings = await SettingsService.getInstance();
settings.setAmbientLighting(ambientLighting.isEnabled);
setState(() {});
}
+11
View File
@@ -75,6 +75,7 @@ class SettingsService extends BaseSharedPreferencesService {
static const String _keySelectedExternalPlayer = 'selected_external_player';
static const String _keyCustomExternalPlayers = 'custom_external_players';
static const String _keyConfirmExitOnBack = 'confirm_exit_on_back';
static const String _keyAmbientLighting = 'ambient_lighting';
SettingsService._();
@@ -1117,6 +1118,15 @@ class SettingsService extends BaseSharedPreferencesService {
return prefs.getBool(_keyConfirmExitOnBack) ?? true; // Default: enabled
}
// Ambient Lighting
Future<void> setAmbientLighting(bool enabled) async {
await prefs.setBool(_keyAmbientLighting, enabled);
}
bool getAmbientLighting() {
return prefs.getBool(_keyAmbientLighting) ?? false;
}
// Reset all settings to defaults
Future<void> resetAllSettings() async {
await Future.wait([
@@ -1171,6 +1181,7 @@ class SettingsService extends BaseSharedPreferencesService {
prefs.remove(_keySelectedExternalPlayer),
prefs.remove(_keyCustomExternalPlayers),
prefs.remove(_keyConfirmExitOnBack),
prefs.remove(_keyAmbientLighting),
]);
}
@@ -576,6 +576,10 @@ class _VideoSettingsSheetState extends State<VideoSettingsSheet> {
: null,
trailing: isSelected ? const AppIcon(Symbols.check_rounded, fill: 1, color: Colors.amber) : null,
onTap: () async {
// Disable ambient lighting when selecting a shader
if (preset.type != ShaderPresetType.none && widget.isAmbientLightingEnabled) {
widget.onToggleAmbientLighting?.call();
}
await widget.shaderService!.applyPreset(preset);
await shaderProvider.setPreset(preset);
widget.onShaderChanged?.call();