tooot/src/screens/Tabs/Shared/Search/index.tsx

196 lines
6.2 KiB
TypeScript
Raw Normal View History

2021-01-19 01:13:45 +01:00
import ComponentAccount from '@components/Account'
import ComponentHashtag from '@components/Hashtag'
2022-12-03 16:50:54 +01:00
import { HeaderLeft } from '@components/Header'
2021-01-19 01:13:45 +01:00
import ComponentSeparator from '@components/Separator'
import CustomText from '@components/Text'
2021-02-08 23:47:20 +01:00
import TimelineDefault from '@components/Timeline/Default'
2021-08-29 15:25:38 +02:00
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
2021-01-11 21:36:57 +01:00
import { useSearchQuery } from '@utils/queryHooks/search'
2021-01-01 16:48:16 +01:00
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
2022-12-03 16:50:54 +01:00
import { debounce } from 'lodash'
2022-12-04 20:08:55 +01:00
import React, { useEffect, useRef, useState } from 'react'
2021-01-19 01:13:45 +01:00
import { Trans, useTranslation } from 'react-i18next'
2022-12-04 20:08:55 +01:00
import { KeyboardAvoidingView, Platform, SectionList, TextInput, View } from 'react-native'
import SearchEmpty from './Empty'
2020-11-24 00:18:47 +01:00
2022-11-29 23:44:11 +01:00
const TabSharedSearch: React.FC<TabSharedStackScreenProps<'Tab-Shared-Search'>> = ({
2022-12-04 20:08:55 +01:00
navigation
2021-03-14 00:47:55 +01:00
}) => {
2021-03-28 23:31:10 +02:00
const { t } = useTranslation('screenTabs')
2022-12-03 16:50:54 +01:00
const { colors, mode } = useTheme()
2022-12-04 20:08:55 +01:00
const inputRef = useRef<TextInput>(null)
const [searchTerm, setSearchTerm] = useState<string>('')
2022-12-03 16:50:54 +01:00
useEffect(() => {
navigation.setOptions({
...(Platform.OS === 'ios'
? {
headerLeft: () => <HeaderLeft onPress={() => navigation.goBack()} />
}
: { headerLeft: () => null }),
headerTitle: () => {
return (
<View
style={{
flexBasis: '80%',
flexDirection: 'row',
alignItems: 'center'
}}
>
<TextInput
editable={false}
style={{
fontSize: StyleConstants.Font.Size.M,
color: colors.primaryDefault
}}
defaultValue={t('shared.search.header.prefix')}
/>
<TextInput
2022-12-04 20:08:55 +01:00
ref={inputRef}
2022-12-03 16:50:54 +01:00
accessibilityRole='search'
keyboardAppearance={mode}
style={{
fontSize: StyleConstants.Font.Size.M,
flex: 1,
color: colors.primaryDefault,
2022-12-12 20:43:45 +01:00
marginLeft: StyleConstants.Spacing.XS,
paddingLeft: StyleConstants.Spacing.XS,
paddingVertical: StyleConstants.Spacing.XS,
borderBottomColor: colors.border,
borderBottomWidth: 1
2022-12-03 16:50:54 +01:00
}}
autoFocus
2022-12-04 20:08:55 +01:00
onChangeText={debounce(
text => {
setSearchTerm(text)
refetch()
},
1000,
{ trailing: true }
)}
2022-12-03 16:50:54 +01:00
autoCapitalize='none'
autoCorrect={false}
2022-12-04 13:48:50 +01:00
clearButtonMode='always'
2022-12-03 16:50:54 +01:00
keyboardType='web-search'
placeholder={t('shared.search.header.placeholder')}
placeholderTextColor={colors.secondary}
2022-12-04 13:48:50 +01:00
returnKeyType='search'
2022-12-03 16:50:54 +01:00
/>
</View>
)
}
})
2022-12-04 20:08:55 +01:00
}, [mode])
2020-12-19 01:57:57 +01:00
2021-01-19 01:13:45 +01:00
const mapKeyToTranslations = {
2021-03-28 23:31:10 +02:00
accounts: t('shared.search.sections.accounts'),
hashtags: t('shared.search.sections.hashtags'),
statuses: t('shared.search.sections.statuses')
2021-01-19 01:13:45 +01:00
}
const { isFetching, data, refetch } = useSearchQuery<
2021-12-18 19:59:38 +01:00
{
title: string
translation: string
data: any[]
}[]
>({
2022-12-04 20:08:55 +01:00
term: searchTerm,
2021-03-14 00:47:55 +01:00
options: {
2022-12-04 20:08:55 +01:00
enabled: !!searchTerm.length,
2021-03-14 00:47:55 +01:00
select: data =>
2020-12-19 01:57:57 +01:00
Object.keys(data as Mastodon.Results)
2020-12-18 19:02:18 +01:00
.map(key => ({
title: key,
// @ts-ignore
2021-01-19 01:13:45 +01:00
translation: mapKeyToTranslations[key],
// @ts-ignore
2020-12-18 19:02:18 +01:00
data: data[key]
}))
2022-12-04 20:08:55 +01:00
.filter(d => d.data.length)
2020-12-18 19:02:18 +01:00
.sort((a, b) => {
if (!a.data.length) {
return 1
} else if (!b.data.length) {
return -1
} else {
return 0
}
})
2020-12-19 01:57:57 +01:00
}
2021-03-14 00:47:55 +01:00
})
2020-12-18 19:02:18 +01:00
return (
2021-01-14 00:43:35 +01:00
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={{ flex: 1 }}
>
2021-01-04 18:29:02 +01:00
<SectionList
style={{ minHeight: '100%' }}
2022-12-04 20:08:55 +01:00
sections={data || []}
renderItem={({ item, section }: { item: any; section: any }) => {
switch (section.title) {
case 'accounts':
return <ComponentAccount account={item} />
case 'hashtags':
return <ComponentHashtag hashtag={item} />
case 'statuses':
return <TimelineDefault item={item} disableDetails />
default:
return null
}
}}
2021-01-04 18:29:02 +01:00
stickySectionHeadersEnabled
2022-12-04 20:08:55 +01:00
ListEmptyComponent={
<SearchEmpty isFetching={isFetching} inputRef={inputRef} setSearchTerm={setSearchTerm} />
2022-12-04 20:08:55 +01:00
}
2021-01-04 18:29:02 +01:00
keyboardShouldPersistTaps='always'
2022-08-07 01:18:10 +02:00
renderSectionHeader={({ section: { translation } }) => (
<View
style={{
padding: StyleConstants.Spacing.M,
backgroundColor: colors.backgroundDefault
}}
>
<CustomText
fontStyle='M'
style={{
textAlign: 'center',
color: colors.primaryDefault
}}
fontWeight='Bold'
>
{translation}
</CustomText>
</View>
)}
renderSectionFooter={({ section: { data, translation } }) =>
!data.length ? (
<View
style={{
padding: StyleConstants.Spacing.S,
backgroundColor: colors.backgroundDefault
}}
>
2022-11-29 23:44:11 +01:00
<CustomText fontStyle='S' style={{ textAlign: 'center', color: colors.secondary }}>
2022-08-07 01:18:10 +02:00
<Trans
i18nKey='screenTabs:shared.search.notFound'
2022-12-04 20:08:55 +01:00
values={{ searchTerm, type: translation }}
2022-08-07 01:18:10 +02:00
components={{
bold: <CustomText fontWeight='Bold' />
}}
/>
</CustomText>
</View>
) : null
}
2021-01-04 18:29:02 +01:00
keyExtractor={(item, index) => item + index}
SectionSeparatorComponent={ComponentSeparator}
ItemSeparatorComponent={ComponentSeparator}
/>
</KeyboardAvoidingView>
2020-12-18 19:02:18 +01:00
)
2020-11-24 00:18:47 +01:00
}
2021-01-30 01:29:15 +01:00
export default TabSharedSearch