fix(Desktop): Fixed some of desktop specific controls (#131)

Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
PartyDonut 2024-11-08 11:58:24 +01:00 committed by GitHub
parent 0b7b73134f
commit 8435a27ed9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 276 additions and 269 deletions

View file

@ -32,10 +32,134 @@ class ItemInfoScreenState extends ConsumerState<ItemInfoScreen> {
AutoDisposeStateNotifierProvider<InformationNotifier, InformationProviderModel> get provider => AutoDisposeStateNotifierProvider<InformationNotifier, InformationProviderModel> get provider =>
informationProvider(widget.item.id); informationProvider(widget.item.id);
FocusNode focusNode = FocusNode();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
Future.microtask(() => ref.read(provider.notifier).getItemInformation(widget.item)); Future.microtask(() {
focusNode.requestFocus();
return ref.read(provider.notifier).getItemInformation(widget.item);
});
}
@override
Widget build(BuildContext context) {
final info = ref.watch(provider);
final videoStreams = (info.model?.videoStreams.map((map) => streamModel("Video", map)) ?? []).toList();
final audioStreams = (info.model?.audioStreams.map((map) => streamModel("Audio", map)) ?? []).toList();
final subStreams = (info.model?.subStreams.map((map) => streamModel("Subtitle", map)) ?? []).toList();
return Dialog(
child: Card(
color: Theme.of(context).colorScheme.surface,
child: Focus(
autofocus: true,
focusNode: focusNode,
onKeyEvent: (node, event) => KeyEventResult.ignored,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
color: Theme.of(context).colorScheme.surface,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Text(
widget.item.name,
style: Theme.of(context).textTheme.titleLarge,
),
),
const Opacity(opacity: 0.3, child: Divider()),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
const Spacer(),
const SizedBox(width: 6),
IconButton(
onPressed: () async {
await Clipboard.setData(ClipboardData(text: info.model.toString()));
if (context.mounted) {
fladderSnackbar(context, title: "Copied to clipboard");
}
},
icon: const Icon(Icons.copy_all_rounded)),
const SizedBox(width: 6),
IconButton(
onPressed: () => ref.read(provider.notifier).getItemInformation(widget.item),
icon: const Icon(IconsaxOutline.refresh),
),
],
),
),
],
),
),
const SizedBox(height: 6),
Flexible(
fit: FlexFit.loose,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
shrinkWrap: true,
children: [
Stack(
alignment: Alignment.center,
children: [
if (info.model != null) ...{
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: double.infinity, child: streamModel("Info", info.model!.baseInformation)),
if ([...videoStreams, ...audioStreams, ...subStreams].isNotEmpty) ...{
const Divider(),
Wrap(
alignment: WrapAlignment.start,
runAlignment: WrapAlignment.start,
crossAxisAlignment: WrapCrossAlignment.start,
runSpacing: 16,
spacing: 16,
children: [
...videoStreams,
...audioStreams,
...subStreams,
],
),
},
],
),
},
AnimatedOpacity(
opacity: info.loading ? 1 : 0,
duration: const Duration(milliseconds: 250),
child: const Center(child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round)),
)
],
),
],
),
),
),
Container(
color: Theme.of(context).colorScheme.surface,
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FilledButton(onPressed: () => Navigator.of(context).pop(), child: Text(context.localized.close))
],
),
),
)
],
),
),
),
);
} }
Widget tileRow(String title, String value) { Widget tileRow(String title, String value) {
@ -103,117 +227,4 @@ class ItemInfoScreenState extends ConsumerState<ItemInfoScreen> {
), ),
); );
} }
@override
Widget build(BuildContext context) {
final info = ref.watch(provider);
final videoStreams = (info.model?.videoStreams.map((map) => streamModel("Video", map)) ?? []).toList();
final audioStreams = (info.model?.audioStreams.map((map) => streamModel("Audio", map)) ?? []).toList();
final subStreams = (info.model?.subStreams.map((map) => streamModel("Subtitle", map)) ?? []).toList();
return Dialog(
child: Card(
color: Theme.of(context).colorScheme.surface,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
color: Theme.of(context).colorScheme.surface,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Text(
widget.item.name,
style: Theme.of(context).textTheme.titleLarge,
),
),
const Opacity(opacity: 0.3, child: Divider()),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
const Spacer(),
const SizedBox(width: 6),
IconButton(
onPressed: () async {
await Clipboard.setData(ClipboardData(text: info.model.toString()));
if (context.mounted) {
fladderSnackbar(context, title: "Copied to clipboard");
}
},
icon: const Icon(Icons.copy_all_rounded)),
const SizedBox(width: 6),
IconButton(
onPressed: () => ref.read(provider.notifier).getItemInformation(widget.item),
icon: const Icon(IconsaxOutline.refresh),
),
],
),
),
],
),
),
const SizedBox(height: 6),
Flexible(
fit: FlexFit.loose,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
shrinkWrap: true,
children: [
Stack(
alignment: Alignment.center,
children: [
if (info.model != null) ...{
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(width: double.infinity, child: streamModel("Info", info.model!.baseInformation)),
if ([...videoStreams, ...audioStreams, ...subStreams].isNotEmpty) ...{
const Divider(),
Wrap(
alignment: WrapAlignment.start,
runAlignment: WrapAlignment.start,
crossAxisAlignment: WrapCrossAlignment.start,
runSpacing: 16,
spacing: 16,
children: [
...videoStreams,
...audioStreams,
...subStreams,
],
),
},
],
),
},
AnimatedOpacity(
opacity: info.loading ? 1 : 0,
duration: const Duration(milliseconds: 250),
child: const Center(child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round)),
)
],
),
],
),
),
),
Container(
color: Theme.of(context).colorScheme.surface,
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FilledButton(onPressed: () => Navigator.of(context).pop(), child: Text(context.localized.close))
],
),
),
)
],
),
),
);
}
} }

