Skip to content

Commit

Permalink
make screen brightness and volume as a setting
Browse files Browse the repository at this point in the history
make volume and brightness controls relative to current values instead of relative to the position of the finger on the screen
only enable the sliders if the user moved at least 5% of the screen
add icon change depending on the value
fix #604
  • Loading branch information
lamarios committed Oct 5, 2024
1 parent 40bb0de commit a40c3fc
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 64 deletions.
6 changes: 4 additions & 2 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1367,7 +1367,7 @@
"customHeadersExplanation": "Set custom headers to be sent to the invidious server",
"value": "Value",
"testAndAddServer": "Test and add server",
"alsoTestServerConfig":"Also test server configuration, like if thumbnails would display properly",
"alsoTestServerConfig": "Also test server configuration, like if thumbnails would display properly",
"serverAlreadyExists": "Server already exists in settings",
"wrongThumbnailConfiguration": "The server is reachable but is not configured properly, the video and channel thumbnails will not be displayed properly. Disable the server test configuration if you are OK with this, fix your server otherwise",
"openWikiLink": "Open wiki for help",
Expand All @@ -1379,5 +1379,7 @@
"stopTheVideo": "Stop the video",
"stopTheVideoExplanation": "If enabled, the video will be closed, if disabled the video will be simply paused",
"setTimer": "Set timer",
"cancelSleepTimer": "Cancel sleep timer"
"cancelSleepTimer": "Cancel sleep timer",
"screenControls": "Screen controls",
"screenControlsExplanation": "When watching a video in full screen, Vertically dragging from the left or the right will adjust the brightness or volume respectively"
}
61 changes: 30 additions & 31 deletions lib/player/states/player_controls.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'dart:ui';
import 'dart:math';

import 'package:bloc/bloc.dart';
import 'package:clipious/player/models/media_event.dart';
Expand Down Expand Up @@ -194,59 +194,56 @@ class PlayerControlsCubit extends Cubit<PlayerControlsState> {
});
}

Future<void> startBrightnessAdjustments() async {
Future<void> startBrightnessAdjustments(DragStartDetails details) async {
final currentBrightness = await ScreenBrightness().current;
emit(state.copyWith(
systemBrightness: currentBrightness, showBrightnessSlider: true));
systemBrightness: currentBrightness,
screenControlStartValue: currentBrightness,
screenControlStart: details.localPosition.dy));
}

Future<void> updateBrightness(
DragUpdateDetails details, BoxConstraints constraints) async {
// Set upper and lower bounds (75% of the screen for full brightness, bottom 25% for zero brightness)
double upperBound = 0.25; // top 75% is full brightness
double lowerBound = 0.75; // bottom is 0 brightness
// percentage of the screen we moved since we started dragging
double movedBy = (state.screenControlStart - details.localPosition.dy) /
constraints.maxHeight;

// Clamping the brightness based on the drag position
double normalizedPosition =
(details.localPosition.dy / constraints.maxHeight)
.clamp(upperBound, lowerBound);
if (movedBy.abs() > 0.05 || state.showBrightnessSlider) {
double screenBrightness =
min(1, max(0, state.screenControlStartValue + movedBy));

// Linearly interpolate between 1 (full brightness) and 0 (no brightness)
final screenBrightness = lerpDouble(
1, 0, (normalizedPosition - upperBound) / (lowerBound - upperBound))!;

await ScreenBrightness().setScreenBrightness(screenBrightness);
emit(state.copyWith(systemBrightness: screenBrightness));
await ScreenBrightness().setScreenBrightness(screenBrightness);
emit(state.copyWith(
systemBrightness: screenBrightness, showBrightnessSlider: true));
}
}

void stopBrightnessAdjustments() {
emit(state.copyWith(showBrightnessSlider: false));
emit(state.copyWith(showBrightnessSlider: false, screenControlStart: 0));
}

Future<void> startVolumeAdjustments() async {
Future<void> startVolumeAdjustments(DragStartDetails details) async {
await FlutterVolumeController.updateShowSystemUI(false);
final currentVolume = await FlutterVolumeController.getVolume();
emit(state.copyWith(
systemVolume: currentVolume ?? 0, showVolumeSlider: true));
systemVolume: currentVolume ?? 0,
screenControlStartValue: currentVolume ?? 0,
screenControlStart: details.localPosition.dy));
}

