feat(front): federated search in search modal
This commit is contained in:
parent
0f2be469da
commit
3ad9022556
|
@ -9,9 +9,12 @@ import { trim, uniqBy } from 'lodash-es'
|
||||||
import useErrorHandler from '~/composables/useErrorHandler'
|
import useErrorHandler from '~/composables/useErrorHandler'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useModal } from '~/ui/composables/useModal.ts'
|
import { useModal } from '~/ui/composables/useModal.ts'
|
||||||
|
import { useStore } from '~/store'
|
||||||
|
|
||||||
import ArtistCard from '~/components/artist/Card.vue'
|
import ArtistCard from '~/components/artist/Card.vue'
|
||||||
import PlaylistCard from '~/components/playlists/Card.vue'
|
import PlaylistCard from '~/components/playlists/Card.vue'
|
||||||
|
import ChannelCard from '~/components/audio/ChannelCard.vue'
|
||||||
|
import ActorLink from '~/components/common/ActorLink.vue'
|
||||||
import TrackTable from '~/components/audio/track/Table.vue'
|
import TrackTable from '~/components/audio/track/Table.vue'
|
||||||
import AlbumCard from '~/components/album/Card.vue'
|
import AlbumCard from '~/components/album/Card.vue'
|
||||||
import RadioCard from '~/components/radios/Card.vue'
|
import RadioCard from '~/components/radios/Card.vue'
|
||||||
|
@ -279,6 +282,26 @@ watch(results, () => {
|
||||||
openSections.value = new Set(categoriesWithResults.map(({ type }) => type))
|
openSections.value = new Set(categoriesWithResults.map(({ type }) => type))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Subscribe to an RSS feed
|
||||||
|
|
||||||
|
const store = useStore()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribe to an RSS feed and return the route for the subscribed channel
|
||||||
|
* @param url The RSS feed URL
|
||||||
|
* @returns The route object for the subscribed channel
|
||||||
|
*/
|
||||||
|
const rssSubscribe = async (url: string) => {
|
||||||
|
try {
|
||||||
|
const response = await axios.post('channels/rss-subscribe/', { url })
|
||||||
|
store.commit('channels/subscriptions', { uuid: response.data.channel.uuid, value: true })
|
||||||
|
return response.data.channel
|
||||||
|
} catch (error) {
|
||||||
|
useErrorHandler(error as Error)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
|
|
||||||
const search = async () => {
|
const search = async () => {
|
||||||
|
@ -324,13 +347,10 @@ const search = async () => {
|
||||||
} else {
|
} else {
|
||||||
// TODO: add (@)type key to Response type
|
// TODO: add (@)type key to Response type
|
||||||
if (category.type === 'rss') {
|
if (category.type === 'rss') {
|
||||||
const response = await axios.post<Response['rss']>(
|
const channel = await rssSubscribe(trimmedQuery.value)
|
||||||
category.endpoint,
|
if (channel) {
|
||||||
{ url: trimmedQuery.value }
|
results.value.rss = [channel] // Store the subscribed channel
|
||||||
)
|
}
|
||||||
results.value.type = category.type
|
|
||||||
results.value.rss = [response.data]
|
|
||||||
responses.value[category.type] = response.data
|
|
||||||
} else if (category.type === 'federation') {
|
} else if (category.type === 'federation') {
|
||||||
const response = await axios.post<Response['federation']>(
|
const response = await axios.post<Response['federation']>(
|
||||||
category.endpoint,
|
category.endpoint,
|
||||||
|
@ -406,8 +426,6 @@ const radioConfig = computed<RadioConfig | null>(() =>
|
||||||
// Start the search
|
// Start the search
|
||||||
|
|
||||||
watch(queryDebounced, search, { immediate: true })
|
watch(queryDebounced, search, { immediate: true })
|
||||||
|
|
||||||
// TODO: Include redirectRoute function from RemoteSearchForm.vue and adapt to !results.value and results.value.type instead of objInfo
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -501,30 +519,29 @@ watch(queryDebounced, search, { immediate: true })
|
||||||
|
|
||||||
<!-- If response has "url": "webfinger://node1@node1.funkwhale.test" -> Link to go directly to the federation page -->
|
<!-- If response has "url": "webfinger://node1@node1.funkwhale.test" -> Link to go directly to the federation page -->
|
||||||
|
|
||||||
<span v-if="category.type === 'rss' && count(category) > 0">
|
<template v-if="category.type === 'rss' && count(category) > 0">
|
||||||
<Alert>{{ t('modals.search.tryAgain') }}</Alert>
|
<Alert
|
||||||
<Link
|
blue
|
||||||
v-for="channel in resultsPerCategory(category)"
|
style="grid-column: 1 / -1"
|
||||||
:key="channel.artist.fid"
|
|
||||||
:to="channel.artist.fid"
|
|
||||||
autofocus
|
|
||||||
>
|
>
|
||||||
{{ channel.artist.name }}
|
{{ t('modals.search.tryAgain') }}
|
||||||
</Link>
|
</Alert>
|
||||||
</span>
|
<channel-card
|
||||||
|
v-if="results.rss && results.rss[0]"
|
||||||
|
:key="results.rss[0].uuid"
|
||||||
|
:object="results.rss[0]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
<span v-else-if="category.type === 'federation' && count(category) > 0">
|
<span v-else-if="category.type === 'federation' && count(category) > 0">
|
||||||
<!-- TODO: Federation search: backend adapter + display, fix results_per_category query -->
|
<!-- TODO: Federation search: backend adapter + display, fix results_per_category query -->
|
||||||
<!-- {{ resultsPerCategory(category) }} -->
|
<!-- {{ resultsPerCategory(category) }} -->
|
||||||
<!-- TODO: compute :to url for federated object -->
|
<!-- TODO: compute :to url for federated object -->
|
||||||
<Link
|
<ActorLink
|
||||||
v-for="result in resultsPerCategory(category)"
|
v-for="result in resultsPerCategory(category)"
|
||||||
:key="result.id"
|
:key="result.id"
|
||||||
:to="{name: 'profile.full', params: result.object?.full_username}"
|
:actor="result.object"
|
||||||
target="_blank"
|
/>
|
||||||
>
|
|
||||||
{{ result.object?.full_username }}
|
|
||||||
</Link>
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<EmptyState
|
<EmptyState
|
||||||
|
|
Loading…
Reference in New Issue