View file

@ -42,12 +42,11 @@ class _DefaultTitleBarState extends ConsumerState<DefaultTitleBar> with WindowLi
return SizedBox( return SizedBox(
height: widget.height, height: widget.height,
child: switch (AdaptiveLayout.of(context).platform) { child: switch (AdaptiveLayout.of(context).platform) {
TargetPlatform.android || TargetPlatform.iOS => SizedBox(height: MediaQuery.paddingOf(context).top),
TargetPlatform.windows || TargetPlatform.linux => Row( TargetPlatform.windows || TargetPlatform.linux => Row(
children: [ children: [
Expanded( Expanded(
child: DragToMoveArea( child: DragToMoveArea(
child: Container(
color: Colors.red.withOpacity(0),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
@ -66,7 +65,6 @@ class _DefaultTitleBarState extends ConsumerState<DefaultTitleBar> with WindowLi
), ),
), ),
), ),
),
Row( Row(
children: [ children: [
FutureBuilder( FutureBuilder(
@ -161,13 +159,7 @@ class _DefaultTitleBarState extends ConsumerState<DefaultTitleBar> with WindowLi
), ),
], ],
), ),
TargetPlatform.macOS => const Row( TargetPlatform.macOS => const SizedBox.shrink(),
children: [
Spacer(),
Text("Fladder"),
SizedBox(width: 16),
],
),
_ => Text(widget.label ?? "Fladder"), _ => Text(widget.label ?? "Fladder"),
}, },
); );

View file

@ -283,7 +283,9 @@ class _VideoPlayerNextWrapperState extends ConsumerState<VideoPlayerNextWrapper>
], ],
), ),
), ),
AnimatedFadeSize( IgnorePointer(
ignoring: !show,
child: AnimatedFadeSize(
duration: animSpeed, duration: animSpeed,
child: show child: show
? Padding( ? Padding(
@ -294,13 +296,16 @@ class _VideoPlayerNextWrapperState extends ConsumerState<VideoPlayerNextWrapper>
) )
: const SizedBox.shrink(), : const SizedBox.shrink(),
), ),
),
], ],
), ),
), ),
), ),
), ),
if (AdaptiveLayout.of(context).isDesktop) if (AdaptiveLayout.of(context).isDesktop)
AnimatedOpacity( IgnorePointer(
ignoring: !show,
child: AnimatedOpacity(
duration: animSpeed, duration: animSpeed,
opacity: show ? 1 : 0, opacity: show ? 1 : 0,
child: const Align( child: const Align(
@ -308,6 +313,7 @@ class _VideoPlayerNextWrapperState extends ConsumerState<VideoPlayerNextWrapper>
child: DefaultTitleBar(), child: DefaultTitleBar(),
), ),
), ),
),
], ],
), ),
); );

View file

