mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-30 13:19:44 +02:00
178 lines
5.4 KiB
Dart
178 lines
5.4 KiB
Dart
import 'package:audio_service/audio_service.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:spotiflac_android/l10n/l10n.dart';
|
|
import 'package:spotiflac_android/providers/library_collections_provider.dart';
|
|
import 'package:spotiflac_android/providers/music_player_provider.dart';
|
|
import 'package:spotiflac_android/theme/cover_palette.dart';
|
|
import 'package:spotiflac_android/theme/mornye_theme.dart';
|
|
import 'package:spotiflac_android/widgets/mornye_context_menu.dart';
|
|
|
|
/// Navigation for the title/artist, separate from playback and file actions.
|
|
class MornyePlayerNavigationMenu extends StatelessWidget {
|
|
const MornyePlayerNavigationMenu({super.key, required this.mediaItem});
|
|
|
|
final MediaItem mediaItem;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final theme = MornyeTheme.fromContext(context, brightness: Brightness.dark);
|
|
final art = mediaItem.artUri;
|
|
final source = art?.scheme == 'file' ? art!.toFilePath() : art?.toString();
|
|
return Theme(
|
|
data: theme.copyWith(
|
|
colorScheme: theme.colorScheme.copyWith(primary: Colors.grey),
|
|
),
|
|
child: CoverPaletteBuilder(
|
|
imageSource: source,
|
|
builder: (context, _) {
|
|
final dominant = HSLColor.fromColor(
|
|
source == null
|
|
? Colors.grey
|
|
: CoverPalette.sourceColor(source, Brightness.dark) ??
|
|
Colors.grey,
|
|
);
|
|
final surface = dominant
|
|
.withSaturation(dominant.saturation.clamp(0.0, 0.28))
|
|
.withLightness(0.28)
|
|
.toColor();
|
|
return Theme(
|
|
data: theme.copyWith(
|
|
colorScheme: theme.colorScheme.copyWith(
|
|
surfaceContainerHigh: surface,
|
|
),
|
|
),
|
|
child: MornyeContextMenu(
|
|
inheritSurface: true,
|
|
dense: true,
|
|
groups: [
|
|
[
|
|
if ((mediaItem.artist ?? '').trim().isNotEmpty)
|
|
MornyeMenuAction(
|
|
icon: CupertinoIcons.mic,
|
|
label: context.l10n.mornyeGoToArtist,
|
|
subtitle: mediaItem.artist,
|
|
onPressed: () => Navigator.of(context).pop('artist'),
|
|
),
|
|
if ((mediaItem.album ?? '').trim().isNotEmpty)
|
|
MornyeMenuAction(
|
|
icon: CupertinoIcons.square_stack,
|
|
label: context.l10n.homeGoToAlbum,
|
|
subtitle: mediaItem.album,
|
|
onPressed: () => Navigator.of(context).pop('album'),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// A floating menu that inherits the player's dark appearance.
|
|
class MornyePlayerActionsSheet extends ConsumerWidget {
|
|
const MornyePlayerActionsSheet({
|
|
super.key,
|
|
required this.mediaItem,
|
|
this.sleepTimerSubtitle,
|
|
});
|
|
|
|
final MediaItem mediaItem;
|
|
final String? sleepTimerSubtitle;
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final track = ref.watch(playerCollectionTrackProvider(mediaItem)).value;
|
|
final loved = ref.watch(
|
|
libraryCollectionsProvider.select(
|
|
(state) => track != null && state.isLoved(track),
|
|
),
|
|
);
|
|
return MornyeContextMenu(
|
|
dense: true,
|
|
quickActions: [
|
|
_action(
|
|
context,
|
|
'favorite',
|
|
loved ? context.l10n.mornyeFavorited : context.l10n.mornyeFavorite,
|
|
CupertinoIcons.star_fill,
|
|
selected: loved,
|
|
),
|
|
_action(
|
|
context,
|
|
'share',
|
|
context.l10n.trackMetadataShare,
|
|
CupertinoIcons.share_solid,
|
|
),
|
|
],
|
|
groups: [
|
|
[
|
|
_action(
|
|
context,
|
|
'playlist',
|
|
context.l10n.collectionAddToPlaylist,
|
|
CupertinoIcons.text_badge_plus,
|
|
),
|
|
],
|
|
[
|
|
if ((mediaItem.album ?? '').trim().isNotEmpty)
|
|
_action(
|
|
context,
|
|
'album',
|
|
context.l10n.homeGoToAlbum,
|
|
CupertinoIcons.square_stack,
|
|
subtitle: mediaItem.album,
|
|
),
|
|
if ((mediaItem.artist ?? '').trim().isNotEmpty)
|
|
_action(
|
|
context,
|
|
'artist',
|
|
context.l10n.mornyeGoToArtist,
|
|
CupertinoIcons.mic,
|
|
subtitle: mediaItem.artist,
|
|
),
|
|
_action(
|
|
context,
|
|
'details',
|
|
context.l10n.nowPlayingDetails,
|
|
CupertinoIcons.info,
|
|
),
|
|
],
|
|
[
|
|
_action(
|
|
context,
|
|
'sleepTimer',
|
|
context.l10n.nowPlayingSleepTimer,
|
|
CupertinoIcons.moon_zzz,
|
|
subtitle: sleepTimerSubtitle,
|
|
),
|
|
_action(
|
|
context,
|
|
'external',
|
|
context.l10n.nowPlayingOpenInExternalPlayer,
|
|
CupertinoIcons.arrow_up_right_square,
|
|
),
|
|
],
|
|
],
|
|
);
|
|
}
|
|
|
|
MornyeMenuAction _action(
|
|
BuildContext context,
|
|
String value,
|
|
String label,
|
|
IconData icon, {
|
|
String? subtitle,
|
|
bool selected = false,
|
|
}) => MornyeMenuAction(
|
|
icon: icon,
|
|
label: label,
|
|
subtitle: subtitle,
|
|
selected: selected,
|
|
onPressed: () => Navigator.of(context).pop(value),
|
|
);
|
|
}
|