Fix front settings fetching
This commit is contained in:
parent
9d7327a45f
commit
3dff9c74d9
|
@ -1,3 +1,55 @@
|
|||
<script setup lang="ts">
|
||||
import type { BackendError, Album } from '~/types'
|
||||
|
||||
import { clone } from 'lodash-es'
|
||||
import { ref, reactive } from 'vue'
|
||||
|
||||
import axios from 'axios'
|
||||
import ChannelSerieCard from '~/components/audio/ChannelSerieCard.vue'
|
||||
import AlbumCard from '~/components/audio/album/Card.vue'
|
||||
|
||||
interface Props {
|
||||
filters: object
|
||||
isPodcast?: boolean
|
||||
limit?: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
isPodcast: true,
|
||||
limit: 5
|
||||
})
|
||||
|
||||
const isLoading = ref(false)
|
||||
const errors = ref([] as string[])
|
||||
|
||||
const albums = reactive([] as Album[])
|
||||
const nextPage = ref()
|
||||
const count = ref(0)
|
||||
|
||||
const fetchData = async (url = 'albums/') => {
|
||||
isLoading.value = true
|
||||
|
||||
try {
|
||||
const params = {
|
||||
...clone(props.filters),
|
||||
page_size: props.limit,
|
||||
include_channels: true
|
||||
}
|
||||
|
||||
const response = await axios.get(url, { params })
|
||||
nextPage.value = response.data.next
|
||||
count.value = response.data.count
|
||||
albums.push(...response.data.results)
|
||||
} catch (error) {
|
||||
errors.value = (error as BackendError).backendErrors
|
||||
}
|
||||
|
||||
isLoading.value = false
|
||||
}
|
||||
|
||||
fetchData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<slot />
|
||||
|
@ -10,7 +62,7 @@
|
|||
</div>
|
||||
<template v-if="isPodcast">
|
||||
<channel-serie-card
|
||||
v-for="serie in objects"
|
||||
v-for="serie in albums"
|
||||
:key="serie.id"
|
||||
:serie="serie"
|
||||
/>
|
||||
|
@ -20,7 +72,7 @@
|
|||
class="ui app-cards cards"
|
||||
>
|
||||
<album-card
|
||||
v-for="album in objects"
|
||||
v-for="album in albums"
|
||||
:key="album.id"
|
||||
:album="album"
|
||||
/>
|
||||
|
@ -37,10 +89,10 @@
|
|||
</translate>
|
||||
</button>
|
||||
</template>
|
||||
<template v-if="!isLoading && objects.length === 0">
|
||||
<template v-if="!isLoading && albums.length === 0">
|
||||
<empty-state
|
||||
:refresh="true"
|
||||
@refresh="fetchData('albums/')"
|
||||
@refresh="fetchData()"
|
||||
>
|
||||
<p>
|
||||
<translate translate-context="Content/Channels/*">
|
||||
|
@ -51,55 +103,3 @@
|
|||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { clone } from 'lodash-es'
|
||||
import axios from 'axios'
|
||||
import ChannelSerieCard from '~/components/audio/ChannelSerieCard.vue'
|
||||
import AlbumCard from '~/components/audio/album/Card.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ChannelSerieCard,
|
||||
AlbumCard
|
||||
},
|
||||
props: {
|
||||
filters: { type: Object, required: true },
|
||||
isPodcast: { type: Boolean, default: true },
|
||||
limit: { type: Number, default: 5 }
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
objects: [],
|
||||
count: 0,
|
||||
isLoading: false,
|
||||
errors: null,
|
||||
nextPage: null
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.fetchData('albums/')
|
||||
},
|
||||
methods: {
|
||||
fetchData (url) {
|
||||
if (!url) {
|
||||
return
|
||||
}
|
||||
this.isLoading = true
|
||||
const self = this
|
||||
const params = clone(this.filters)
|
||||
params.page_size = this.limit
|
||||
params.include_channels = true
|
||||
axios.get(url, { params }).then((response) => {
|
||||
self.nextPage = response.data.next
|
||||
self.isLoading = false
|
||||
self.objects = self.objects.concat(response.data.results)
|
||||
self.count = response.data.count
|
||||
}, error => {
|
||||
self.isLoading = false
|
||||
self.errors = error.backendErrors
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,3 +1,53 @@
|
|||
<script setup lang="ts">
|
||||
import type { BackendError, Channel } from '~/types'
|
||||
|
||||
import { clone } from 'lodash-es'
|
||||
import { ref, reactive } from 'vue'
|
||||
|
||||
import axios from 'axios'
|
||||
import ChannelCard from '~/components/audio/ChannelCard.vue'
|
||||
|
||||
interface Props {
|
||||
filters: object
|
||||
limit?: number
|
||||
}
|
||||
|
||||
const emit = defineEmits(['fetched'])
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
limit: 5
|
||||
})
|
||||
|
||||
const channels = reactive([] as Channel[])
|
||||
const errors = ref([] as string[])
|
||||
const nextPage = ref()
|
||||
const count = ref(0)
|
||||
|
||||
const isLoading = ref(false)
|
||||
const fetchData = async (url = 'channels/') => {
|
||||
isLoading.value = true
|
||||
|
||||
const params = {
|
||||
...clone(props.filters),
|
||||
page_size: props.limit,
|
||||
include_channels: true
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.get(url, { params })
|
||||
nextPage.value = response.data.next
|
||||
count.value = response.data.count
|
||||
channels.push(...response.data.results)
|
||||
emit('fetched', response.data)
|
||||
} catch (error) {
|
||||
errors.value = (error as BackendError).backendErrors
|
||||
}
|
||||
|
||||
isLoading.value = false
|
||||
}
|
||||
|
||||
fetchData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<slot />
|
||||
|
@ -10,7 +60,7 @@
|
|||
<div class="ui loader" />
|
||||
</div>
|
||||
<channel-card
|
||||
v-for="object in objects"
|
||||
v-for="object in channels"
|
||||
:key="object.uuid"
|
||||
:object="object"
|
||||
/>
|
||||
|
@ -27,7 +77,7 @@
|
|||
</translate>
|
||||
</button>
|
||||
</template>
|
||||
<template v-if="!isLoading && objects.length === 0">
|
||||
<template v-if="!isLoading && channels.length === 0">
|
||||
<empty-state
|
||||
:refresh="true"
|
||||
@refresh="fetchData('channels/')"
|
||||
|
@ -35,53 +85,3 @@
|
|||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { clone } from 'lodash-es'
|
||||
import axios from 'axios'
|
||||
import ChannelCard from '~/components/audio/ChannelCard.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ChannelCard
|
||||
},
|
||||
props: {
|
||||
filters: { type: Object, required: true },
|
||||
limit: { type: Number, default: 5 }
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
objects: [],
|
||||
count: 0,
|
||||
isLoading: false,
|
||||
errors: null,
|
||||
nextPage: null
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.fetchData('channels/')
|
||||
},
|
||||
methods: {
|
||||
fetchData (url) {
|
||||
if (!url) {
|
||||
return
|
||||
}
|
||||
this.isLoading = true
|
||||
const self = this
|
||||
const params = clone(this.filters)
|
||||
params.page_size = this.limit
|
||||
params.include_channels = true
|
||||
axios.get(url, { params }).then((response) => {
|
||||
self.nextPage = response.data.next
|
||||
self.isLoading = false
|
||||
self.objects = self.objects.concat(response.data.results)
|
||||
self.count = response.data.count
|
||||
self.$emit('fetched', response.data)
|
||||
}, error => {
|
||||
self.isLoading = false
|
||||
self.errors = error.backendErrors
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,3 +1,73 @@
|
|||
<script setup lang="ts">
|
||||
import type { Artist, Album } from '~/types'
|
||||
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
import { ref, computed, reactive, watch, onMounted } from 'vue'
|
||||
import { refDebounced } from '@vueuse/core'
|
||||
|
||||
import axios from 'axios'
|
||||
import AlbumCard from '~/components/audio/album/Card.vue'
|
||||
import ArtistCard from '~/components/audio/artist/Card.vue'
|
||||
import useLogger from '~/composables/useLogger'
|
||||
|
||||
interface Props {
|
||||
autofocus?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
autofocus: false
|
||||
})
|
||||
|
||||
const logger = useLogger()
|
||||
const { $pgettext } = useGettext()
|
||||
|
||||
const query = ref('')
|
||||
const queryDebounced = refDebounced(query, 500)
|
||||
|
||||
const results = reactive({
|
||||
artists: [] as Artist[],
|
||||
albums: [] as Album[]
|
||||
})
|
||||
|
||||
const isLoading = ref(false)
|
||||
const search = async () => {
|
||||
if (queryDebounced.value.length < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
isLoading.value = true
|
||||
logger.debug(`Searching track matching "${queryDebounced.value}"`)
|
||||
|
||||
const params = {
|
||||
query: queryDebounced.value
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.get('search/', { params })
|
||||
results.artists = response.data.artists
|
||||
results.albums = response.data.albums
|
||||
} catch (error) {
|
||||
// TODO (wvffle): Handle error
|
||||
}
|
||||
|
||||
isLoading.value = false
|
||||
}
|
||||
|
||||
watch(queryDebounced, search, { immediate: true })
|
||||
|
||||
const searchInput = ref()
|
||||
onMounted(() => {
|
||||
if (props.autofocus) {
|
||||
searchInput.value.focus()
|
||||
}
|
||||
})
|
||||
|
||||
const labels = computed(() => ({
|
||||
searchPlaceholder: $pgettext('*/Search/Input.Placeholder', 'Artist, album, track…')
|
||||
}))
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h2>
|
||||
|
@ -9,7 +79,7 @@
|
|||
<div class="ui icon big input">
|
||||
<i class="search icon" />
|
||||
<input
|
||||
ref="search"
|
||||
ref="searchInput"
|
||||
v-model.trim="query"
|
||||
class="prompt"
|
||||
:placeholder="labels.searchPlaceholder"
|
||||
|
@ -67,76 +137,3 @@
|
|||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { debounce } from 'lodash-es'
|
||||
import axios from 'axios'
|
||||
import AlbumCard from '~/components/audio/album/Card.vue'
|
||||
import ArtistCard from '~/components/audio/artist/Card.vue'
|
||||
import useLogger from '~/composables/useLogger'
|
||||
|
||||
const logger = useLogger()
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AlbumCard,
|
||||
ArtistCard
|
||||
},
|
||||
props: {
|
||||
autofocus: { type: Boolean, default: false }
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
query: '',
|
||||
results: {
|
||||
albums: [],
|
||||
artists: []
|
||||
},
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
labels () {
|
||||
return {
|
||||
searchPlaceholder: this.$pgettext('*/Search/Input.Placeholder', 'Artist, album, track…')
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
query () {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
if (this.autofocus) {
|
||||
this.$refs.search.focus()
|
||||
}
|
||||
this.search()
|
||||
},
|
||||
methods: {
|
||||
search: debounce(function () {
|
||||
if (this.query.length < 1) {
|
||||
return
|
||||
}
|
||||
const self = this
|
||||
self.isLoading = true
|
||||
logger.debug('Searching track matching "' + this.query + '"')
|
||||
const params = {
|
||||
query: this.query
|
||||
}
|
||||
axios.get('search', {
|
||||
params
|
||||
}).then((response) => {
|
||||
self.results = self.castResults(response.data)
|
||||
self.isLoading = false
|
||||
})
|
||||
}, 500),
|
||||
castResults (results) {
|
||||
return {
|
||||
albums: results.albums,
|
||||
artists: results.artists
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -183,7 +183,7 @@ const store: Module<State, RootState> = {
|
|||
payload?.callback?.()
|
||||
},
|
||||
async fetchFrontSettings ({ state }) {
|
||||
const response = await axios.get('/front/settings.json')
|
||||
const response = await axios.get(`${import.meta.env.BASE_URL}settings.json`)
|
||||
.catch(() => logger.error('Error when fetching front-end configuration (or no customization available)'))
|
||||
|
||||
if (!response) return
|
||||
|
|
Loading…
Reference in New Issue