@ -255,6 +255,7 @@ class _VideoOptionsMobileState extends ConsumerState<VideoOptions> {
ListView itemInfo(ItemBaseModel? currentItem, BuildContext context) { ListView itemInfo(ItemBaseModel? currentItem, BuildContext context) {
return ListView( return ListView(
shrinkWrap: true, shrinkWrap: true,
controller: widget.controller,
children: [ children: [
navTitle(currentItem?.title, currentItem?.subTextShort(context)), navTitle(currentItem?.title, currentItem?.subTextShort(context)),
if (currentItem != null) ...{ if (currentItem != null) ...{

View file

@ -65,13 +65,14 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
if (value.logicalKey == LogicalKeyboardKey.arrowUp) { if (value.logicalKey == LogicalKeyboardKey.arrowUp) {
resetTimer(); resetTimer();
ref.read(videoPlayerSettingsProvider.notifier).steppedVolume(5); ref.read(videoPlayerSettingsProvider.notifier).steppedVolume(5);
return true;
} }
if (value.logicalKey == LogicalKeyboardKey.arrowDown) { if (value.logicalKey == LogicalKeyboardKey.arrowDown) {
resetTimer(); resetTimer();
ref.read(videoPlayerSettingsProvider.notifier).steppedVolume(-5); ref.read(videoPlayerSettingsProvider.notifier).steppedVolume(-5);
}
return true; return true;
} }
}
if (value is KeyDownEvent) { if (value is KeyDownEvent) {
if (value.logicalKey == LogicalKeyboardKey.keyS) { if (value.logicalKey == LogicalKeyboardKey.keyS) {
if (showIntroSkipButton) { if (showIntroSkipButton) {
@ -79,26 +80,31 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
} else if (showCreditSkipButton) { } else if (showCreditSkipButton) {
skipCredits(introSkipModel); skipCredits(introSkipModel);
} }
return true;
} }
if (value.logicalKey == LogicalKeyboardKey.escape) { if (value.logicalKey == LogicalKeyboardKey.escape) {
disableFullscreen(); disableFullscreen();
return true;
} }
if (value.logicalKey == LogicalKeyboardKey.space) { if (value.logicalKey == LogicalKeyboardKey.space) {
ref.read(videoPlayerProvider).playOrPause(); ref.read(videoPlayerProvider).playOrPause();
return true;
} }
if (value.logicalKey == LogicalKeyboardKey.keyF) { if (value.logicalKey == LogicalKeyboardKey.keyF) {
toggleFullScreen(ref); toggleFullScreen(ref);
return true;
} }
if (value.logicalKey == LogicalKeyboardKey.arrowUp) { if (value.logicalKey == LogicalKeyboardKey.arrowUp) {
resetTimer(); resetTimer();
ref.read(videoPlayerSettingsProvider.notifier).steppedVolume(5); ref.read(videoPlayerSettingsProvider.notifier).steppedVolume(5);
return true;
} }
if (value.logicalKey == LogicalKeyboardKey.arrowDown) { if (value.logicalKey == LogicalKeyboardKey.arrowDown) {
resetTimer(); resetTimer();
ref.read(videoPlayerSettingsProvider.notifier).steppedVolume(-5); ref.read(videoPlayerSettingsProvider.notifier).steppedVolume(-5);
}
return true; return true;
} }
}
return false; return false;
} }
@ -115,8 +121,6 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
return InputHandler( return InputHandler(
autoFocus: false, autoFocus: false,
onKeyEvent: (node, event) => _onKey(event) ? KeyEventResult.handled : KeyEventResult.ignored, onKeyEvent: (node, event) => _onKey(event) ? KeyEventResult.handled : KeyEventResult.ignored,
child: Listener(
onPointerSignal: (event) => resetTimer(),
child: PopScope( child: PopScope(
canPop: false, canPop: false,
onPopInvokedWithResult: (didPop, result) { onPopInvokedWithResult: (didPop, result) {
@ -128,9 +132,9 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
onTap: () => toggleOverlay(), onTap: () => toggleOverlay(),
child: MouseRegion( child: MouseRegion(
cursor: showOverlay ? SystemMouseCursors.basic : SystemMouseCursors.none, cursor: showOverlay ? SystemMouseCursors.basic : SystemMouseCursors.none,
onEnter: (event) => toggleOverlay(value: true),
onExit: (event) => toggleOverlay(value: false), onExit: (event) => toggleOverlay(value: false),
onHover: AdaptiveLayout.of(context).isDesktop || kIsWeb ? (event) => toggleOverlay(value: true) : null, onEnter: (event) => toggleOverlay(value: true),
onHover: AdaptiveLayout.of(context).isDesktop ? (event) => toggleOverlay(value: true) : null,
child: Stack( child: Stack(
children: [ children: [
if (player != null) if (player != null)
@ -198,7 +202,6 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
), ),
), ),
), ),
),
); );
} }
@ -236,20 +239,16 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
Colors.black.withOpacity(0), Colors.black.withOpacity(0),
], ],
)), )),
child: Stack( child: Padding(
padding: MediaQuery.paddingOf(context).copyWith(bottom: 0, top: 0),
child: Container(
alignment: Alignment.topCenter,
child: Column(
children: [ children: [
if (AdaptiveLayout.of(context).isDesktop)
const Align( const Align(
alignment: Alignment.topRight, alignment: Alignment.topRight,
child: DefaultTitleBar(), child: DefaultTitleBar(),
), ),
Padding(
padding: MediaQuery.paddingOf(context).copyWith(bottom: 0),
child: Container(
alignment: Alignment.topCenter,
height: 80,
child: Column(
children: [
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 12), padding: const EdgeInsets.symmetric(horizontal: 12),
child: Row( child: Row(
@ -276,8 +275,6 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
), ),
), ),
), ),
],
),
); );
} }