front:add playlist cart popover button to request access to playlist files
This commit is contained in:
parent
cb014118a2
commit
6629e37e02
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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[];
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue