Update API interface and wire up Podcast Episodes for playlist-synced podcasts.
This commit is contained in:
parent
8fa8ab7e26
commit
09d186d506
|
@ -1,9 +1,6 @@
|
|||
<template>
|
||||
<section
|
||||
class="card"
|
||||
role="region"
|
||||
>
|
||||
<div class="card-header text-bg-primary">
|
||||
<card-page>
|
||||
<template #header>
|
||||
<div class="row align-items-center">
|
||||
<div class="col-md-7">
|
||||
<div class="d-flex align-items-center">
|
||||
|
@ -27,9 +24,18 @@
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body buttons">
|
||||
</template>
|
||||
<template
|
||||
v-if="!podcastIsManual"
|
||||
#info
|
||||
>
|
||||
<p class="card-text">
|
||||
{{
|
||||
$gettext('This podcast is automatically synchronized with a playlist. Episodes cannot be manually added or removed via this panel.')
|
||||
}}
|
||||
</p>
|
||||
</template>
|
||||
<template #actions>
|
||||
<router-link
|
||||
class="btn btn-secondary"
|
||||
:to="{name: 'stations:podcasts:index'}"
|
||||
|
@ -39,10 +45,11 @@
|
|||
</router-link>
|
||||
|
||||
<add-button
|
||||
v-if="podcastIsManual"
|
||||
:text="$gettext('Add Episode')"
|
||||
@click="doCreate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<data-table
|
||||
id="station_podcast_episodes"
|
||||
|
@ -74,12 +81,18 @@
|
|||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #cell(podcast_media)="{item}">
|
||||
<template #cell(media)="{item}">
|
||||
<template v-if="item.media">
|
||||
<span>{{ item.media.original_name }}</span>
|
||||
<br>
|
||||
<small>{{ item.media.length_text }}</small>
|
||||
</template>
|
||||
<template v-else-if="item.playlist_media">
|
||||
<span>{{ item.playlist_media.text }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
||||
</template>
|
||||
</template>
|
||||
<template #cell(is_published)="{item}">
|
||||
<span v-if="item.is_published">
|
||||
|
@ -106,6 +119,7 @@
|
|||
{{ $gettext('Edit') }}
|
||||
</button>
|
||||
<button
|
||||
v-if="podcastIsManual"
|
||||
type="button"
|
||||
class="btn btn-danger"
|
||||
@click="doDelete(item.links.self)"
|
||||
|
@ -115,14 +129,12 @@
|
|||
</div>
|
||||
</template>
|
||||
</data-table>
|
||||
</section>
|
||||
</card-page>
|
||||
|
||||
<edit-modal
|
||||
ref="$editEpisodeModal"
|
||||
:podcast="podcast"
|
||||
:create-url="podcast.links.episodes"
|
||||
:new-art-url="podcast.links.episode_new_art"
|
||||
:new-media-url="podcast.links.episode_new_media"
|
||||
:podcast-id="podcast.id"
|
||||
@relist="relist"
|
||||
/>
|
||||
</template>
|
||||
|
@ -134,7 +146,7 @@ import Icon from '~/components/Common/Icon.vue';
|
|||
import AlbumArt from '~/components/Common/AlbumArt.vue';
|
||||
import StationsCommonQuota from "~/components/Stations/Common/Quota.vue";
|
||||
import {useTranslate} from "~/vendor/gettext";
|
||||
import {ref} from "vue";
|
||||
import {computed, ref} from "vue";
|
||||
import AddButton from "~/components/Common/AddButton.vue";
|
||||
import {IconChevronLeft} from "~/components/Common/icons";
|
||||
import useHasDatatable, {DataTableTemplateRef} from "~/functions/useHasDatatable.ts";
|
||||
|
@ -143,6 +155,7 @@ import useConfirmAndDelete from "~/functions/useConfirmAndDelete.ts";
|
|||
import {ApiPodcast} from "~/entities/ApiInterfaces.ts";
|
||||
import useHasEditModal from "~/functions/useHasEditModal.ts";
|
||||
import useStationDateTimeFormatter from "~/functions/useStationDateTimeFormatter.ts";
|
||||
import CardPage from "~/components/Common/CardPage.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
podcast: ApiPodcast
|
||||
|
@ -168,7 +181,7 @@ const fields: DataTableField[] = [
|
|||
sortable: false
|
||||
},
|
||||
{
|
||||
key: 'podcast_media',
|
||||
key: 'media',
|
||||
label: $gettext('File Name'),
|
||||
sortable: false
|
||||
},
|
||||
|
@ -200,6 +213,10 @@ const fields: DataTableField[] = [
|
|||
}
|
||||
];
|
||||
|
||||
const podcastIsManual = computed(() => {
|
||||
return props.podcast.source == 'manual';
|
||||
});
|
||||
|
||||
const $quota = ref<InstanceType<typeof StationsCommonQuota> | null>(null);
|
||||
|
||||
const $datatable = ref<DataTableTemplateRef>(null);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
/>
|
||||
|
||||
<episode-form-media
|
||||
v-if="podcastIsManual"
|
||||
v-model="form.media_file"
|
||||
:record-has-media="record.has_media"
|
||||
:new-media-url="newMediaUrl"
|
||||
|
@ -44,20 +45,18 @@ import Tabs from "~/components/Common/Tabs.vue";
|
|||
|
||||
const props = defineProps({
|
||||
...baseEditModalProps,
|
||||
podcastId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
newArtUrl: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
newMediaUrl: {
|
||||
type: String,
|
||||
podcast: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const newArtUrl = computed(() => props.podcast.links.episode_new_art);
|
||||
const newMediaUrl = computed(() => props.podcast.links.episode_new_media);
|
||||
const podcastIsManual = computed(() => {
|
||||
return props.podcast.source == 'manual';
|
||||
});
|
||||
|
||||
const emit = defineEmits(['relist']);
|
||||
|
||||
const $modal = ref<ModalFormTemplateRef>(null);
|
||||
|
|
|
@ -604,6 +604,9 @@ export interface ApiNowPlayingStationRemote {
|
|||
export type ApiPodcast = HasLinks & {
|
||||
id?: string;
|
||||
storage_location_id?: number;
|
||||
source?: string;
|
||||
playlist_id?: number | null;
|
||||
playlist_auto_publish?: boolean;
|
||||
title?: string;
|
||||
link?: string | null;
|
||||
description?: string;
|
||||
|
@ -637,7 +640,9 @@ export type ApiPodcastEpisode = HasLinks & {
|
|||
is_published?: boolean;
|
||||
publish_at?: number | null;
|
||||
has_media?: boolean;
|
||||
media?: ApiPodcastMedia;
|
||||
playlist_media_id?: string | null;
|
||||
playlist_media?: ApiSong | null;
|
||||
media?: ApiPodcastMedia | null;
|
||||
has_custom_art?: boolean;
|
||||
art?: string | null;
|
||||
art_updated_at?: number;
|
||||
|
|
|
@ -45,6 +45,9 @@ final class PodcastEpisode
|
|||
#[OA\Property]
|
||||
public ?string $playlist_media_id = null;
|
||||
|
||||
#[OA\Property]
|
||||
public ?Song $playlist_media = null;
|
||||
|
||||
#[OA\Property]
|
||||
public ?PodcastMedia $media = null;
|
||||
|
||||
|
|
|
@ -15,6 +15,11 @@ use App\Utilities\Strings;
|
|||
|
||||
final class PodcastEpisodeApiGenerator
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SongApiGenerator $songApiGen
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(
|
||||
PodcastEpisode $record,
|
||||
ServerRequest $request
|
||||
|
@ -43,14 +48,19 @@ final class PodcastEpisodeApiGenerator
|
|||
$playlistMediaRow = $record->getPlaylistMedia();
|
||||
if ($playlistMediaRow instanceof StationMedia) {
|
||||
$return->has_media = true;
|
||||
|
||||
$return->playlist_media = $this->songApiGen->__invoke($playlistMediaRow);
|
||||
$return->playlist_media_id = $playlistMediaRow->getUniqueId();
|
||||
} else {
|
||||
$return->has_media = false;
|
||||
|
||||
$return->playlist_media = null;
|
||||
$return->playlist_media_id = null;
|
||||
}
|
||||
break;
|
||||
|
||||
case PodcastSources::Manual:
|
||||
$return->playlist_media = null;
|
||||
$return->playlist_media_id = null;
|
||||
|
||||
$mediaRow = $record->getMedia();
|
||||
|
|
Loading…
Reference in New Issue