Skip to content

Commit

Permalink
Added right click support for opening song context menu #431
Browse files Browse the repository at this point in the history
  • Loading branch information
anandnet committed Feb 10, 2025
1 parent 8da63fd commit e05c0df
Show file tree
Hide file tree
Showing 2 changed files with 227 additions and 181 deletions.
287 changes: 155 additions & 132 deletions lib/ui/widgets/list_widget.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:audio_service/audio_service.dart';
import 'package:flutter/gestures.dart' show kSecondaryMouseButton;
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:widget_marquee/widget_marquee.dart';
Expand Down Expand Up @@ -86,153 +87,175 @@ class ListWidget extends StatelessWidget with RemoveSongFromPlaylistMixin {
physics: isCompleteList
? const BouncingScrollPhysics()
: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) => Slidable(
enabled:
Get.find<SettingsScreenController>().slidableActionEnabled.isTrue,
startActionPane: ActionPane(motion: const DrawerMotion(), children: [
SlidableAction(
onPressed: (context) {
showDialog(
context: context,
builder: (context) =>
AddToPlaylist([items[index] as MediaItem]),
).whenComplete(() => Get.delete<AddToPlaylistController>());
},
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Theme.of(context).textTheme.titleMedium!.color,
icon: Icons.playlist_add,
//label: 'Add to playlist',
),
if (playlist != null && !playlist.isCloudPlaylist)
SlidableAction(
onPressed: (context) {
removeSongFromPlaylist(items[index] as MediaItem, playlist);
},
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Theme.of(context).textTheme.titleMedium!.color,
icon: Icons.delete,
//label: 'delete',
),
]),
endActionPane: ActionPane(motion: const DrawerMotion(), children: [
SlidableAction(
onPressed: (context) {
playerController
.enqueueSong(items[index] as MediaItem)
.whenComplete(() {
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(snackbar(
context, "songEnqueueAlert".tr,
size: SanckBarSize.MEDIUM));
});
},
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Theme.of(context).textTheme.titleMedium!.color,
icon: Icons.merge,
//label: 'Enqueue',
),
SlidableAction(
onPressed: (context) {
playerController.playNext(items[index] as MediaItem);
ScaffoldMessenger.of(context).showSnackBar(snackbar(
context, "${"playnextMsg".tr} ${(items[index] as MediaItem).title}",
size: SanckBarSize.BIG));
},
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Theme.of(context).textTheme.titleMedium!.color,
icon: Icons.next_plan_outlined,
//label: 'Play Next',
),
]),
child: ListTile(
onTap: () {
(isPlaylist || isArtistSongs)
? playerController.playPlayListSong(
List<MediaItem>.from(items), index)
: playerController.pushSongToQueue(items[index] as MediaItem);
},
onLongPress: () async {
itemBuilder: (context, index) => Listener(
onPointerDown: (PointerDownEvent event) {
if (event.buttons == kSecondaryMouseButton) {
//show songinfobotomsheet
showModalBottomSheet(
constraints: const BoxConstraints(maxWidth: 500),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(10.0)),
),
isScrollControlled: true,
context: playerController.homeScaffoldkey.currentState!.context,
//constraints: BoxConstraints(maxHeight:Get.height),
barrierColor: Colors.transparent.withAlpha(100),
builder: (context) => SongInfoBottomSheet(
items[index] as MediaItem,
playlist: playlist,
),
).whenComplete(() => Get.delete<SongInfoController>());
},
contentPadding: const EdgeInsets.only(top: 0, left: 5, right: 30),
leading: ImageWidget(
size: 55,
song: items[index],
),
title: Marquee(
delay: const Duration(milliseconds: 300),
duration: const Duration(seconds: 5),
id: items[index].title.hashCode.toString(),
child: Text(
items[index].title.length > 50
? items[index].title.substring(0, 50)
: items[index].title,
maxLines: 1,
style: Theme.of(context).textTheme.titleMedium,
}
},
child: Slidable(
enabled:
Get.find<SettingsScreenController>().slidableActionEnabled.isTrue,
startActionPane: ActionPane(motion: const DrawerMotion(), children: [
SlidableAction(
onPressed: (context) {
showDialog(
context: context,
builder: (context) =>
AddToPlaylist([items[index] as MediaItem]),
).whenComplete(() => Get.delete<AddToPlaylistController>());
},
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Theme.of(context).textTheme.titleMedium!.color,
icon: Icons.playlist_add,
//label: 'Add to playlist',
),
),
subtitle: Text(
"${items[index].artist}",
maxLines: 1,
style: Theme.of(context).textTheme.titleSmall,
),
trailing: SizedBox(
width: Get.size.width > 800 ? 80 : 40,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (isPlaylist)
Obx(() => playerController.currentSong.value?.id ==
items[index].id
? const Icon(
Icons.equalizer_rounded,
)
: const SizedBox.shrink()),
Text(
items[index].extras!['length'] ?? "",
style: Theme.of(context).textTheme.titleSmall,
),
],
if (playlist != null && !playlist.isCloudPlaylist)
SlidableAction(
onPressed: (context) {
removeSongFromPlaylist(items[index] as MediaItem, playlist);
},
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Theme.of(context).textTheme.titleMedium!.color,
icon: Icons.delete,
//label: 'delete',
),
]),
endActionPane: ActionPane(motion: const DrawerMotion(), children: [
SlidableAction(
onPressed: (context) {
playerController
.enqueueSong(items[index] as MediaItem)
.whenComplete(() {
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(snackbar(
context, "songEnqueueAlert".tr,
size: SanckBarSize.MEDIUM));
});
},
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Theme.of(context).textTheme.titleMedium!.color,
icon: Icons.merge,
//label: 'Enqueue',
),
SlidableAction(
onPressed: (context) {
playerController.playNext(items[index] as MediaItem);
ScaffoldMessenger.of(context).showSnackBar(snackbar(context,
"${"playnextMsg".tr} ${(items[index] as MediaItem).title}",
size: SanckBarSize.BIG));
},
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Theme.of(context).textTheme.titleMedium!.color,
icon: Icons.next_plan_outlined,
//label: 'Play Next',
),
]),
child: ListTile(
onTap: () {
(isPlaylist || isArtistSongs)
? playerController.playPlayListSong(
List<MediaItem>.from(items), index)
: playerController.pushSongToQueue(items[index] as MediaItem);
},
onLongPress: () async {
showModalBottomSheet(
constraints: const BoxConstraints(maxWidth: 500),
shape: const RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(10.0)),
),
if (GetPlatform.isDesktop)
IconButton(
splashRadius: 20,
onPressed: () {
showModalBottomSheet(
constraints: const BoxConstraints(maxWidth: 500),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(10.0)),
),
isScrollControlled: true,
context: playerController
.homeScaffoldkey.currentState!.context,
//constraints: BoxConstraints(maxHeight:Get.height),
barrierColor: Colors.transparent.withAlpha(100),
builder: (context) => SongInfoBottomSheet(
items[index] as MediaItem,
playlist: playlist,
),
).whenComplete(() => Get.delete<SongInfoController>());
},
icon: const Icon(Icons.more_vert))
],
isScrollControlled: true,
context: playerController.homeScaffoldkey.currentState!.context,
//constraints: BoxConstraints(maxHeight:Get.height),
barrierColor: Colors.transparent.withAlpha(100),
builder: (context) => SongInfoBottomSheet(
items[index] as MediaItem,
playlist: playlist,
),
).whenComplete(() => Get.delete<SongInfoController>());
},
contentPadding: const EdgeInsets.only(top: 0, left: 5, right: 30),
leading: ImageWidget(
size: 55,
song: items[index],
),
title: Marquee(
delay: const Duration(milliseconds: 300),
duration: const Duration(seconds: 5),
id: items[index].title.hashCode.toString(),
child: Text(
items[index].title.length > 50
? items[index].title.substring(0, 50)
: items[index].title,
maxLines: 1,
style: Theme.of(context).textTheme.titleMedium,
),
),
subtitle: Text(
"${items[index].artist}",
maxLines: 1,
style: Theme.of(context).textTheme.titleSmall,
),
trailing: SizedBox(
width: Get.size.width > 800 ? 80 : 40,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (isPlaylist)
Obx(() => playerController.currentSong.value?.id ==
items[index].id
? const Icon(
Icons.equalizer_rounded,
)
: const SizedBox.shrink()),
Text(
items[index].extras!['length'] ?? "",
style: Theme.of(context).textTheme.titleSmall,
),
],
),
if (GetPlatform.isDesktop)
IconButton(
splashRadius: 20,
onPressed: () {
showModalBottomSheet(
constraints: const BoxConstraints(maxWidth: 500),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(10.0)),
),
isScrollControlled: true,
context: playerController
.homeScaffoldkey.currentState!.context,
//constraints: BoxConstraints(maxHeight:Get.height),
barrierColor: Colors.transparent.withAlpha(100),
builder: (context) => SongInfoBottomSheet(
items[index] as MediaItem,
playlist: playlist,
),
).whenComplete(
() => Get.delete<SongInfoController>());
},
icon: const Icon(Icons.more_vert))
],
),
),
),
),
Expand Down
Loading

0 comments on commit e05c0df

Please sign in to comment.