Fix front settings fetching

This commit is contained in:
wvffle 2022-07-21 17:56:57 +00:00 committed by Georg Krause
parent 9d7327a45f
commit 3dff9c74d9
4 changed files with 180 additions and 183 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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