tooot/src/screens/Shared/Search.tsx

235 lines
6.7 KiB
TypeScript
Raw Normal View History

2020-12-18 19:02:18 +01:00
import { useNavigation } from '@react-navigation/native'
2021-01-04 18:29:02 +01:00
import ComponentAccount from '@root/components/Account'
import ComponentSeparator from '@root/components/Separator'
import TimelineDefault from '@root/components/Timelines/Timeline/Default'
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'
2020-12-19 01:57:57 +01:00
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import {
KeyboardAvoidingView,
2020-12-19 01:57:57 +01:00
Pressable,
SectionList,
StyleSheet,
Text,
View
} from 'react-native'
import { Chase } from 'react-native-animated-spinkit'
2020-11-24 00:18:47 +01:00
export interface Props {
searchTerm: string | undefined
}
const ScreenSharedSearch: React.FC<Props> = ({ searchTerm }) => {
2020-12-18 19:02:18 +01:00
const navigation = useNavigation()
const { theme } = useTheme()
2021-01-11 21:36:57 +01:00
const { status, data, refetch } = useSearchQuery({
2021-01-07 19:13:09 +01:00
term: searchTerm,
options: { enabled: false }
})
2020-12-19 01:57:57 +01:00
const [setctionData, setSectionData] = useState<
{ title: string; data: any }[]
>([])
useEffect(
() =>
data &&
setSectionData(
Object.keys(data as Mastodon.Results)
2020-12-18 19:02:18 +01:00
.map(key => ({
title: key,
// @ts-ignore
data: data[key]
}))
.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
),
[data]
)
2020-12-18 19:02:18 +01:00
2020-12-19 01:57:57 +01:00
useEffect(() => {
if (searchTerm) {
refetch()
} else {
setSectionData([])
}
}, [searchTerm])
2020-12-18 19:02:18 +01:00
const listEmpty = useMemo(
() => (
<View style={styles.emptyBase}>
2021-01-04 18:29:02 +01:00
<View>
{status === 'loading' ? (
<View style={styles.loading}>
<Chase
size={StyleConstants.Font.Size.M * 1.25}
color={theme.secondary}
/>
</View>
) : (
<>
<Text
style={[
styles.emptyDefault,
styles.emptyFontSize,
{ color: theme.primary }
]}
>
<Text style={styles.emptyFontBold}></Text>
<Text style={styles.emptyFontBold}></Text>
<Text style={styles.emptyFontBold}></Text>
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>@username@domain</Text>
{' '}
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>#example</Text>
{' '}
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>URL</Text>
{' '}
</Text>
<Text style={[styles.emptyAdvanced, { color: theme.primary }]}>
<Text style={{ color: theme.secondary }}>URL</Text>
{' '}
</Text>
</>
)}
</View>
</View>
),
2020-12-20 17:53:24 +01:00
[status]
2020-12-18 19:02:18 +01:00
)
2020-12-19 01:57:57 +01:00
const sectionHeader = useCallback(
({ section: { title } }) => (
<View
2021-01-04 18:29:02 +01:00
style={[styles.sectionHeader, { backgroundColor: theme.background }]}
2020-12-19 01:57:57 +01:00
>
<Text style={[styles.sectionHeaderText, { color: theme.primary }]}>
{title}
</Text>
</View>
),
[]
)
const sectionFooter = useCallback(
({ section: { data, title } }) =>
!data.length ? (
<View
style={[styles.sectionFooter, { backgroundColor: theme.background }]}
>
<Text style={[styles.sectionFooterText, { color: theme.secondary }]}>
{' '}
<Text style={{ fontWeight: StyleConstants.Font.Weight.Bold }}>
{searchTerm}
</Text>{' '}
{title}
</Text>
</View>
) : null,
[searchTerm]
)
2021-01-04 18:29:02 +01:00
const listItem = useCallback(({ item, section, index }) => {
2020-12-19 01:57:57 +01:00
switch (section.title) {
case 'accounts':
2021-01-04 18:29:02 +01:00
return <ComponentAccount account={item} />
2020-12-19 01:57:57 +01:00
case 'hashtags':
return (
<Pressable
style={[styles.itemDefault, { borderBottomColor: theme.border }]}
onPress={() => {
navigation.goBack()
navigation.push('Screen-Shared-Hashtag', {
hashtag: item.name
})
}}
>
<Text style={[styles.itemHashtag, { color: theme.primary }]}>
#{item.name}
</Text>
</Pressable>
)
case 'statuses':
2021-01-04 18:29:02 +01:00
return <TimelineDefault item={item} index={index} disableDetails />
2020-12-19 01:57:57 +01:00
default:
return null
}
}, [])
2020-12-18 19:02:18 +01:00
return (
<KeyboardAvoidingView behavior='padding' style={{ flex: 1 }}>
2021-01-04 18:29:02 +01:00
<SectionList
style={styles.base}
renderItem={listItem}
stickySectionHeadersEnabled
sections={setctionData}
ListEmptyComponent={listEmpty}
keyboardShouldPersistTaps='always'
renderSectionHeader={sectionHeader}
renderSectionFooter={sectionFooter}
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
}
2020-12-18 19:02:18 +01:00
const styles = StyleSheet.create({
base: {
2021-01-04 18:29:02 +01:00
minHeight: '100%'
2020-12-18 19:02:18 +01:00
},
emptyBase: {
2021-01-04 18:29:02 +01:00
marginVertical: StyleConstants.Spacing.Global.PagePadding,
alignItems: 'center'
2020-12-18 19:02:18 +01:00
},
loading: { flex: 1, alignItems: 'center' },
emptyFontSize: { ...StyleConstants.FontStyle.S },
2020-12-18 19:02:18 +01:00
emptyFontBold: {
fontWeight: StyleConstants.Font.Weight.Bold
},
emptyDefault: {
marginBottom: StyleConstants.Spacing.L
},
emptyAdvanced: {
marginBottom: StyleConstants.Spacing.S
2020-12-19 01:57:57 +01:00
},
sectionHeader: {
2021-01-04 18:29:02 +01:00
padding: StyleConstants.Spacing.M
2020-12-19 01:57:57 +01:00
},
sectionHeaderText: {
...StyleConstants.FontStyle.M,
2020-12-19 01:57:57 +01:00
fontWeight: StyleConstants.Font.Weight.Bold,
textAlign: 'center'
},
sectionFooter: {
padding: StyleConstants.Spacing.S
},
sectionFooterText: {
...StyleConstants.FontStyle.S,
2020-12-19 01:57:57 +01:00
textAlign: 'center'
},
itemDefault: {
padding: StyleConstants.Spacing.S * 1.5,
borderBottomWidth: StyleSheet.hairlineWidth
},
itemHashtag: {
...StyleConstants.FontStyle.M
2020-12-18 19:02:18 +01:00
}
})
2020-11-24 00:18:47 +01:00
export default ScreenSharedSearch