@@ -12,6 +12,7 @@ import 'package:chewie/src/models/option_item.dart';
12
12
import 'package:chewie/src/models/subtitle_model.dart' ;
13
13
import 'package:chewie/src/notifiers/index.dart' ;
14
14
import 'package:flutter/material.dart' ;
15
+ import 'package:flutter/services.dart' ;
15
16
import 'package:provider/provider.dart' ;
16
17
import 'package:video_player/video_player.dart' ;
17
18
@@ -49,16 +50,36 @@ class _MaterialDesktopControlsState extends State<MaterialDesktopControls>
49
50
50
51
late VideoPlayerController controller;
51
52
ChewieController ? _chewieController;
53
+ late final FocusNode _focusNode;
52
54
53
55
// We know that _chewieController is set in didChangeDependencies
54
56
ChewieController get chewieController => _chewieController! ;
55
57
56
58
@override
57
59
void initState () {
58
60
super .initState ();
61
+ _focusNode = FocusNode ();
62
+ _focusNode.requestFocus ();
59
63
notifier = Provider .of <PlayerNotifier >(context, listen: false );
60
64
}
61
65
66
+ void _handleKeyPress (event) {
67
+ if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey .space) {
68
+ _playPause ();
69
+ } else if (event is KeyDownEvent &&
70
+ event.logicalKey == LogicalKeyboardKey .arrowRight) {
71
+ _seekForward ();
72
+ } else if (event is KeyDownEvent &&
73
+ event.logicalKey == LogicalKeyboardKey .arrowLeft) {
74
+ _seekBackward ();
75
+ } else if (event is KeyDownEvent &&
76
+ event.logicalKey == LogicalKeyboardKey .escape) {
77
+ if (chewieController.isFullScreen) {
78
+ _onExpandCollapse ();
79
+ }
80
+ }
81
+ }
82
+
62
83
@override
63
84
Widget build (BuildContext context) {
64
85
if (_latestValue.hasError) {
@@ -75,39 +96,44 @@ class _MaterialDesktopControlsState extends State<MaterialDesktopControls>
75
96
);
76
97
}
77
98
78
- return MouseRegion (
79
- onHover: (_) {
80
- _cancelAndRestartTimer ();
81
- },
82
- child: GestureDetector (
83
- onTap: () => _cancelAndRestartTimer (),
84
- child: AbsorbPointer (
85
- absorbing: notifier.hideStuff,
86
- child: Stack (
87
- children: [
88
- if (_displayBufferingIndicator)
89
- _chewieController? .bufferingBuilder? .call (context) ??
90
- const Center (
91
- child: CircularProgressIndicator (),
92
- )
93
- else
94
- _buildHitArea (),
95
- Column (
96
- mainAxisAlignment: MainAxisAlignment .end,
97
- children: < Widget > [
98
- if (_subtitleOn)
99
- Transform .translate (
100
- offset: Offset (
101
- 0.0 ,
102
- notifier.hideStuff ? barHeight * 0.8 : 0.0 ,
99
+ return KeyboardListener (
100
+ focusNode: _focusNode,
101
+ onKeyEvent: _handleKeyPress,
102
+ child: MouseRegion (
103
+ onHover: (_) {
104
+ _focusNode.requestFocus ();
105
+ _cancelAndRestartTimer ();
106
+ },
107
+ child: GestureDetector (
108
+ onTap: () => _cancelAndRestartTimer (),
109
+ child: AbsorbPointer (
110
+ absorbing: notifier.hideStuff,
111
+ child: Stack (
112
+ children: [
113
+ if (_displayBufferingIndicator)
114
+ _chewieController? .bufferingBuilder? .call (context) ??
115
+ const Center (
116
+ child: CircularProgressIndicator (),
117
+ )
118
+ else
119
+ _buildHitArea (),
120
+ Column (
121
+ mainAxisAlignment: MainAxisAlignment .end,
122
+ children: < Widget > [
123
+ if (_subtitleOn)
124
+ Transform .translate (
125
+ offset: Offset (
126
+ 0.0 ,
127
+ notifier.hideStuff ? barHeight * 0.8 : 0.0 ,
128
+ ),
129
+ child: _buildSubtitles (
130
+ context, chewieController.subtitle! ),
103
131
),
104
- child:
105
- _buildSubtitles (context, chewieController.subtitle! ),
106
- ),
107
- _buildBottomBar (context),
108
- ],
109
- ),
110
- ],
132
+ _buildBottomBar (context),
133
+ ],
134
+ ),
135
+ ],
136
+ ),
111
137
),
112
138
),
113
139
),
@@ -117,6 +143,7 @@ class _MaterialDesktopControlsState extends State<MaterialDesktopControls>
117
143
@override
118
144
void dispose () {
119
145
_dispose ();
146
+ _focusNode.dispose ();
120
147
super .dispose ();
121
148
}
122
149
@@ -566,6 +593,36 @@ class _MaterialDesktopControlsState extends State<MaterialDesktopControls>
566
593
});
567
594
}
568
595
596
+ void _seekBackward () {
597
+ _seekRelative (
598
+ const Duration (
599
+ seconds: - 10 ,
600
+ ),
601
+ );
602
+ }
603
+
604
+ void _seekForward () {
605
+ _seekRelative (
606
+ const Duration (
607
+ seconds: 10 ,
608
+ ),
609
+ );
610
+ }
611
+
612
+ void _seekRelative (Duration relativeSeek) {
613
+ _cancelAndRestartTimer ();
614
+ final position = _latestValue.position + relativeSeek;
615
+ final duration = _latestValue.duration;
616
+
617
+ if (position < Duration .zero) {
618
+ controller.seekTo (Duration .zero);
619
+ } else if (position > duration) {
620
+ controller.seekTo (duration);
621
+ } else {
622
+ controller.seekTo (position);
623
+ }
624
+ }
625
+
569
626
Widget _buildProgressBar () {
570
627
return Expanded (
571
628
child: MaterialVideoProgressBar (
@@ -592,8 +649,9 @@ class _MaterialDesktopControlsState extends State<MaterialDesktopControls>
592
649
playedColor: Theme .of (context).colorScheme.secondary,
593
650
handleColor: Theme .of (context).colorScheme.secondary,
594
651
bufferedColor:
595
- Theme .of (context).colorScheme.surface.withOpacity (0.5 ),
596
- backgroundColor: Theme .of (context).disabledColor.withOpacity (.5 ),
652
+ Theme .of (context).colorScheme.surface.withValues (alpha: 0.5 ),
653
+ backgroundColor:
654
+ Theme .of (context).disabledColor.withValues (alpha: 0.5 ),
597
655
),
598
656
draggableProgressBar: chewieController.draggableProgressBar,
599
657
),
0 commit comments