mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-14 00:15:17 +00:00
feat: right click to open track option
This commit is contained in:
parent
d4f99ec899
commit
1540999f50
@ -78,6 +78,31 @@ class AdaptivePopSheetList<T> extends StatelessWidget {
|
||||
'Either icon or child must be provided',
|
||||
);
|
||||
|
||||
Future<T?> showPopupMenu(BuildContext context, RelativeRect position) {
|
||||
final mediaQuery = MediaQuery.of(context);
|
||||
|
||||
return showMenu<T>(
|
||||
context: context,
|
||||
useRootNavigator: useRootNavigator,
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: mediaQuery.size.height * 0.6,
|
||||
),
|
||||
position: position,
|
||||
items: children
|
||||
.map(
|
||||
(item) => PopupMenuItem<T>(
|
||||
padding: EdgeInsets.zero,
|
||||
enabled: false,
|
||||
child: _AdaptivePopSheetListItem<T>(
|
||||
item: item,
|
||||
onSelected: onSelected,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final mediaQuery = MediaQuery.of(context);
|
||||
|
@ -14,7 +14,6 @@ import 'package:spotube/components/shared/heart_button.dart';
|
||||
import 'package:spotube/components/shared/image/universal_image.dart';
|
||||
import 'package:spotube/extensions/context.dart';
|
||||
import 'package:spotube/models/local_track.dart';
|
||||
import 'package:spotube/models/spotube_track.dart';
|
||||
import 'package:spotube/provider/authentication_provider.dart';
|
||||
import 'package:spotube/provider/blacklist_provider.dart';
|
||||
import 'package:spotube/provider/download_manager_provider.dart';
|
||||
@ -40,9 +39,11 @@ class TrackOptions extends HookConsumerWidget {
|
||||
final Track track;
|
||||
final bool userPlaylist;
|
||||
final String? playlistId;
|
||||
final ObjectRef<ValueChanged<RelativeRect>?>? showMenuCbRef;
|
||||
const TrackOptions({
|
||||
Key? key,
|
||||
required this.track,
|
||||
this.showMenuCbRef,
|
||||
this.userPlaylist = false,
|
||||
this.playlistId,
|
||||
}) : super(key: key);
|
||||
@ -114,11 +115,7 @@ class TrackOptions extends HookConsumerWidget {
|
||||
return downloadManager.getProgressNotifier(spotubeTrack);
|
||||
});
|
||||
|
||||
return ListTileTheme(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: AdaptivePopSheetList<TrackOptionValue>(
|
||||
final adaptivePopSheetList = AdaptivePopSheetList<TrackOptionValue>(
|
||||
onSelected: (value) async {
|
||||
switch (value) {
|
||||
case TrackOptionValue.delete:
|
||||
@ -203,8 +200,7 @@ class TrackOptions extends HookConsumerWidget {
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: UniversalImage(
|
||||
path: TypeConversionUtils.image_X_UrlString(
|
||||
track.album!.images,
|
||||
path: TypeConversionUtils.image_X_UrlString(track.album!.images,
|
||||
placeholder: ImagePlaceholder.albumArt),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
@ -317,7 +313,18 @@ class TrackOptions extends HookConsumerWidget {
|
||||
),
|
||||
]
|
||||
},
|
||||
);
|
||||
|
||||
//! This is the most ANTI pattern I've ever done, but it works
|
||||
showMenuCbRef?.value = (relativeRect) {
|
||||
adaptivePopSheetList.showPopupMenu(context, relativeRect);
|
||||
};
|
||||
|
||||
return ListTileTheme(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: adaptivePopSheetList,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@ -57,10 +58,24 @@ class TrackTile extends HookConsumerWidget {
|
||||
[blacklist, track],
|
||||
);
|
||||
|
||||
final showOptionCbRef = useRef<ValueChanged<RelativeRect>?>(null);
|
||||
|
||||
final isPlaying = track.id == playlist.activeTrack?.id;
|
||||
|
||||
return LayoutBuilder(builder: (context, constrains) {
|
||||
return HoverBuilder(
|
||||
return Listener(
|
||||
onPointerDown: (event) {
|
||||
if (event.buttons != kSecondaryMouseButton) return;
|
||||
showOptionCbRef.value?.call(
|
||||
RelativeRect.fromLTRB(
|
||||
event.position.dx,
|
||||
event.position.dy,
|
||||
constrains.maxWidth - event.position.dx,
|
||||
constrains.maxHeight - event.position.dy,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: HoverBuilder(
|
||||
permanentState: isPlaying || constrains.smAndDown ? true : null,
|
||||
builder: (context, isHovering) {
|
||||
return ListTile(
|
||||
@ -69,7 +84,8 @@ class TrackTile extends HookConsumerWidget {
|
||||
onLongPress: onLongPress,
|
||||
enabled: !isBlackListed,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
tileColor: isBlackListed ? theme.colorScheme.errorContainer : null,
|
||||
tileColor:
|
||||
isBlackListed ? theme.colorScheme.errorContainer : null,
|
||||
horizontalTitleGap: 12,
|
||||
leadingAndTrailingTextStyle: theme.textTheme.bodyMedium,
|
||||
leading: Row(
|
||||
@ -220,11 +236,13 @@ class TrackTile extends HookConsumerWidget {
|
||||
track: track,
|
||||
playlistId: playlistId,
|
||||
userPlaylist: userPlaylist,
|
||||
showMenuCbRef: showOptionCbRef,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user