Keyboard support on player

This commit is contained in:
2025-12-16 23:50:04 +08:00
parent 79e0c65f0b
commit c0a495484c

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:drift/drift.dart' as drift; import 'package:drift/drift.dart' as drift;
import 'package:groovybox/data/db.dart' as db; import 'package:groovybox/data/db.dart' as db;
import 'package:groovybox/logic/lyrics_parser.dart'; import 'package:groovybox/logic/lyrics_parser.dart';
@@ -37,7 +38,28 @@ class PlayerScreen extends HookConsumerWidget {
final path = Uri.decodeFull(Uri.parse(media.uri).path); final path = Uri.decodeFull(Uri.parse(media.uri).path);
final metadataAsync = ref.watch(trackMetadataProvider(path)); final metadataAsync = ref.watch(trackMetadataProvider(path));
return Scaffold( return Focus(
autofocus: true,
onKeyEvent: (node, event) {
if (event is KeyDownEvent) {
if (event.logicalKey == LogicalKeyboardKey.space) {
if (player.state.playing) {
player.pause();
} else {
player.play();
}
return KeyEventResult.handled;
} else if (event.logicalKey == LogicalKeyboardKey.bracketLeft) {
player.previous();
return KeyEventResult.handled;
} else if (event.logicalKey == LogicalKeyboardKey.bracketRight) {
player.next();
return KeyEventResult.handled;
}
}
return KeyEventResult.ignored;
},
child: Scaffold(
body: Stack( body: Stack(
children: [ children: [
// Main content (StreamBuilder) // Main content (StreamBuilder)
@@ -94,7 +116,9 @@ class PlayerScreen extends HookConsumerWidget {
], ],
dividerHeight: 0, dividerHeight: 0,
indicatorColor: Colors.transparent, indicatorColor: Colors.transparent,
overlayColor: WidgetStatePropertyAll(Colors.transparent), overlayColor: WidgetStatePropertyAll(
Colors.transparent,
),
splashFactory: NoSplash.splashFactory, splashFactory: NoSplash.splashFactory,
), ),
), ),
@@ -102,6 +126,7 @@ class PlayerScreen extends HookConsumerWidget {
_LyricsRefreshButton(trackPath: path), _LyricsRefreshButton(trackPath: path),
], ],
), ),
),
); );
}, },
); );
@@ -251,7 +276,10 @@ class _PlayerCoverArt extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return metadataAsync.when( return metadataAsync.when(
data: (meta) => Container( data: (meta) => Center(
child: AspectRatio(
aspectRatio: 1,
child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.grey[800], color: Colors.grey[800],
borderRadius: BorderRadius.circular(24), borderRadius: BorderRadius.circular(24),
@@ -271,10 +299,16 @@ class _PlayerCoverArt extends StatelessWidget {
), ),
child: meta.artBytes == null child: meta.artBytes == null
? const Center( ? const Center(
child: Icon(Icons.music_note, size: 80, color: Colors.white54), child: Icon(
Icons.music_note,
size: 80,
color: Colors.white54,
),
) )
: null, : null,
), ),
),
),
loading: () => const Center(child: CircularProgressIndicator()), loading: () => const Center(child: CircularProgressIndicator()),
error: (_, _) => Container( error: (_, _) => Container(
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -994,7 +1028,7 @@ class _PlayerControls extends HookWidget {
), ),
), ),
loading: () => const SizedBox(height: 24), loading: () => const SizedBox(height: 24),
error: (_, __) => const SizedBox.shrink(), error: (_, _) => const SizedBox.shrink(),
), ),
], ],
), ),