Newer
Older
<template>
<tr :class="rowClass" v-bind="attrs">
<td>
<router-link
:to="{
name: 'show-episode',
params: { showId: timeslot.showId, episodeId: timeslot.id },
}"
class="tw-text-inherit tw-flex tw-gap-3 tw-items-center hocus:tw-underline hocus:tw-outline-none"
:title="t('showTimeslots.editDescription')"
>
<div
class="tw-w-12 tw-flex-none tw-aspect-square rounded-lg tw-bg-gray-400 tw-overflow-hidden"
>
<img
v-if="noteImage"
class="tw-object-cover tw-h-full tw-w-full tw-max-w-full tw-max-h-full"
:src="noteImage.image"
sizes="100px"
:srcset="
noteImage.thumbnails
.filter(({ width, height }) => width === height)
.map(({ width, url }) => `${url} ${width}w`)
.join(',')
"
alt=""
/>
</div>
<span class="tw-truncate tw-max-w-[200px]">
<template v-if="!isLoadingNote">
<template v-if="note">
{{ note.title }}
</template>
<span v-else class="tw-text-sm tw-text-gray-500">
{{ t('noneSetMasculine') }}
</span>
</template>
</td>
<td>
{{ prettyDateTime(timeslot.start) }}
</td>
<td>
{{ secondsToDurationString(duration) }}
<AStatus
class="tw-text-xs"
rounded
:is-warning="playlistState.state !== 'ok'"
:is-success="playlistState.state === 'ok'"
>
{{ t(`playlist.state.${playlistState.state}.title`) }}
</AStatus>
</td>
</tr>
</template>
<script lang="ts" setup>
import { useObjectFromStore } from '@rokoli/bnb/drf'
import { parseISO } from 'date-fns'
import { computed, useAttrs } from 'vue'
import { useI18n } from '@/i18n'
import { TimeSlot } from '@/types'
import { useNoteStore } from '@/stores/notes'
import { useImage } from '@/stores/images'
import { usePretty } from '@/mixins/prettyDate'
import { calculateDurationSeconds, secondsToDurationString } from '@/util'
import { usePlaylistStore } from '@/stores'
import { usePlaylistState } from '@/stores/playlists'
import AStatus from '@/components/generic/AStatus.vue'
defineOptions({
compatConfig: { MODE: 3 },
inheritAttrs: false,
ATTR_FALSE_VALUE: false,
})
const props = defineProps<{
timeslot: TimeSlot
}>()
const attrs = useAttrs()
const { t } = useI18n()
const { prettyDateTime } = usePretty()
const playlistStore = usePlaylistStore()
const noteStore = useNoteStore()
const { obj: note, isLoading: isLoadingNote } = useObjectFromStore(
() => props.timeslot.noteId,
noteStore,
)
const noteImage = useImage(computed(() => note.value?.imageId ?? null))
const duration = computed(() => calculateDurationSeconds(props.timeslot.start, props.timeslot.end))
const { obj: playlist } = useObjectFromStore(() => props.timeslot.playlistId, playlistStore)
const playlistState = usePlaylistState(playlist, duration)
const rowClass = computed(() => {
const now = new Date()
const startDate = parseISO(props.timeslot.start)
const endDate = new Date(startDate.getTime() + duration.value * 1000)
return { 'tw-opacity-50': now > endDate }