mirror of
https://github.com/R0m1k3/xtremobile.git
synced 2026-10-11 17:29:26 +02:00
v1.1.0: Add remote control/keyboard support for Android TV
- Space/Enter/Select: Toggle play/pause - Left/Right arrows: Seek -10s/+10s (VOD only) - Up/Down arrows: Previous/Next channel (Live TV) - Escape/Back: Exit player - Added favorite button to Live TV channel tiles
This commit is contained in:
1 parent
3cf5aaeb67
commit
ee1152ee95
2 files changed
+68
-1
No files matched your search
@@ -92,6 +92,9 @@ class _NativePlayerScreenState extends ConsumerState<NativePlayerScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// Register keyboard handler for remote control
|
||||
HardwareKeyboard.instance.addHandler(_handleKeyEvent);
|
||||
|
||||
// Only start clock if setting is enabled (will check in build too, but timer can run)
|
||||
_startClock();
|
||||
_currentIndex = widget.initialIndex;
|
||||
@@ -228,6 +231,9 @@ class _NativePlayerScreenState extends ConsumerState<NativePlayerScreen> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// Unregister keyboard handler
|
||||
HardwareKeyboard.instance.removeHandler(_handleKeyEvent);
|
||||
|
||||
// Save resume position before cleanup (only for VOD/Series)
|
||||
_saveResumePositionOnExit();
|
||||
|
||||
@@ -544,6 +550,67 @@ class _NativePlayerScreenState extends ConsumerState<NativePlayerScreen> {
|
||||
_resetControlsTimer();
|
||||
}
|
||||
|
||||
/// Handle keyboard/remote control events
|
||||
bool _handleKeyEvent(KeyEvent event) {
|
||||
if (event is! KeyDownEvent) return false;
|
||||
|
||||
final key = event.logicalKey;
|
||||
|
||||
// Space / Enter / Select - Toggle play/pause
|
||||
if (key == LogicalKeyboardKey.space ||
|
||||
key == LogicalKeyboardKey.enter ||
|
||||
key == LogicalKeyboardKey.select) {
|
||||
_togglePlayPause();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Left Arrow - Seek back 10 seconds
|
||||
if (key == LogicalKeyboardKey.arrowLeft) {
|
||||
if (widget.streamType != StreamType.live) {
|
||||
final newPos = _position - const Duration(seconds: 10);
|
||||
_player.seek(newPos < Duration.zero ? Duration.zero : newPos);
|
||||
_onUserInteraction();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Right Arrow - Seek forward 10 seconds
|
||||
if (key == LogicalKeyboardKey.arrowRight) {
|
||||
if (widget.streamType != StreamType.live) {
|
||||
final newPos = _position + const Duration(seconds: 10);
|
||||
if (newPos < _duration) {
|
||||
_player.seek(newPos);
|
||||
}
|
||||
_onUserInteraction();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Up Arrow - Previous channel (Live only)
|
||||
if (key == LogicalKeyboardKey.arrowUp) {
|
||||
if (widget.streamType == StreamType.live && widget.channels != null) {
|
||||
_playPrevious();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Down Arrow - Next channel (Live only)
|
||||
if (key == LogicalKeyboardKey.arrowDown) {
|
||||
if (widget.streamType == StreamType.live && widget.channels != null) {
|
||||
_playNext();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Escape / Back - Exit player
|
||||
if (key == LogicalKeyboardKey.escape ||
|
||||
key == LogicalKeyboardKey.goBack) {
|
||||
Navigator.of(context).pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ class _MobileSettingsTabState extends ConsumerState<MobileSettingsTab> {
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
'Version 1.0.5',
|
||||
'Version 1.1.0',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: AppColors.textSecondary,
|
||||
|
||||
Reference in new issue
Block a user