subtracks/app/screens/SearchResultsView.tsx
austinried 860a4cec16
Localization support (#99)
* basic i18n poc

* translate home, filters, tabs

support dot notation in backend for namespaces

* i18n context menu, artist filters, list controls

also nothings here
fix backend not caching fallback

* i18n queue, artist view, search/results

* i18n settings and server view

* Added translation using Weblate (Norwegian Bokmål)

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (6 of 6 strings)

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/nb_NO/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/

* fix url escaping

* added some mostly naive text overflow fixes

rewrote filter context menu as a slide in because the old one apparently can't handle dynamic width

* Added translation using Weblate (French)

* Translated using Weblate (French)

Currently translated at 17.4% (11 of 63 strings)

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/fr/

* Translated using Weblate (French)

Currently translated at 19.0% (12 of 63 strings)

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/fr/

* Translated using Weblate (French)

Currently translated at 40.0% (26 of 65 strings)

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/fr/

* add weblate and some pretty badges to readme

* fix link

* Translated using Weblate (French)

Currently translated at 50.7% (33 of 65 strings)

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/fr/

* Translated using Weblate (English)

Currently translated at 100.0% (65 of 65 strings)

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/en/

* Translated using Weblate (French)

Currently translated at 90.7% (59 of 65 strings)

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/fr/

* i18n now playing context type

fix overscroll on new filter menu
fix getting default namespace from the i18n backend

* Translated using Weblate (French)

Currently translated at 96.9% (63 of 65 strings)

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (66 of 66 strings)

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/fr/

* Translated using Weblate (Japanese) (#98)

Currently translated at 7.5% (5 of 66 strings)

Translation: Subtracks/subtracks
Translate-URL: https://hosted.weblate.org/projects/subtracks/subtracks/ja/

Co-authored-by: Austin Riedhammer <austinried@functionkey.xyz>

* little note to remind me why that's there

* update licenses

Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Clyhtsuriva <aimeric@adjutor.xyz>
2022-04-15 12:11:00 +09:00

117 lines
3.1 KiB
TypeScript

import GradientFlatList from '@app/components/GradientFlatList'
import ListItem from '@app/components/ListItem'
import { withSuspense } from '@app/components/withSuspense'
import { useQuerySearchResults } from '@app/hooks/query'
import { useSetQueue } from '@app/hooks/trackplayer'
import { Album, Artist, Song } from '@app/models/library'
import { Search3Params } from '@app/subsonic/params'
import { useNavigation } from '@react-navigation/native'
import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { StyleSheet } from 'react-native'
type SearchListItemType = Album | Song | Artist
const SongResultsListItem: React.FC<{ item: Song }> = ({ item }) => {
const { setQueue, isReady, contextId } = useSetQueue('song', [item])
return (
<ListItem
item={item}
contextId={contextId}
queueId={0}
showArt={true}
showStar={false}
listStyle="small"
onPress={() => setQueue({ title: item.title, playTrack: 0 })}
style={styles.listItem}
disabled={!isReady}
/>
)
}
const OtherResultsListItem: React.FC<{ item: SearchListItemType }> = ({ item }) => {
return (
<ListItem
item={item}
contextId={item.id}
queueId={0}
showArt={true}
showStar={false}
listStyle="small"
style={styles.listItem}
/>
)
}
const ResultsListItem: React.FC<{ item: SearchListItemType }> = ({ item }) => {
if (item.itemType === 'song') {
return <SongResultsListItem item={item} />
} else {
return <OtherResultsListItem item={item} />
}
}
const SearchResultsRenderItem: React.FC<{ item: SearchListItemType }> = ({ item }) => <ResultsListItem item={item} />
const SearchResultsView = withSuspense<{
query: string
type: 'album' | 'artist' | 'song'
}>(({ query, type }) => {
const navigation = useNavigation()
const { t } = useTranslation('search')
const size = 100
const params: Search3Params = { query }
if (type === 'album') {
params.albumCount = size
} else if (type === 'artist') {
params.artistCount = size
} else {
params.songCount = size
}
const { data, isLoading, refetch, fetchNextPage } = useQuerySearchResults(params)
const items: (Artist | Album | Song)[] = []
if (type === 'album') {
data && items.push(...data.pages.flatMap(p => p.albums))
} else if (type === 'artist') {
data && items.push(...data.pages.flatMap(p => p.artists))
} else {
data && items.push(...data.pages.flatMap(p => p.songs))
}
useEffect(() => {
navigation.setOptions({
title: t('headerTitle', { query }),
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return (
<GradientFlatList
data={items}
renderItem={SearchResultsRenderItem}
keyExtractor={(item, i) => i.toString()}
onRefresh={refetch}
refreshing={isLoading}
overScrollMode="never"
onEndReached={() => fetchNextPage}
removeClippedSubviews={true}
onEndReachedThreshold={2}
contentMarginTop={6}
windowSize={5}
/>
)
})
const styles = StyleSheet.create({
listItem: {
paddingHorizontal: 10,
},
})
export default SearchResultsView