chore(front): [WIP] new toplevel channels page
This commit is contained in:
parent
4a9f2f99ae
commit
b1ac6612fd
|
@ -145,7 +145,7 @@ const logoUrl = computed(() => store.state.auth.authenticated ? 'library.index'
|
|||
{{ t('components.Sidebar.link.artists') }}
|
||||
</Link>
|
||||
|
||||
<Link to="/subscriptions"
|
||||
<Link to="/channels"
|
||||
ghost
|
||||
full
|
||||
align-text="left"
|
||||
|
|
|
@ -124,6 +124,12 @@ export default [
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'channels',
|
||||
name: 'channels',
|
||||
component: () => import('~/views/channels/List.vue'),
|
||||
props: route => ({ defaultQuery: route.query.q })
|
||||
},
|
||||
{
|
||||
path: 'subscriptions',
|
||||
name: 'subscriptions',
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
<script setup lang="ts">
|
||||
import type { Channel } from '~/types'
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
import axios from 'axios'
|
||||
|
||||
import ChannelsWidget from '~/components/audio/ChannelsWidget.vue'
|
||||
import RemoteSearchForm from '~/components/RemoteSearchForm.vue'
|
||||
import Layout from '~/components/ui/Layout.vue'
|
||||
import Header from '~/components/ui/Header.vue'
|
||||
import Modal from '~/components/ui/Modal.vue'
|
||||
import Button from '~/components/ui/Button.vue'
|
||||
|
||||
import useErrorHandler from '~/composables/useErrorHandler'
|
||||
|
||||
interface Props {
|
||||
defaultQuery?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
defaultQuery: ''
|
||||
})
|
||||
|
||||
const query = ref(props.defaultQuery)
|
||||
const widgetKey = ref(new Date().toLocaleString())
|
||||
|
||||
const { t } = useI18n()
|
||||
const labels = computed(() => ({
|
||||
searchPlaceholder: t('views.channels.SubscriptionsList.placeholder.search')
|
||||
}))
|
||||
|
||||
const previousPage = ref()
|
||||
const nextPage = ref()
|
||||
const channels = ref([] as Channel[])
|
||||
const count = ref(0)
|
||||
const isLoading = ref(false)
|
||||
const fetchData = async () => {
|
||||
isLoading.value = true
|
||||
|
||||
try {
|
||||
const response = await axios.get('channels/', { params: { q: query.value } })
|
||||
previousPage.value = response.data.previous
|
||||
nextPage.value = response.data.next
|
||||
channels.value.push(...response.data.results)
|
||||
count.value = response.data.count
|
||||
} catch (error) {
|
||||
useErrorHandler(error as Error)
|
||||
}
|
||||
|
||||
isLoading.value = false
|
||||
}
|
||||
fetchData()
|
||||
|
||||
const reloadWidget = () => (widgetKey.value = new Date().toLocaleString())
|
||||
const showSubscribeModal = ref(false)
|
||||
const showCreateModal = ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Layout stack main
|
||||
>
|
||||
<Header
|
||||
:h1="t('views.channels.SubscriptionsList.title')"
|
||||
:action="{
|
||||
text: t('views.channels.SubscriptionsList.link.addNew'),
|
||||
onClick: ()=> showSubscribeModal = true
|
||||
}"
|
||||
icon="bi-plus"
|
||||
primary
|
||||
/>
|
||||
<Modal
|
||||
v-model="showSubscribeModal"
|
||||
:title="t('views.channels.SubscriptionsList.modal.subscription.header')"
|
||||
class="tiny"
|
||||
>
|
||||
<div
|
||||
ref="modalContent"
|
||||
class="scrolling content"
|
||||
>
|
||||
<remote-search-form
|
||||
initial-type="both"
|
||||
:show-submit="false"
|
||||
:standalone="false"
|
||||
:redirect="true"
|
||||
@subscribed="showSubscribeModal = false; reloadWidget()"
|
||||
/>
|
||||
</div>
|
||||
<template #actions>
|
||||
<Button
|
||||
secondary
|
||||
@click="showSubscribeModal = false"
|
||||
>
|
||||
{{ t('views.channels.SubscriptionsList.button.cancel') }}
|
||||
</Button>
|
||||
<Button
|
||||
form="remote-search"
|
||||
type="submit"
|
||||
icon="bi-bookmark-check-fill"
|
||||
primary
|
||||
>
|
||||
{{ t('views.channels.SubscriptionsList.button.subscribe') }}
|
||||
</Button>
|
||||
</template>
|
||||
</Modal>
|
||||
|
||||
<inline-search-bar
|
||||
v-model="query"
|
||||
:placeholder="labels.searchPlaceholder"
|
||||
@search="reloadWidget"
|
||||
/>
|
||||
<channels-widget
|
||||
:key="widgetKey"
|
||||
:limit="50"
|
||||
:show-modification-date="true"
|
||||
:filters="{q: query, ordering: '-name'}"
|
||||
/>
|
||||
<!-- TODO: Translations -->
|
||||
<Header
|
||||
:h1="t('views.auth.ProfileOverview.header.channels')"
|
||||
:action="{
|
||||
text: t('views.channels.SubscriptionsList.link.addNew'),
|
||||
onClick: ()=> showCreateModal = true
|
||||
}"
|
||||
icon="bi-plus"
|
||||
primary
|
||||
/>
|
||||
<channels-widget
|
||||
:show-modification-date="true"
|
||||
:limit="12"
|
||||
:filters="{ordering: '-creation_date', external: 'true'}"
|
||||
>
|
||||
<template #title>
|
||||
{{ t('components.library.Home.header.newChannels') }}
|
||||
</template>
|
||||
</channels-widget>
|
||||
</Layout>
|
||||
|
||||
<Modal v-model="showCreateModal"
|
||||
:title="t(`views.auth.ProfileOverview.modal.createChannel.${
|
||||
step === 1 ?
|
||||
'header' :
|
||||
category === 'podcast' ?
|
||||
'podcast.header'
|
||||
:
|
||||
'artist.header'
|
||||
}`)"
|
||||
>
|
||||
<div
|
||||
ref="modalContent"
|
||||
class="scrolling content"
|
||||
>
|
||||
<channel-form
|
||||
ref="createForm"
|
||||
:object="null"
|
||||
:step="step"
|
||||
@loading="loading = $event"
|
||||
@submittable="submittable = $event"
|
||||
@category="category = $event"
|
||||
@errored="modalContent.scrollTop = 0"
|
||||
@created="router.push({name: 'channels.detail', params: {id: $event.actor.preferred_username}})"
|
||||
/>
|
||||
</div>
|
||||
<template #actions>
|
||||
<Button secondary
|
||||
v-if="step === 1"
|
||||
autofocus
|
||||
>
|
||||
{{ t('views.auth.ProfileOverview.button.cancel') }}
|
||||
</Button>
|
||||
<Button secondary
|
||||
v-if="step > 1"
|
||||
@click.stop.prevent="step -= 1"
|
||||
>
|
||||
{{ t('views.auth.ProfileOverview.button.previous') }}
|
||||
</Button>
|
||||
<Button primary
|
||||
v-if="step === 1"
|
||||
@click.stop.prevent="step += 1"
|
||||
>
|
||||
{{ t('views.auth.ProfileOverview.button.next') }}
|
||||
</Button>
|
||||
<Button primary
|
||||
v-if="step === 2"
|
||||
type="submit"
|
||||
:disabled="!submittable && !loading"
|
||||
:isLoading="loading"
|
||||
@click.prevent.stop="createForm.submit"
|
||||
>
|
||||
{{ t('views.auth.ProfileOverview.button.createChannel') }}
|
||||
</Button>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
Loading…
Reference in New Issue