Future<void> updateVolume(
DragUpdateDetails details, BoxConstraints constraints) async {
// Set upper and lower bounds (75% of the screen for full volume, bottom 25% for zero volume)
double upperBound = 0.25; // top 75% is full volume
double lowerBound = 0.75; // bottom is 0 volume
// percentage of the screen we moved since we started dragging
double movedBy = (state.screenControlStart - details.localPosition.dy) /
constraints.maxHeight;

// Clamping the volume based on the drag position
double normalizedPosition =
(details.localPosition.dy / constraints.maxHeight)
.clamp(upperBound, lowerBound);
if (movedBy.abs() > 0.05 || state.showVolumeSlider) {
double volume = min(1, max(0, state.screenControlStartValue + movedBy));

// Linearly interpolate between 1 (full volume) and 0 (no volume)
final volume = lerpDouble(
1, 0, (normalizedPosition - upperBound) / (lowerBound - upperBound))!;

await FlutterVolumeController.setVolume(volume);
emit(state.copyWith(systemVolume: volume));
await FlutterVolumeController.setVolume(volume);
emit(state.copyWith(systemVolume: volume, showVolumeSlider: true));
}
}

void stopVolumeAdjustments() {
Expand All @@ -270,6 +267,8 @@ class PlayerControlsState with _$PlayerControlsState {
@Default(0) double doubleTapRewindedOpacity,
@Default(false) bool justDoubleTappedSkip,
@Default(false) bool showSponsorBlocked,
@Default(0) double screenControlStart,
@Default(0) double screenControlStartValue,
// system setting adjustments
@Default(false) bool showBrightnessSlider,
@Default(0) double systemBrightness,
Expand Down
90 changes: 70 additions & 20 deletions lib/player/states/player_controls.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ mixin _$PlayerControlsState {
double get doubleTapRewindedOpacity => throw _privateConstructorUsedError;
bool get justDoubleTappedSkip => throw _privateConstructorUsedError;
bool get showSponsorBlocked => throw _privateConstructorUsedError;
double get screenControlStart => throw _privateConstructorUsedError;
double get screenControlStartValue =>
throw _privateConstructorUsedError; // system setting adjustments
bool get showBrightnessSlider => throw _privateConstructorUsedError;
double get systemBrightness => throw _privateConstructorUsedError;
bool get showVolumeSlider => throw _privateConstructorUsedError;
Expand Down Expand Up @@ -62,6 +65,8 @@ abstract class $PlayerControlsStateCopyWith<$Res> {
double doubleTapRewindedOpacity,
bool justDoubleTappedSkip,
bool showSponsorBlocked,
double screenControlStart,
double screenControlStartValue,
bool showBrightnessSlider,
double systemBrightness,
bool showVolumeSlider,
Expand Down Expand Up @@ -96,6 +101,8 @@ class _$PlayerControlsStateCopyWithImpl<$Res, $Val extends PlayerControlsState>
Object? doubleTapRewindedOpacity = null,
Object? justDoubleTappedSkip = null,
Object? showSponsorBlocked = null,
Object? screenControlStart = null,
Object? screenControlStartValue = null,
Object? showBrightnessSlider = null,
Object? systemBrightness = null,
Object? showVolumeSlider = null,
Expand Down Expand Up @@ -154,6 +161,14 @@ class _$PlayerControlsStateCopyWithImpl<$Res, $Val extends PlayerControlsState>
? _value.showSponsorBlocked
: showSponsorBlocked // ignore: cast_nullable_to_non_nullable
as bool,
screenControlStart: null == screenControlStart
? _value.screenControlStart
: screenControlStart // ignore: cast_nullable_to_non_nullable
as double,
screenControlStartValue: null == screenControlStartValue
? _value.screenControlStartValue
: screenControlStartValue // ignore: cast_nullable_to_non_nullable
as double,
showBrightnessSlider: null == showBrightnessSlider
? _value.showBrightnessSlider
: showBrightnessSlider // ignore: cast_nullable_to_non_nullable
Expand Down Expand Up @@ -196,6 +211,8 @@ abstract class _$$PlayercontrolsStateImplCopyWith<$Res>
double doubleTapRewindedOpacity,
bool justDoubleTappedSkip,
bool showSponsorBlocked,
double screenControlStart,
double screenControlStartValue,
bool showBrightnessSlider,
double systemBrightness,
bool showVolumeSlider,
Expand Down Expand Up @@ -228,6 +245,8 @@ class __$$PlayercontrolsStateImplCopyWithImpl<$Res>
Object? doubleTapRewindedOpacity = null,
Object? justDoubleTappedSkip = null,
Object? showSponsorBlocked = null,
Object? screenControlStart = null,
Object? screenControlStartValue = null,
Object? showBrightnessSlider = null,
Object? systemBrightness = null,
Object? showVolumeSlider = null,
Expand Down Expand Up @@ -286,6 +305,14 @@ class __$$PlayercontrolsStateImplCopyWithImpl<$Res>
? _value.showSponsorBlocked
: showSponsorBlocked // ignore: cast_nullable_to_non_nullable
as bool,
screenControlStart: null == screenControlStart
? _value.screenControlStart
: screenControlStart // ignore: cast_nullable_to_non_nullable
as double,
screenControlStartValue: null == screenControlStartValue
? _value.screenControlStartValue
: screenControlStartValue // ignore: cast_nullable_to_non_nullable
as double,
showBrightnessSlider: null == showBrightnessSlider
? _value.showBrightnessSlider
: showBrightnessSlider // ignore: cast_nullable_to_non_nullable
Expand Down Expand Up @@ -323,6 +350,8 @@ class _$PlayercontrolsStateImpl implements _PlayercontrolsState {
this.doubleTapRewindedOpacity = 0,
this.justDoubleTappedSkip = false,
this.showSponsorBlocked = false,
this.screenControlStart = 0,
this.screenControlStartValue = 0,
this.showBrightnessSlider = false,
this.systemBrightness = 0,
this.showVolumeSlider = false,
Expand Down Expand Up @@ -367,6 +396,13 @@ class _$PlayercontrolsStateImpl implements _PlayercontrolsState {
@override
@JsonKey()
final bool showSponsorBlocked;
@override
@JsonKey()
final double screenControlStart;
@override
@JsonKey()
final double screenControlStartValue;
// system setting adjustments
@override
@JsonKey()
final bool showBrightnessSlider;
Expand All @@ -382,7 +418,7 @@ class _$PlayercontrolsStateImpl implements _PlayercontrolsState {

@override
String toString() {
return 'PlayerControlsState(errored: $errored, position: $position, duration: $duration, buffer: $buffer, fullScreenState: $fullScreenState, displayControls: $displayControls, muted: $muted, buffering: $buffering, draggingPositionSlider: $draggingPositionSlider, doubleTapFastForwardedOpacity: $doubleTapFastForwardedOpacity, doubleTapRewindedOpacity: $doubleTapRewindedOpacity, justDoubleTappedSkip: $justDoubleTappedSkip, showSponsorBlocked: $showSponsorBlocked, showBrightnessSlider: $showBrightnessSlider, systemBrightness: $systemBrightness, showVolumeSlider: $showVolumeSlider, systemVolume: $systemVolume)';
return 'PlayerControlsState(errored: $errored, position: $position, duration: $duration, buffer: $buffer, fullScreenState: $fullScreenState, displayControls: $displayControls, muted: $muted, buffering: $buffering, draggingPositionSlider: $draggingPositionSlider, doubleTapFastForwardedOpacity: $doubleTapFastForwardedOpacity, doubleTapRewindedOpacity: $doubleTapRewindedOpacity, justDoubleTappedSkip: $justDoubleTappedSkip, showSponsorBlocked: $showSponsorBlocked, screenControlStart: $screenControlStart, screenControlStartValue: $screenControlStartValue, showBrightnessSlider: $showBrightnessSlider, systemBrightness: $systemBrightness, showVolumeSlider: $showVolumeSlider, systemVolume: $systemVolume)';
}

@override
Expand Down Expand Up @@ -416,6 +452,11 @@ class _$PlayercontrolsStateImpl implements _PlayercontrolsState {
other.justDoubleTappedSkip == justDoubleTappedSkip) &&
(identical(other.showSponsorBlocked, showSponsorBlocked) ||
other.showSponsorBlocked == showSponsorBlocked) &&
(identical(other.screenControlStart, screenControlStart) ||
other.screenControlStart == screenControlStart) &&
(identical(
other.screenControlStartValue, screenControlStartValue) ||
other.screenControlStartValue == screenControlStartValue) &&
(identical(other.showBrightnessSlider, showBrightnessSlider) ||
other.showBrightnessSlider == showBrightnessSlider) &&
(identical(other.systemBrightness, systemBrightness) ||
Expand All @@ -427,25 +468,28 @@ class _$PlayercontrolsStateImpl implements _PlayercontrolsState {
}

@override
int get hashCode => Object.hash(
runtimeType,
errored,
position,
duration,
buffer,
fullScreenState,
displayControls,
muted,
buffering,
draggingPositionSlider,
doubleTapFastForwardedOpacity,
doubleTapRewindedOpacity,
justDoubleTappedSkip,
showSponsorBlocked,
showBrightnessSlider,
systemBrightness,
showVolumeSlider,
systemVolume);
int get hashCode => Object.hashAll([
runtimeType,
errored,
position,
duration,
buffer,
fullScreenState,
displayControls,
muted,
buffering,
draggingPositionSlider,
doubleTapFastForwardedOpacity,
doubleTapRewindedOpacity,
justDoubleTappedSkip,
showSponsorBlocked,
screenControlStart,
screenControlStartValue,
showBrightnessSlider,
systemBrightness,
showVolumeSlider,
systemVolume
]);

/// Create a copy of PlayerControlsState
/// with the given fields replaced by the non-null parameter values.
Expand All @@ -472,6 +516,8 @@ abstract class _PlayercontrolsState implements PlayerControlsState {
final double doubleTapRewindedOpacity,
final bool justDoubleTappedSkip,
final bool showSponsorBlocked,
final double screenControlStart,
final double screenControlStartValue,
final bool showBrightnessSlider,
final double systemBrightness,
final bool showVolumeSlider,
Expand Down Expand Up @@ -504,6 +550,10 @@ abstract class _PlayercontrolsState implements PlayerControlsState {
@override
bool get showSponsorBlocked;
@override
double get screenControlStart;
@override
double get screenControlStartValue; // system setting adjustments
@override
bool get showBrightnessSlider;
@override
double get systemBrightness;
Expand Down
18 changes: 12 additions & 6 deletions lib/player/views/components/player_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ class PlayerControls extends StatelessWidget {
.select((PlayerCubit cubit) => cubit.state.totalFastForward);
int totalRewind =
context.select((PlayerCubit cubit) => cubit.state.totalRewind);

bool screenControlsEnabled = context.select(
(SettingsCubit settings) => settings.state.screenControls);

String videoTitle = context.select((PlayerCubit cubit) =>
cubit.state.currentlyPlaying?.title ??
cubit.state.offlineCurrentlyPlaying?.title ??
Expand All @@ -265,9 +269,9 @@ class PlayerControls extends StatelessWidget {
var cubit = context.read<PlayerControlsCubit>();

// to allow or not dragging to adjust brightness and volume
var canDragToAdjustDeviceSettings =
var canDragToAdjustDeviceSettings = screenControlsEnabled &&
playerState.fullScreenState == FullScreenState.fullScreen &&
!playerState.displayControls;
!playerState.displayControls;

return BlocListener<PlayerCubit, PlayerState>(
listenWhen: (previous, current) =>
Expand Down Expand Up @@ -352,7 +356,8 @@ class PlayerControls extends StatelessWidget {
canDragToAdjustDeviceSettings
? (details) {
cubit
.startBrightnessAdjustments();
.startBrightnessAdjustments(
details);
}
: null,
onVerticalDragUpdate:
Expand Down Expand Up @@ -386,7 +391,8 @@ class PlayerControls extends StatelessWidget {
canDragToAdjustDeviceSettings
? (details) {
cubit
.startVolumeAdjustments();
.startVolumeAdjustments(
details);
}
: null,
onVerticalDragUpdate:
Expand Down Expand Up @@ -701,7 +707,7 @@ class PlayerControls extends StatelessWidget {
bottom: constraints.maxHeight * 0.15,
right: 20,
child: SystemSettingsSlider(
icon: Icons.brightness_5,
type: SystemSliderType.brightness,
value: playerState.systemBrightness))
.animate(
target: playerState.showBrightnessSlider ? 1 : 0,
Expand All @@ -721,7 +727,7 @@ class PlayerControls extends StatelessWidget {
bottom: constraints.maxHeight * 0.15,
left: 20,
child: SystemSettingsSlider(
icon: Icons.volume_up,
type: SystemSliderType.volume,
value: playerState.systemVolume))
.animate(
target: playerState.showVolumeSlider ? 1 : 0,
Expand Down
Loading

0 comments on commit a40c3fc

Please sign in to comment.