mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-07-20 02:54:17 +01:00
fix: remove song from playlist
This commit is contained in:
@@ -21,6 +21,7 @@ import { CreatePlaylistModal } from "@/components/music/CreatePlaylistModal";
|
|||||||
import { MusicTrackItem } from "@/components/music/MusicTrackItem";
|
import { MusicTrackItem } from "@/components/music/MusicTrackItem";
|
||||||
import { PlaylistPickerSheet } from "@/components/music/PlaylistPickerSheet";
|
import { PlaylistPickerSheet } from "@/components/music/PlaylistPickerSheet";
|
||||||
import { TrackOptionsSheet } from "@/components/music/TrackOptionsSheet";
|
import { TrackOptionsSheet } from "@/components/music/TrackOptionsSheet";
|
||||||
|
import { useRemoveFromPlaylist } from "@/hooks/usePlaylistMutations";
|
||||||
import { downloadTrack, getLocalPath } from "@/providers/AudioStorage";
|
import { downloadTrack, getLocalPath } from "@/providers/AudioStorage";
|
||||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||||
import { useMusicPlayer } from "@/providers/MusicPlayerProvider";
|
import { useMusicPlayer } from "@/providers/MusicPlayerProvider";
|
||||||
@@ -46,6 +47,8 @@ export default function PlaylistDetailScreen() {
|
|||||||
const [createPlaylistOpen, setCreatePlaylistOpen] = useState(false);
|
const [createPlaylistOpen, setCreatePlaylistOpen] = useState(false);
|
||||||
const [isDownloading, setIsDownloading] = useState(false);
|
const [isDownloading, setIsDownloading] = useState(false);
|
||||||
|
|
||||||
|
const removeFromPlaylist = useRemoveFromPlaylist();
|
||||||
|
|
||||||
const handleTrackOptionsPress = useCallback((track: BaseItemDto) => {
|
const handleTrackOptionsPress = useCallback((track: BaseItemDto) => {
|
||||||
setSelectedTrack(track);
|
setSelectedTrack(track);
|
||||||
setTrackOptionsOpen(true);
|
setTrackOptionsOpen(true);
|
||||||
@@ -59,6 +62,15 @@ export default function PlaylistDetailScreen() {
|
|||||||
setCreatePlaylistOpen(true);
|
setCreatePlaylistOpen(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleRemoveFromPlaylist = useCallback(() => {
|
||||||
|
if (selectedTrack?.Id && playlistId) {
|
||||||
|
removeFromPlaylist.mutate({
|
||||||
|
playlistId,
|
||||||
|
entryIds: [selectedTrack.PlaylistItemId ?? selectedTrack.Id],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [selectedTrack, playlistId, removeFromPlaylist]);
|
||||||
|
|
||||||
const { data: playlist, isLoading: loadingPlaylist } = useQuery({
|
const { data: playlist, isLoading: loadingPlaylist } = useQuery({
|
||||||
queryKey: ["music-playlist", playlistId, user?.Id],
|
queryKey: ["music-playlist", playlistId, user?.Id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
@@ -269,6 +281,8 @@ export default function PlaylistDetailScreen() {
|
|||||||
setOpen={setTrackOptionsOpen}
|
setOpen={setTrackOptionsOpen}
|
||||||
track={selectedTrack}
|
track={selectedTrack}
|
||||||
onAddToPlaylist={handleAddToPlaylist}
|
onAddToPlaylist={handleAddToPlaylist}
|
||||||
|
playlistId={playlistId}
|
||||||
|
onRemoveFromPlaylist={handleRemoveFromPlaylist}
|
||||||
/>
|
/>
|
||||||
<PlaylistPickerSheet
|
<PlaylistPickerSheet
|
||||||
open={playlistPickerOpen}
|
open={playlistPickerOpen}
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ interface Props {
|
|||||||
setOpen: (open: boolean) => void;
|
setOpen: (open: boolean) => void;
|
||||||
track: BaseItemDto | null;
|
track: BaseItemDto | null;
|
||||||
onAddToPlaylist: () => void;
|
onAddToPlaylist: () => void;
|
||||||
|
playlistId?: string;
|
||||||
|
onRemoveFromPlaylist?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TrackOptionsSheet: React.FC<Props> = ({
|
export const TrackOptionsSheet: React.FC<Props> = ({
|
||||||
@@ -49,6 +51,8 @@ export const TrackOptionsSheet: React.FC<Props> = ({
|
|||||||
setOpen,
|
setOpen,
|
||||||
track,
|
track,
|
||||||
onAddToPlaylist,
|
onAddToPlaylist,
|
||||||
|
playlistId,
|
||||||
|
onRemoveFromPlaylist,
|
||||||
}) => {
|
}) => {
|
||||||
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
|
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
|
||||||
const [api] = useAtom(apiAtom);
|
const [api] = useAtom(apiAtom);
|
||||||
@@ -132,6 +136,13 @@ export const TrackOptionsSheet: React.FC<Props> = ({
|
|||||||
}, 300);
|
}, 300);
|
||||||
}, [onAddToPlaylist, setOpen]);
|
}, [onAddToPlaylist, setOpen]);
|
||||||
|
|
||||||
|
const handleRemoveFromPlaylist = useCallback(() => {
|
||||||
|
if (onRemoveFromPlaylist) {
|
||||||
|
onRemoveFromPlaylist();
|
||||||
|
setOpen(false);
|
||||||
|
}
|
||||||
|
}, [onRemoveFromPlaylist, setOpen]);
|
||||||
|
|
||||||
const handleDownload = useCallback(async () => {
|
const handleDownload = useCallback(async () => {
|
||||||
if (!track?.Id || !api || !user?.Id || isAlreadyDownloaded) return;
|
if (!track?.Id || !api || !user?.Id || isAlreadyDownloaded) return;
|
||||||
|
|
||||||
@@ -298,6 +309,21 @@ export const TrackOptionsSheet: React.FC<Props> = ({
|
|||||||
</Text>
|
</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{playlistId && (
|
||||||
|
<>
|
||||||
|
<View style={styles.separator} />
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={handleRemoveFromPlaylist}
|
||||||
|
className='flex-row items-center px-4 py-3.5'
|
||||||
|
>
|
||||||
|
<Ionicons name='trash-outline' size={22} color='#ef4444' />
|
||||||
|
<Text className='text-red-500 ml-4 text-base'>
|
||||||
|
{t("music.track_options.remove_from_playlist")}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<View style={styles.separator} />
|
<View style={styles.separator} />
|
||||||
|
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
|||||||
@@ -136,6 +136,9 @@ export const useRemoveFromPlaylist = () => {
|
|||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: ["music-playlist", variables.playlistId],
|
queryKey: ["music-playlist", variables.playlistId],
|
||||||
});
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: ["music-playlist-tracks", variables.playlistId],
|
||||||
|
});
|
||||||
if (variables.playlistName) {
|
if (variables.playlistName) {
|
||||||
toast.success(
|
toast.success(
|
||||||
t("music.playlists.removed_from", { name: variables.playlistName }),
|
t("music.playlists.removed_from", { name: variables.playlistName }),
|
||||||
|
|||||||
@@ -653,7 +653,8 @@
|
|||||||
"go_to_artist": "Go to Artist",
|
"go_to_artist": "Go to Artist",
|
||||||
"go_to_album": "Go to Album",
|
"go_to_album": "Go to Album",
|
||||||
"add_to_favorites": "Add to Favorites",
|
"add_to_favorites": "Add to Favorites",
|
||||||
"remove_from_favorites": "Remove from Favorites"
|
"remove_from_favorites": "Remove from Favorites",
|
||||||
|
"remove_from_playlist": "Remove from Playlist"
|
||||||
},
|
},
|
||||||
"playlists": {
|
"playlists": {
|
||||||
"create_playlist": "Create Playlist",
|
"create_playlist": "Create Playlist",
|
||||||
|
|||||||
Reference in New Issue
Block a user