mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-13 17:30:31 -07:00
feat: Customizable shortcuts/hotkeys (#439)
This implements the logic for allowing hotkeys with modifiers. Implemented globalhotkeys and videocontrol hotkeys Also implements saving the forward backwards seconds to the user. Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
parent
23385d8e62
commit
fa30e634b4
29 changed files with 1360 additions and 162 deletions
|
|
@ -1,9 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:async/async.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fladder/models/account_model.dart';
|
||||
import 'package:fladder/models/settings/video_player_settings.dart';
|
||||
import 'package:fladder/providers/settings/video_player_settings_provider.dart';
|
||||
import 'package:fladder/providers/user_provider.dart';
|
||||
import 'package:fladder/providers/video_player_provider.dart';
|
||||
import 'package:fladder/util/input_handler.dart';
|
||||
import 'package:fladder/util/localization_helper.dart';
|
||||
|
|
@ -48,35 +51,12 @@ class _VideoPlayerSeekIndicatorState extends ConsumerState<VideoPlayerSeekIndica
|
|||
});
|
||||
}
|
||||
|
||||
bool _onKey(KeyEvent value) {
|
||||
if (value is KeyRepeatEvent) {
|
||||
if (value.logicalKey == LogicalKeyboardKey.arrowLeft) {
|
||||
seekBack();
|
||||
return true;
|
||||
}
|
||||
if (value.logicalKey == LogicalKeyboardKey.arrowRight) {
|
||||
seekForward();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (value is KeyDownEvent) {
|
||||
if (value.logicalKey == LogicalKeyboardKey.arrowLeft) {
|
||||
seekBack();
|
||||
return true;
|
||||
}
|
||||
if (value.logicalKey == LogicalKeyboardKey.arrowRight) {
|
||||
seekForward();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InputHandler(
|
||||
autoFocus: true,
|
||||
onKeyEvent: (node, event) => _onKey(event) ? KeyEventResult.handled : KeyEventResult.ignored,
|
||||
keyMap: ref.watch(videoPlayerSettingsProvider.select((value) => value.currentShortcuts)),
|
||||
keyMapResult: (result) => _onKey(result),
|
||||
child: IgnorePointer(
|
||||
child: AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 500),
|
||||
|
|
@ -108,6 +88,29 @@ class _VideoPlayerSeekIndicatorState extends ConsumerState<VideoPlayerSeekIndica
|
|||
);
|
||||
}
|
||||
|
||||
void seekBack({int seconds = -10}) => onSeekStart(seconds);
|
||||
void seekForward({int seconds = 30}) => onSeekStart(seconds);
|
||||
bool _onKey(VideoHotKeys value) {
|
||||
switch (value) {
|
||||
case VideoHotKeys.seekForward:
|
||||
seekForward();
|
||||
return true;
|
||||
case VideoHotKeys.seekBack:
|
||||
seekBack();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void seekBack() {
|
||||
final seconds = -ref.read(userProvider
|
||||
.select((value) => (value?.userSettings?.skipBackDuration ?? UserSettings().skipBackDuration).inSeconds));
|
||||
onSeekStart(seconds);
|
||||
}
|
||||
|
||||
void seekForward() {
|
||||
final seconds = ref.read(userProvider
|
||||
.select((value) => (value?.userSettings?.skipForwardDuration ?? UserSettings().skipForwardDuration).inSeconds));
|
||||
onSeekStart(seconds);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:iconsax_plus/iconsax_plus.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:iconsax_plus/iconsax_plus.dart';
|
||||
|
||||
import 'package:fladder/providers/settings/video_player_settings_provider.dart';
|
||||
import 'package:fladder/util/list_padding.dart';
|
||||
|
|
@ -19,6 +19,8 @@ class VideoVolumeSlider extends ConsumerStatefulWidget {
|
|||
class _VideoVolumeSliderState extends ConsumerState<VideoVolumeSlider> {
|
||||
bool sliderActive = false;
|
||||
|
||||
double? previousVolume;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final volume = ref.watch(videoPlayerSettingsProvider.select((value) => value.volume));
|
||||
|
|
@ -27,7 +29,12 @@ class _VideoVolumeSliderState extends ConsumerState<VideoVolumeSlider> {
|
|||
children: [
|
||||
IconButton(
|
||||
icon: Icon(volumeIcon(volume)),
|
||||
onPressed: () => ref.read(videoPlayerSettingsProvider.notifier).setVolume(0),
|
||||
onPressed: () {
|
||||
if (volume != 0) {
|
||||
previousVolume = volume;
|
||||
}
|
||||
ref.read(videoPlayerSettingsProvider.notifier).setVolume(volume == 0 ? (previousVolume ?? 100) : 0);
|
||||
},
|
||||
),
|
||||
AnimatedSize(
|
||||
duration: const Duration(milliseconds: 250),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue