fix(front): [WIP] in search modal, show rss result as channel link

This commit is contained in:
upsiflu 2025-03-17 13:30:11 +01:00
parent e31c6c0e74
commit e05a5b9d7a
3 changed files with 41 additions and 11 deletions

View File

@ -87,6 +87,7 @@ const headerGrid
<Layout <Layout
main main
:inert="'collapsed' in props && props.collapsed"
:style="`${ :style="`${
'alignLeft' in props && props.alignLeft 'alignLeft' in props && props.alignLeft
? 'justify-content: start;' ? 'justify-content: start;'

View File

@ -3332,7 +3332,7 @@
"tags": "Tags", "tags": "Tags",
"tracks": "Tracks", "tracks": "Tracks",
"rss": "RSS feeds", "rss": "RSS feeds",
"federation": "Federation" "fetches": "Federation fetches"
} }
}, },
"admin": { "admin": {

View File

@ -21,6 +21,7 @@ import Button from '~/components/ui/Button.vue'
import Spacer from '~/components/ui/Spacer.vue' import Spacer from '~/components/ui/Spacer.vue'
import Input from '~/components/ui/Input.vue' import Input from '~/components/ui/Input.vue'
import Section from '~/components/ui/Section.vue' import Section from '~/components/ui/Section.vue'
import Link from '~/components/ui/Link.vue'
import Loader from '~/components/ui/Loader.vue' import Loader from '~/components/ui/Loader.vue'
import Alert from '~/components/ui/Alert.vue' import Alert from '~/components/ui/Alert.vue'
import EmptyState from '~/components/common/EmptyState.vue' import EmptyState from '~/components/common/EmptyState.vue'
@ -46,7 +47,8 @@ const paginateBy = ref<number>(100)
const queryDebounced = refDebounced(query, 500) const queryDebounced = refDebounced(query, 500)
const trimmedQuery = computed(() => trim(trim(queryDebounced.value), '@')) const trimmedQuery = computed(() => trim(trim(queryDebounced.value), '@'))
const isUri = computed(() => trimmedQuery.value.startsWith('http://') || trimmedQuery.value.startsWith('https://') || trimmedQuery.value.includes('@')) const isFetch = computed(() => ((trimmedQuery.value.startsWith('http://') || trimmedQuery.value.startsWith('https://')) || trimmedQuery.value.includes('@')) && !isRss.value)
const isRss = computed(() => trimmedQuery.value.includes('.rss') || trimmedQuery.value.includes('.xml'))
const isLoading = ref(false) const isLoading = ref(false)
@ -130,14 +132,16 @@ const categories = computed(() => [
type: 'rss', type: 'rss',
label: t('views.Search.label.rss'), label: t('views.Search.label.rss'),
endpoint: '/channels/rss-subscribe/', endpoint: '/channels/rss-subscribe/',
post: true,
params: { params: {
object: trimmedQuery.value url: trimmedQuery.value
} }
}, },
{ {
type: 'federation', type: 'federation',
label: t('views.Search.label.fetches'), label: t('views.Search.label.fetches'),
endpoint: '/federation/fetches/', endpoint: '/federation/fetches/',
post: true,
params: { params: {
object: trimmedQuery.value object: trimmedQuery.value
} }
@ -145,6 +149,7 @@ const categories = computed(() => [
] as const satisfies { ] as const satisfies {
type: Category type: Category
label: string label: string
post?: true
params?: { params?: {
[key: string]: string [key: string]: string
} }
@ -152,15 +157,23 @@ const categories = computed(() => [
}[]) }[])
// Limit the available categories based on the search query // Limit the available categories based on the search query
const federatedCategories: Category[] = ['federation', 'rss'] // Show fetch if the query is a URL; show RSS if the query is an email address; show all other cateories otherwise
const availableCategories = computed(() => const availableCategories = computed(() =>
categories.value.filter(({ type }) => categories.value.filter(({ type }) =>
isUri.value isFetch.value
? federatedCategories.includes(type) ? type==='federation'
: !federatedCategories.includes(type) : isRss.value
? type==='rss'
: !['federation', 'rss'].includes(type)
)) ))
// If there is only one available category, open it immediately
watch(availableCategories, () => {
if (availableCategories.value.length === 1 && openSectionHistory.value.at(0) !== availableCategories.value[0].type) {
openSectionHistory.value.unshift(availableCategories.value[0].type)
}
})
/** /**
* Get the results for a given category * Get the results for a given category
* @param category The category to get the results for * @param category The category to get the results for
@ -250,9 +263,11 @@ const search = async () => {
...response.data ...response.data
} }
} else { } else {
const response = await axios.get<Results[typeof category.type][0]>( console.log("endpoint", category.endpoint)
console.log("params", params)
const response = await axios['post' in category ? 'post' : 'get']<Results[typeof category.type][0]>(
category.endpoint, category.endpoint,
{ params } isRss.value ? ({ url: trimmedQuery.value }) : ({ params })
) )
results.value = { results.value = {
...results.value, ...results.value,
@ -303,6 +318,7 @@ watch(queryDebounced, search, { immediate: true })
> >
<!-- Each section collapses if it is not current --> <!-- Each section collapses if it is not current -->
<Section <Section
align-left
:action="{ :action="{
text: `${ text: `${
!isCategoryQueried(category.type) !isCategoryQueried(category.type)
@ -369,8 +385,21 @@ watch(queryDebounced, search, { immediate: true })
</template> </template>
<!-- TODO: Implement results from non-`/v2/search` requests (federated/uri results etc.) here --> <!-- TODO: Implement results from non-`/v2/search` requests (federated/uri results etc.) here -->
<!-- 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'">
<Alert>If the following link does not work, wait a few seconds and try again</Alert>
<Link
:to="channel.artist.fid"
autofocus
>
{{ channel.artist.name }}
</Link>
</span>
<span v-else-if="category.type === 'federation'">
{{ resultsPerCategory(category.type) }}
</span>
</Section> </Section>
</template> </template>
</Modal> </Modal>