Add "Source" tab to Podcast modal and wire up select API request.
This commit is contained in:
parent
b0ab0916ae
commit
e3dfe85653
|
@ -125,6 +125,9 @@ return static function (RouteCollectorProxy $group) {
|
|||
$group->post('/podcasts/art', Controller\Api\Stations\Podcasts\Art\PostArtAction::class)
|
||||
->setName('api:stations:podcasts:new-art');
|
||||
|
||||
$group->get('/podcasts/playlists', Controller\Api\Stations\Podcasts\PlaylistsAction::class)
|
||||
->setName('api:stations:podcasts:playlists');
|
||||
|
||||
$group->group(
|
||||
'/podcast/{podcast_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
:language-options="languageOptions"
|
||||
/>
|
||||
|
||||
<podcast-form-source
|
||||
:form="form"
|
||||
/>
|
||||
|
||||
<podcast-common-artwork
|
||||
v-model="form.artwork_file"
|
||||
:artwork-src="record.links.art"
|
||||
|
@ -26,6 +30,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import PodcastFormBasicInfo from './PodcastForm/BasicInfo.vue';
|
||||
import PodcastFormSource from './PodcastForm/Source.vue';
|
||||
import PodcastCommonArtwork from './Common/Artwork.vue';
|
||||
import mergeExisting from "~/functions/mergeExisting";
|
||||
import {baseEditModalProps, ModalFormTemplateRef, useBaseEditModal} from "~/functions/useBaseEditModal";
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
<template>
|
||||
<tab
|
||||
:label="$gettext('Source')"
|
||||
:item-header-class="tabClass"
|
||||
>
|
||||
<div class="row g-3">
|
||||
<form-group-multi-check
|
||||
id="edit_form_source"
|
||||
class="col-md-12"
|
||||
:field="v$.source"
|
||||
:options="sourceOptions"
|
||||
stacked
|
||||
radio
|
||||
:label="$gettext('Source')"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<section
|
||||
v-show="form.source === 'playlist'"
|
||||
class="card mb-3"
|
||||
role="region"
|
||||
>
|
||||
<div class="card-header text-bg-primary">
|
||||
<h2 class="card-title">
|
||||
{{ $gettext('Playlist-Based Podcast') }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>
|
||||
{{
|
||||
$gettext('Playlist-based podcasts will automatically sync with the contents of a playlist, creating new podcast episodes for any media added to the playlist.')
|
||||
}}
|
||||
</p>
|
||||
|
||||
<loading :loading="playlistsLoading">
|
||||
<div class="row g-3 mb-3">
|
||||
<form-group-select
|
||||
id="form_edit_playlist_id"
|
||||
class="col-md-12"
|
||||
:field="v$.playlist_id"
|
||||
:options="playlistOptions"
|
||||
:label="$gettext('Select Playlist')"
|
||||
/>
|
||||
|
||||
<form-group-checkbox
|
||||
id="form_edit_playlist_auto_publish"
|
||||
class="col-md-12"
|
||||
:field="v$.playlist_auto_publish"
|
||||
:label="$gettext('Automatically Publish New Episodes')"
|
||||
:description="$gettext('Whether new episodes should be marked as published or held for review as unpublished.')"
|
||||
/>
|
||||
</div>
|
||||
</loading>
|
||||
</div>
|
||||
</section>
|
||||
</tab>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import FormGroupSelect from "~/components/Form/FormGroupSelect.vue";
|
||||
import {useVModel} from "@vueuse/core";
|
||||
import {useVuelidateOnFormTab} from "~/functions/useVuelidateOnFormTab";
|
||||
import {required} from "@vuelidate/validators";
|
||||
import Tab from "~/components/Common/Tab.vue";
|
||||
import FormGroupMultiCheck from "~/components/Form/FormGroupMultiCheck.vue";
|
||||
import FormGroupCheckbox from "~/components/Form/FormGroupCheckbox.vue";
|
||||
import {useTranslate} from "~/vendor/gettext.ts";
|
||||
import {onMounted, ref, shallowRef} from "vue";
|
||||
import {useAxios} from "~/vendor/axios.ts";
|
||||
import objectToFormOptions from "~/functions/objectToFormOptions.ts";
|
||||
import {getStationApiUrl} from "~/router.ts";
|
||||
import Loading from "~/components/Common/Loading.vue";
|
||||
|
||||
const props = defineProps({
|
||||
form: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:form']);
|
||||
const form = useVModel(props, 'form', emit);
|
||||
|
||||
const {v$, tabClass} = useVuelidateOnFormTab(
|
||||
{
|
||||
source: {required},
|
||||
playlist_id: {},
|
||||
playlist_auto_publish: {}
|
||||
},
|
||||
form,
|
||||
{
|
||||
source: 'manual',
|
||||
playlist_id: null,
|
||||
playlist_auto_publish: true,
|
||||
}
|
||||
);
|
||||
|
||||
const {$gettext} = useTranslate();
|
||||
|
||||
const sourceOptions = [
|
||||
{
|
||||
value: 'manual',
|
||||
text: $gettext('Manually Add Episodes'),
|
||||
description: $gettext('Create podcast episodes independent of your station\'s media collection.')
|
||||
},
|
||||
{
|
||||
value: 'playlist',
|
||||
text: $gettext('Synchronize with Playlist'),
|
||||
description: $gettext('Automatically create new podcast episodes when media is added to a specified playlist.')
|
||||
}
|
||||
];
|
||||
|
||||
const playlistsLoading = ref(true);
|
||||
const playlistOptions = shallowRef([]);
|
||||
|
||||
const {axios} = useAxios();
|
||||
const playlistsApiUrl = getStationApiUrl('/podcasts/playlists');
|
||||
|
||||
const loadPlaylists = () => {
|
||||
axios.get(playlistsApiUrl.value).then((resp) => {
|
||||
playlistOptions.value = objectToFormOptions(resp.data);
|
||||
}).finally(() => {
|
||||
playlistsLoading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(loadPlaylists);
|
||||
</script>
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\Api\Stations\Podcasts;
|
||||
|
||||
use App\Container\EntityManagerAwareTrait;
|
||||
use App\Controller\SingleActionInterface;
|
||||
use App\Entity\Enums\PlaylistSources;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
final class PlaylistsAction implements SingleActionInterface
|
||||
{
|
||||
use EntityManagerAwareTrait;
|
||||
|
||||
public function __invoke(
|
||||
ServerRequest $request,
|
||||
Response $response,
|
||||
array $params
|
||||
): ResponseInterface {
|
||||
$playlistsRaw = $this->em->createQuery(
|
||||
<<<'DQL'
|
||||
SELECT sp.id, sp.name
|
||||
FROM App\Entity\StationPlaylist sp
|
||||
WHERE sp.station = :station
|
||||
AND sp.source = :sourceSongs
|
||||
DQL
|
||||
)->setParameter('station', $request->getStation())
|
||||
->setParameter('sourceSongs', PlaylistSources::Songs->value)
|
||||
->getArrayResult();
|
||||
|
||||
return $response->withJson(
|
||||
array_column($playlistsRaw, 'name', 'id')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -302,6 +302,12 @@ final class PodcastsController extends AbstractApiCrudController
|
|||
unset($data['categories']);
|
||||
}
|
||||
|
||||
if (isset($data['playlist_id'])) {
|
||||
$data['playlist'] = $data['playlist_id'];
|
||||
unset($data['playlist_id']);
|
||||
}
|
||||
|
||||
|
||||
$record = parent::fromArray($data, $record, $context);
|
||||
|
||||
if (null !== $newCategories) {
|
||||
|
|
Loading…
Reference in New Issue