front:add playlist cart popover button to request access to playlist files

This commit is contained in:
Petitminion 2025-05-01 13:52:57 +02:00
parent cb014118a2
commit 6629e37e02
6 changed files with 83 additions and 4 deletions

View File

@ -24846,6 +24846,9 @@ components:
type: string type: string
format: uri format: uri
readOnly: true readOnly: true
library_followed:
type: boolean
readOnly: true
required: required:
- actor - actor
- album_covers - album_covers
@ -24854,6 +24857,7 @@ components:
- fid - fid
- is_playable - is_playable
- library - library
- library_followed
- modification_date - modification_date
- name - name
- tracks_count - tracks_count

View File

@ -35,6 +35,7 @@ class PlaylistSerializer(serializers.ModelSerializer):
is_playable = serializers.SerializerMethodField() is_playable = serializers.SerializerMethodField()
actor = APIActorSerializer(read_only=True) actor = APIActorSerializer(read_only=True)
library = serializers.SerializerMethodField() library = serializers.SerializerMethodField()
library_followed = serializers.SerializerMethodField()
class Meta: class Meta:
model = models.Playlist model = models.Playlist
@ -53,6 +54,7 @@ class PlaylistSerializer(serializers.ModelSerializer):
"actor", "actor",
"description", "description",
"library", "library",
"library_followed",
) )
read_only_fields = ["uuid", "fid", "modification_date", "creation_date"] read_only_fields = ["uuid", "fid", "modification_date", "creation_date"]
@ -63,6 +65,15 @@ class PlaylistSerializer(serializers.ModelSerializer):
else: else:
return None return None
@extend_schema_field(OpenApiTypes.BOOL)
def get_library_followed(self, obj):
if lib_follow := obj.library.received_follows.filter(
actor=self.context["request"].user.actor
):
return lib_follow.approved
else:
return None
@extend_schema_field(OpenApiTypes.BOOL) @extend_schema_field(OpenApiTypes.BOOL)
def get_is_playable(self, obj): def get_is_playable(self, obj):
return getattr(obj, "is_playable_by_actor", False) return getattr(obj, "is_playable_by_actor", False)

View File

@ -72,7 +72,8 @@ const {
enqueue, enqueue,
enqueueNext, enqueueNext,
replacePlay, replacePlay,
isLoading isLoading,
requestPlaylistUploadsAccess
} = usePlayOptions(props) } = usePlayOptions(props)
const { report, getReportableObjects } = useReport() const { report, getReportableObjects } = useReport()
@ -98,10 +99,50 @@ const labels = computed(() => ({
? t('components.audio.PlayButton.button.playArtist') ? t('components.audio.PlayButton.button.playArtist')
: props.playlist : props.playlist
? t('components.audio.PlayButton.button.playPlaylist') ? t('components.audio.PlayButton.button.playPlaylist')
: t('components.audio.PlayButton.button.playTracks') : t('components.audio.PlayButton.button.playTracks'),
PlaylistUploadAlreadyFollowed: t('components.audio.PlayButton.button.playPlaylist'),
PlaylistUploadPending:t('components.audio.PlayButton.button.PlaylistUploadPending'),
PlaylistUploadAccess: t('components.audio.PlayButton.button.PlaylistUploadAccess'),
PlaylistUploadTooltip: t('components.audio.PlayButton.button.PlaylistUploadTooltip')
})) }))
const isOpen = ref(false) const isOpen = ref(false)
const playlistFollowInfo = computed(() => {
const playlist = props.playlist;
if (!playlist) return null;
const followed = playlist.library_followed;
if (followed === true) {
return {
label: labels.value.PlaylistUploadAlreadyFollowed,
tooltip: labels.value.PlaylistUploadTooltip,
icon: 'bi-check-circle',
disabled: true
};
}
if (followed === false) {
return {
label: labels.value.PlaylistUploadPending,
tooltip: labels.value.PlaylistUploadTooltip,
icon: 'bi-hourglass-split',
disabled: true
};
}
// Assume null/undefined means not yet requested
return {
label: labels.value.PlaylistUploadAccess,
tooltip: labels.value.PlaylistUploadTooltip,
icon: 'bi-eye-slash',
disabled: false,
action: requestPlaylistUploadsAccess
};
});
</script> </script>
<template> <template>
@ -226,6 +267,15 @@ const isOpen = ref(false)
> >
{{ obj.label }} {{ obj.label }}
</PopoverItem> </PopoverItem>
<PopoverItem
v-if="playlist && playlistFollowInfo"
:title="playlistFollowInfo.tooltip"
:icon="playlistFollowInfo.icon"
:disabled="playlistFollowInfo.disabled"
@click.stop.prevent="playlistFollowInfo.action "
>
{{ playlistFollowInfo.label }}
</PopoverItem>
</template> </template>
</Popover> </Popover>
<Button <Button

View File

@ -200,6 +200,14 @@ export default (props: PlayOptionsProps) => {
return replacePlay(index) return replacePlay(index)
} }
const requestPlaylistUploadsAccess = async (playlist: Playlist) => {
const libresponse = await axios.get(props.playlist?.library)
const response = await axios.post('federation/follows/library', {
params: { target: libresponse.data.results.uuid }
});
return response;
};
return { return {
playable, playable,
filterableArtist, filterableArtist,
@ -208,6 +216,7 @@ export default (props: PlayOptionsProps) => {
enqueueNext, enqueueNext,
replacePlay, replacePlay,
activateTrack, activateTrack,
isLoading isLoading,
requestPlaylistUploadsAccess
} }
} }

View File

@ -8513,6 +8513,7 @@ export interface components {
description?: string | null; description?: string | null;
/** Format: uri */ /** Format: uri */
readonly library: string; readonly library: string;
readonly library_followed: boolean;
}; };
PlaylistAddManyRequest: { PlaylistAddManyRequest: {
tracks: number[]; tracks: number[];

View File

@ -483,6 +483,10 @@
"playArtist": "Play artist", "playArtist": "Play artist",
"playNext": "Play next", "playNext": "Play next",
"playNow": "Play now", "playNow": "Play now",
"PlaylistUploadAlreadyFollowed": "The owner of the playlist granted you access to his playlist's files",
"PlaylistUploadTooltip": "This only applies to files owned by the playlist actor. If you want to get access to all the files, think to buy them to support your favorites artists",
"PlaylistUploadPending": "You've already requested access to the playlist files",
"PlaylistUploadAccess": "Request access to the files from this playlist",
"playPlaylist": "Play playlist", "playPlaylist": "Play playlist",
"playTrack": "Play track", "playTrack": "Play track",
"playTracks": "Play tracks", "playTracks": "Play tracks",