(), {
isActivity: true,
limit: 9,
itemClasses: '',
- websocketHandlers: () => []
+ websocketHandlers: () => [],
+ title: undefined
})
const store = useStore()
@@ -92,7 +93,7 @@ watch(count, (to) => emit('count', to))
watch(() => props.websocketHandlers.includes('Listen'), (to) => {
if (to) {
- useWebSocketHandler('Listen', (event) => {
+ useWebSocketHandler('Listen', (event: unknown) => {
// Handle WebSocket events for "Listen"
// Add the event to `objects` reactively
@@ -102,10 +103,6 @@ watch(() => props.websocketHandlers.includes('Listen'), (to) => {
if (objects.length > props.limit) {
objects.pop()
}
-
- // Recompute coverUrl for the updated `objects`
- console.log('WebSocket event received:', event)
- console.log('Updated cover URL:', coverUrl.value)
})
}
}, { immediate: true })
@@ -134,8 +131,7 @@ watch(() => props.websocketHandlers.includes('Listen'), (to) => {
({ required: true })
-defineEmits(['created'])
+const emit = defineEmits(['created'])
const newAlbumTitle = ref('')
const isLoading = ref(false)
@@ -58,7 +58,7 @@ const submit = async () => {
diff --git a/front/src/components/channels/AlbumSelect.vue b/front/src/components/channels/AlbumSelect.vue
index a55970128..094061eb1 100644
--- a/front/src/components/channels/AlbumSelect.vue
+++ b/front/src/components/channels/AlbumSelect.vue
@@ -27,7 +27,6 @@ const fetchAlbums = async () => {
}
})
- console.log('I found another album with artist', model.value.channel.artist.name, ':', response.data.results)
albums.value = response.data.results
isLoading.value = false
}
diff --git a/front/src/components/channels/UploadForm.vue b/front/src/components/channels/UploadForm.vue
index e95056aba..742d0f408 100644
--- a/front/src/components/channels/UploadForm.vue
+++ b/front/src/components/channels/UploadForm.vue
@@ -129,10 +129,8 @@ const createEmptyChannel = async () => {
'channels/',
(emptyChannelCreateRequest satisfies operations['create_channel_2']['requestBody']['content']['application/json'])
)
- console.log('Created Channel: ', response.data)
} catch (error) {
errors.value = (error as BackendError).backendErrors
- console.log('Error:', error)
}
}
@@ -149,21 +147,16 @@ const fetchChannels = async () => {
}
// Albums
-const albumSelection = ref<{channel: Channel, albumId: Album['id'] | '', albums: Album[]}>
+const albumSelection = ref<{channel: Channel, albumId: Album['id'] | '', albums: Album[]}>()
-watch(selectedChannel, (channel) =>
- albumSelection.value
- = {
- channel,
- albumId: '',
- albums: []
- }
-)
-
-const channelChange = async (channelId) => {
- selectedChannel.value = channelId
- await fetchAlbums(channelId)
-}
+watch(selectedChannel, channel => {
+ if (!channel) return
+ albumSelection.value = {
+ channel,
+ albumId: '',
+ albums: []
+ }
+})
// Quota and space
//
@@ -412,7 +405,6 @@ const labels = computed(() => ({
}))
const publish = async () => {
- console.log('starting publish...')
isLoading.value = true
errors.value = []
@@ -435,24 +427,17 @@ const publish = async () => {
// headers: { 'Authorization': `Bearer ${store.state.auth.oauth}` }
// })
- console.log('Channels Store Before: ', store.state.channels)
-
// Tell the store that the uploaded files are pending import
store.commit('channels/publish', {
uploads: uploadedFiles.value.map((file) => ({ ...file.response, import_status: 'pending' })),
channel: selectedChannel.value
})
-
- console.log('Channels Store After: ', store.state.channels)
} catch (error) {
// TODO: Use inferred error type instead of typecasting
errors.value = (error as BackendError).backendErrors
- console.log('Error:', error)
}
isLoading.value = false
-
- console.log('...finished publish')
}
defineExpose({
@@ -552,7 +537,7 @@ ChannelCreateRequest: {
v-if="availableChannels.length === 1"
for="channel-dropdown"
>
- {{ t('components.channels.UploadForm.label.channel') }}: {{ selectedChannel?.artist.name }}
+ {{ `${t('components.channels.UploadForm.label.channel')}: ${selectedChannel?.artist.name}` }}
diff --git a/front/src/components/channels/UploadModal.vue b/front/src/components/channels/UploadModal.vue
index b92c30431..4f70bcf98 100644
--- a/front/src/components/channels/UploadModal.vue
+++ b/front/src/components/channels/UploadModal.vue
@@ -18,6 +18,8 @@ const update = (value: boolean) => store.commit('channels/showUploadModal', { sh
const { t } = useI18n()
+const { filter } = defineProps<{ filter: 'podcast' | 'music' }>()
+
const uploadForm = ref()
const statusData = ref()
@@ -50,17 +52,27 @@ const step = ref(1)
const isLoading = ref(false)
const open = ref(false)
+
+const title = computed(() =>
+ [t('components.channels.UploadModal.header'),
+ t('components.channels.UploadModal.header.publish'),
+ t('components.channels.UploadModal.header.uploadFiles'),
+ t('components.channels.UploadModal.header.uploadDetails'),
+ t('components.channels.UploadModal.header.processing')
+ ][step.value]
+)
sortedUniq([12, 25, 50, paginateBy.value]
-
@@ -126,7 +130,7 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
-
+
sortedUniq([12, 25, 50, paginateBy.value]
:class="['ui', { 'loading': isLoading }, 'form']"
>
-
-
+
+
{{ t('components.favorites.List.ordering.label') }}
@@ -153,7 +165,12 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
-
+
{{ t('components.favorites.List.ordering.direction.label') }}
@@ -170,7 +187,12 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
-
+
{{ t('components.favorites.List.pagination.results') }}
@@ -203,13 +225,18 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
:tracks="results"
/>
-
-
+
{{ t('components.favorites.List.empty.noFavorites') }}
-
+
({
const {
isShuffled,
- shuffle,
+ shuffle
} = useQueue()
const isLoading = ref(false)
@@ -150,7 +150,10 @@ const remove = async () => {
-
+
{
v-lazy="store.getters['instance/absoluteUrl'](object.cover.urls.large_square_crop)"
:alt="object.title"
class="channel-image"
- />
+ >
-
- {{ object.title }}
-
+
+
+ {{ object.title }}
+
+
+
+
+
+ {{ momentFormat(new Date(object.release_date ?? '1970-01-01'), 'Y') }}
+
+
+
+
+ {{ t('components.library.AlbumBase.meta.episodes', totalTracks) }}
+
+
+ {{ t('components.library.AlbumBase.meta.tracks', totalTracks) }}
+
+
+
+
+
+
+
+
-
-
-
- {{ momentFormat(new Date(object.release_date ?? '1970-01-01'), 'Y') }}
-
-
-
-
- {{ t('components.library.AlbumBase.meta.episodes', totalTracks) }}
-
-
- {{ t('components.library.AlbumBase.meta.tracks', totalTracks) }}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ t('components.library.AlbumDropdown.button.delete') }}
-
-
-
-
-
-
-
+
+
+
+
+ {{ t('components.library.AlbumDropdown.button.delete') }}
+
+
+
+
+
+
+
+
-
-
-
+
+
+
diff --git a/front/src/components/library/Albums.vue b/front/src/components/library/Albums.vue
index e36ca4ac8..33a0bfa68 100644
--- a/front/src/components/library/Albums.vue
+++ b/front/src/components/library/Albums.vue
@@ -79,7 +79,7 @@ const fetchData = async () => {
page: page.value,
page_size: paginateBy.value,
q: query.value,
- // @ts-ignore
+ // @ts-expect-error TODO: add strict types to useOrdering
ordering: orderingString.value,
playable: true,
tag: tags.value,
diff --git a/front/src/components/library/ArtistBase.vue b/front/src/components/library/ArtistBase.vue
index 5f10e925d..c16da86d0 100644
--- a/front/src/components/library/ArtistBase.vue
+++ b/front/src/components/library/ArtistBase.vue
@@ -25,7 +25,6 @@ import Layout from '~/components/ui/Layout.vue'
import Modal from '~/components/ui/Modal.vue'
import Spacer from '~/components/ui/Spacer.vue'
-
interface Props {
id: number
}
@@ -56,8 +55,7 @@ const musicbrainzUrl = computed(() => object.value?.mbid ? `https://musicbrainz.
const discogsUrl = computed(() => `https://discogs.com/search/?type=artist&title=${encodeURI(object.value?.name ?? '')}`)
const publicLibraries = computed(() => libraries.value?.filter(library => library.privacy_level === 'everyone') ?? [])
-
-const cover = computed(() => {
+const cover = computed(() => {
const artistCover: Cover | undefined = object.value?.cover
const albumCover: Cover | undefined = object.value?.albums
@@ -68,12 +66,12 @@ const cover = computed(() => {
)?.cover
const fallback : Cover = {
- uuid: '',
- urls: {
- original: `${import.meta.env.BASE_URL}embed-default-cover.jpeg`,
- medium_square_crop: `${import.meta.env.BASE_URL}embed-default-cover.jpeg`,
- large_square_crop: `${import.meta.env.BASE_URL}embed-default-cover.jpeg`
- }
+ uuid: '',
+ urls: {
+ original: `${import.meta.env.BASE_URL}embed-default-cover.jpeg`,
+ medium_square_crop: `${import.meta.env.BASE_URL}embed-default-cover.jpeg`,
+ large_square_crop: `${import.meta.env.BASE_URL}embed-default-cover.jpeg`
+ }
}
return artistCover
@@ -122,7 +120,11 @@ watch(() => props.id, fetchData, { immediate: true })
-
+
@@ -131,9 +133,18 @@ watch(() => props.id, fetchData, { immediate: true })
:alt="object.name"
class="channel-image"
>
-
- {{ object.name }}
-
+
+
+ {{ object.name }}
+
+
@@ -181,8 +192,8 @@ watch(() => props.id, fetchData, { immediate: true })
{{ t('components.library.ArtistBase.button.embed') }}
@@ -223,7 +234,7 @@ watch(() => props.id, fetchData, { immediate: true })
{{ t('components.library.ArtistBase.button.edit') }}
-
+
props.id, fetchData, { immediate: true })
{{ obj.label }}
-
+
{
{{ t('components.library.EditForm.message.noPermission') }}
router.resolve({
const artistCredit = track.value?.artist_credit
-const totalDuration = computed(() => track.value?.uploads?.[0]?.duration ?? 0)
+const totalDuration = computed(() => track.value?.uploads?.[0]?.duration ?? 0)
const { t } = useI18n()
const labels = computed(() => ({
@@ -142,253 +142,276 @@ watch(showDeleteModal, (newValue) => {
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
- {{ track.title }}
-
-
-
-
-
+
+ {{ t('components.library.TrackBase.title') }}
+
+ {{ track.album.title }}
+
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
- {{ t('components.library.TrackBase.link.domain', { domain }) }}
-
+
+
+
+
+
+
+
+
+ {{ t('components.library.TrackBase.link.domain', { domain }) }}
+
-
- {{ t('components.library.TrackBase.button.embed') }}
-
+
+ {{ t('components.library.TrackBase.button.embed') }}
+
-
- {{ t('components.library.TrackBase.link.wikipedia') }}
-
+
+ {{ t('components.library.TrackBase.link.wikipedia') }}
+
-
- {{ t('components.library.TrackBase.link.discogs') }}
-
+
+ {{ t('components.library.TrackBase.link.discogs') }}
+
-
- {{ t('components.library.TrackBase.button.edit') }}
-
+
+ {{ t('components.library.TrackBase.button.edit') }}
+
-
- {{ t('components.library.TrackBase.button.delete') }}
-
+
+ {{ t('components.library.TrackBase.button.delete') }}
+
-
+
-
- {{ obj.label }}
-
+
+ {{ obj.label }}
+
-
+
-
- {{ t('components.library.TrackBase.link.moderation') }}
-
+
+ {{ t('components.library.TrackBase.link.moderation') }}
+
-
- {{ t('components.library.TrackBase.link.django') }}
-
-
-
+
+ {{ t('components.library.TrackBase.link.django') }}
+
+
+
+
-
-
-
-
-
- {{ t('components.library.TrackBase.subtitle.with-uploader') }}
-
-
- {{ t('components.library.TrackBase.subtitle.without-uploader') }}
-
-
+
+
+
+ {{ t('components.library.TrackBase.subtitle.with-uploader') }}
+
+
+ {{ t('components.library.TrackBase.subtitle.without-uploader') }}
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+ {{ t('components.library.TrackBase.modal.delete.content.warning') }}
+
+
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
- {{ t('components.library.TrackBase.modal.delete.content.warning') }}
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/front/src/components/library/TrackDetail.vue b/front/src/components/library/TrackDetail.vue
index cdfe76c66..c70fac77a 100644
--- a/front/src/components/library/TrackDetail.vue
+++ b/front/src/components/library/TrackDetail.vue
@@ -53,19 +53,18 @@ const fetchLicense = async (licenseId: string) => {
watchEffect(() => {
if (props.track.license) {
- // @ts-expect-error For some reason, track.license is id instead of License here
fetchLicense(props.track.license)
}
})
-const release_details: {
+const releaseDetails: {
label: string;
- release_value: string;
+ releaseValue: string;
link?: { name: string; params: { id: number } };
}[] = [
{
label: t('components.library.TrackDetail.table.release.artist'),
- release_value: props.track.artist_credit.map(ac => ac.credit).join(', '),
+ releaseValue: props.track.artist_credit.map(ac => ac.credit).join(', '),
link: props.track.artist_credit.length > 0
? {
name: 'library.artists.detail',
@@ -78,7 +77,7 @@ const release_details: {
props.track.album?.artist_credit?.[0].artist.content_category === 'music'
? t('components.library.TrackDetail.table.release.album')
: t('components.library.TrackDetail.table.release.series'),
- release_value: props.track.album?.title || t('components.library.TrackDetail.notApplicable'),
+ releaseValue: props.track.album?.title || t('components.library.TrackDetail.notApplicable'),
link: props.track.album
? {
name: 'library.albums.detail',
@@ -88,48 +87,48 @@ const release_details: {
},
{
label: t('components.library.TrackDetail.table.release.year'),
- release_value: props.track.album?.release_date
+ releaseValue: props.track.album?.release_date
? momentFormat(new Date(props.track.album.release_date), 'Y')
: t('components.library.TrackDetail.notApplicable')
},
{
label: t('components.library.TrackDetail.table.release.copyright'),
- release_value: props.track.copyright || t('components.library.TrackDetail.notApplicable')
+ releaseValue: props.track.copyright || t('components.library.TrackDetail.notApplicable')
},
{
label: t('components.library.TrackDetail.table.release.license'),
- release_value: license.value?.name || t('components.library.TrackDetail.notApplicable')
+ releaseValue: license.value?.name || t('components.library.TrackDetail.notApplicable')
}
]
-const track_details: {
+const trackDetails: {
label: string;
- track_value: string | number;
+ trackValue: string | number;
link?: { name: string; params: { id: number } };
}[] = [
{
label: t('components.library.TrackDetail.table.track.duration'),
- track_value: upload?.value.duration ? time.parse(upload.value.duration) : t('components.library.TrackDetail.notApplicable')
+ trackValue: upload?.value.duration ? time.parse(upload.value.duration) : t('components.library.TrackDetail.notApplicable')
},
{
label:
t('components.library.TrackDetail.table.track.size'),
- track_value: upload?.value.size ? humanSize(upload.value.size) : t('components.library.TrackDetail.notApplicable')
+ trackValue: upload?.value.size ? humanSize(upload.value.size) : t('components.library.TrackDetail.notApplicable')
},
{
label: t('components.library.TrackDetail.table.track.codec'),
- track_value: upload?.value.extension || t('components.library.TrackDetail.notApplicable')
+ trackValue: upload?.value.extension || t('components.library.TrackDetail.notApplicable')
},
{
label:
t('components.library.TrackDetail.table.track.bitrate.label'),
- track_value: upload?.value.bitrate
+ trackValue: upload?.value.bitrate
? t('components.library.TrackDetail.table.track.bitrate.value', { bitrate: humanSize(upload.value.bitrate) })
: t('components.library.TrackDetail.notApplicable')
},
{
label: t('components.library.TrackDetail.table.track.downloads'),
- track_value: props.track.downloads_count
+ trackValue: props.track.downloads_count
}
]
@@ -156,15 +155,15 @@ const track_details: {
- {{ item.release_value }}
+ {{ item.releaseValue }}
{{ item.release_value }}
+ >{{ item.releaseValue }}
@@ -197,8 +196,8 @@ const track_details: {
h2="Track Details"
/>
- {{ item.track_value }}
+ {{ item.trackValue }}
{{ item.track_value }}
+ >{{ item.trackValue }}
diff --git a/front/src/components/manage/library/AlbumsTable.vue b/front/src/components/manage/library/AlbumsTable.vue
index b1d8244b3..f0c9272f9 100644
--- a/front/src/components/manage/library/AlbumsTable.vue
+++ b/front/src/components/manage/library/AlbumsTable.vue
@@ -102,7 +102,6 @@ const labels = computed(() => ({