Skip to content
Snippets Groups Projects
Commit 780c698e authored by Konrad Mohrfeldt's avatar Konrad Mohrfeldt :koala:
Browse files

feat: add licensing to media sources

refs #320
parent a080ae54
No related branches found
No related tags found
No related merge requests found
Pipeline #8944 passed
Pipeline: aura-tests

#8945

    ......@@ -91,6 +91,7 @@
    :title="t('media.editor.editMediaSource')"
    :save="save"
    class="tw-w-[90vw] md:tw-w-min"
    @close="resetData"
    >
    <FormTable>
    <template v-if="type === 'file'">
    ......@@ -105,7 +106,13 @@
    </FormGroup>
    </template>
    <FormGroup v-if="type !== 'file'" v-slot="attrs" :label="t('file.duration')" center>
    <FormGroup
    v-if="type !== 'file'"
    v-slot="attrs"
    :label="t('file.duration')"
    center
    :errors="errors.forField('duration')"
    >
    <input
    autofocus
    type="text"
    ......@@ -119,6 +126,12 @@
    </FormGroup>
    </FormTable>
    <hr />
    <section>
    <AAttributionEditor v-model="licensing" :errors="errors.subtree('licensing')" />
    </section>
    <template #footer-buttons-extra="{ isSaving }">
    <div class="tw-ml-auto">
    <button
    ......@@ -159,11 +172,11 @@
    import { useObjectFromStore } from '@rokoli/bnb/drf'
    import { computed, ref } from 'vue'
    import { useCopy } from '@/form'
    import { useCopy, useSaveBehaviour } from '@/form'
    import { useI18n } from '@/i18n'
    import { useFilesStore, useMediaSourceStore } from '@/stores'
    import { useInput } from '@/stores/playout'
    import { FileMetadata, MediaSource } from '@/types'
    import { FileMetadata, MediaSource, MediaSourceUpdateData } from '@/types'
    import { parseTime, secondsToDurationString } from '@/util'
    import SafeHTML from '@/components/generic/SafeHTML'
    import AEditDialog from '@/components/generic/AEditDialog.vue'
    ......@@ -171,6 +184,8 @@ import FormTable from '@/components/generic/FormTable.vue'
    import FormGroup from '@/components/generic/FormGroup.vue'
    import AFileImportLog from '@/components/media/AFileImportLog.vue'
    import AStatus from '@/components/generic/AStatus.vue'
    import { isEqual } from 'lodash'
    import AAttributionEditor from '@/components/license/AAttributionEditor.vue'
    const props = withDefaults(
    defineProps<{
    ......@@ -201,6 +216,8 @@ const title = useCopy(() => file.value?.metadata?.title)
    const artist = useCopy(() => file.value?.metadata?.artist)
    const album = useCopy(() => file.value?.metadata?.album)
    const duration = useCopy(() => props.mediaSource.duration)
    const licensing = useCopy(() => props.mediaSource.licensing)
    const uri = computed(() =>
    props.mediaSource.uri ? new URL(props.mediaSource.uri as string) : null,
    )
    ......@@ -221,6 +238,14 @@ const artistInfo = computed(() => {
    }
    })
    function resetData() {
    title.reset()
    artist.reset()
    album.reset()
    duration.reset()
    licensing.reset()
    }
    function setDuration(event: Event) {
    const value = (event.target as HTMLInputElement).value
    // A duration of zero should be treated as null so that the
    ......@@ -228,9 +253,16 @@ function setDuration(event: Event) {
    duration.value = parseTime(value) || null
    }
    async function save() {
    const { save, errors } = useSaveBehaviour(async () => {
    const mediaSourceData: MediaSourceUpdateData = {}
    if (duration.value !== props.mediaSource.duration) {
    await mediaSourceStore.partialUpdate(props.mediaSource.id, { duration: duration.value })
    mediaSourceData.duration = duration.value
    }
    if (!isEqual(licensing.value, props.mediaSource.licensing)) {
    mediaSourceData.licensing = licensing.value
    }
    if (Object.keys(mediaSourceData).length > 0) {
    await mediaSourceStore.partialUpdate(props.mediaSource.id, mediaSourceData)
    }
    if (file.value) {
    ......@@ -245,7 +277,7 @@ async function save() {
    }
    editDialog.value.close()
    }
    })
    async function remove() {
    isDeleted.value = true
    ......
    ......@@ -132,9 +132,9 @@ const importFile: MediaSourceJobProcessor = async (job: MediaSourceJob, next: ()
    async function makeMediaSourceFromJob(job: MediaSourceJob): Promise<MediaSourceCreateData> {
    const mediaId = (await job.getMedia()).id
    if (job.tankFile) {
    return { mediaId, duration: job.tankFile.duration, fileId: job.tankFile.id }
    return { mediaId, duration: job.tankFile.duration, licensing: null, fileId: job.tankFile.id }
    } else if ('url' in job.data) {
    return { mediaId, duration: null, uri: job.data.url }
    return { mediaId, duration: null, licensing: null, uri: job.data.url }
    } else {
    throw new TypeError('Invalid job type. Cannot convert to media source.')
    }
    ......
    ......@@ -55,8 +55,8 @@ export type ImageUpdateData = Omit<Image, _ImageReadonlyAttrs>
    type _MediaSource = steeringComponents['schemas']['MediaSource']
    export type MediaSource = Required<_MediaSource>
    export type MediaSourceCreateData =
    | Pick<MediaSource, 'mediaId' | 'duration' | 'fileId'>
    | Pick<MediaSource, 'mediaId' | 'duration' | 'uri'>
    | Pick<MediaSource, 'mediaId' | 'duration' | 'licensing' | 'fileId'>
    | Pick<MediaSource, 'mediaId' | 'duration' | 'licensing' | 'uri'>
    export type MediaSourceUpdateData = Partial<MediaSourceCreateData>
    type _Media = steeringComponents['schemas']['Media']
    ......
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Please register or to comment