2021-01-19 01:13:45 +01:00
|
|
|
import ComponentAccount from '@components/Account'
|
|
|
|
import ComponentHashtag from '@components/Hashtag'
|
|
|
|
import ComponentSeparator from '@components/Separator'
|
2021-02-08 23:47:20 +01:00
|
|
|
import TimelineDefault from '@components/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'
|
2021-03-14 00:47:55 +01:00
|
|
|
import React, { useCallback, useMemo } from 'react'
|
2021-01-19 01:13:45 +01:00
|
|
|
import { Trans, useTranslation } from 'react-i18next'
|
2020-12-19 01:57:57 +01:00
|
|
|
import {
|
2020-12-27 00:32:51 +01:00
|
|
|
KeyboardAvoidingView,
|
2021-01-14 00:43:35 +01:00
|
|
|
Platform,
|
2020-12-19 01:57:57 +01:00
|
|
|
SectionList,
|
|
|
|
StyleSheet,
|
|
|
|
Text,
|
|
|
|
View
|
|
|
|
} from 'react-native'
|
2021-02-08 23:47:20 +01:00
|
|
|
import { Circle } from 'react-native-animated-spinkit'
|
2021-03-14 00:47:55 +01:00
|
|
|
import { SharedSearchProp } from './sharedScreens'
|
2020-11-24 00:18:47 +01:00
|
|
|
|
2021-03-14 00:47:55 +01:00
|
|
|
const TabSharedSearch: React.FC<SharedSearchProp> = ({
|
|
|
|
route: {
|
|
|
|
params: { text }
|
|
|
|
}
|
|
|
|
}) => {
|
2021-03-28 23:31:10 +02:00
|
|
|
const { t } = useTranslation('screenTabs')
|
2020-12-18 19:02:18 +01:00
|
|
|
const { theme } = useTheme()
|
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
|
|
|
}
|
2021-03-14 00:47:55 +01:00
|
|
|
const { status, data } = useSearchQuery({
|
|
|
|
term: text,
|
|
|
|
options: {
|
|
|
|
enabled: text !== undefined,
|
|
|
|
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]
|
|
|
|
}))
|
|
|
|
.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
|
|
|
|
2021-01-19 01:13:45 +01:00
|
|
|
const listEmpty = useMemo(() => {
|
|
|
|
return (
|
2020-12-27 00:32:51 +01:00
|
|
|
<View style={styles.emptyBase}>
|
2021-01-04 18:29:02 +01:00
|
|
|
<View>
|
|
|
|
{status === 'loading' ? (
|
|
|
|
<View style={styles.loading}>
|
2021-02-08 23:47:20 +01:00
|
|
|
<Circle
|
2021-01-04 18:29:02 +01:00
|
|
|
size={StyleConstants.Font.Size.M * 1.25}
|
|
|
|
color={theme.secondary}
|
|
|
|
/>
|
|
|
|
</View>
|
|
|
|
) : (
|
|
|
|
<>
|
|
|
|
<Text
|
|
|
|
style={[
|
|
|
|
styles.emptyDefault,
|
|
|
|
styles.emptyFontSize,
|
2021-03-21 14:14:10 +01:00
|
|
|
{ color: theme.primaryDefault }
|
2021-01-04 18:29:02 +01:00
|
|
|
]}
|
|
|
|
>
|
2021-01-19 01:13:45 +01:00
|
|
|
<Trans
|
2021-03-28 23:31:10 +02:00
|
|
|
i18nKey='screenTabs:shared.search.empty.general'
|
2021-01-19 01:13:45 +01:00
|
|
|
components={{ bold: <Text style={styles.emptyFontBold} /> }}
|
|
|
|
/>
|
2021-01-04 18:29:02 +01:00
|
|
|
</Text>
|
2021-04-01 01:11:12 +02:00
|
|
|
<Text
|
|
|
|
style={[styles.emptyAdvanced, { color: theme.primaryDefault }]}
|
|
|
|
>
|
2021-03-28 23:31:10 +02:00
|
|
|
{t('shared.search.empty.advanced.header')}
|
2021-01-04 18:29:02 +01:00
|
|
|
</Text>
|
2021-04-01 01:11:12 +02:00
|
|
|
<Text
|
|
|
|
style={[styles.emptyAdvanced, { color: theme.primaryDefault }]}
|
|
|
|
>
|
2021-01-04 18:29:02 +01:00
|
|
|
<Text style={{ color: theme.secondary }}>@username@domain</Text>
|
|
|
|
{' '}
|
2021-03-28 23:31:10 +02:00
|
|
|
{t('shared.search.empty.advanced.example.account')}
|
2021-01-04 18:29:02 +01:00
|
|
|
</Text>
|
2021-04-01 01:11:12 +02:00
|
|
|
<Text
|
|
|
|
style={[styles.emptyAdvanced, { color: theme.primaryDefault }]}
|
|
|
|
>
|
2021-01-04 18:29:02 +01:00
|
|
|
<Text style={{ color: theme.secondary }}>#example</Text>
|
2021-01-19 01:13:45 +01:00
|
|
|
{' '}
|
2021-03-28 23:31:10 +02:00
|
|
|
{t('shared.search.empty.advanced.example.hashtag')}
|
2021-01-04 18:29:02 +01:00
|
|
|
</Text>
|
2021-04-01 01:11:12 +02:00
|
|
|
<Text
|
|
|
|
style={[styles.emptyAdvanced, { color: theme.primaryDefault }]}
|
|
|
|
>
|
2021-01-04 18:29:02 +01:00
|
|
|
<Text style={{ color: theme.secondary }}>URL</Text>
|
2021-01-19 01:13:45 +01:00
|
|
|
{' '}
|
2021-03-28 23:31:10 +02:00
|
|
|
{t('shared.search.empty.advanced.example.statusLink')}
|
2021-01-04 18:29:02 +01:00
|
|
|
</Text>
|
2021-04-01 01:11:12 +02:00
|
|
|
<Text
|
|
|
|
style={[styles.emptyAdvanced, { color: theme.primaryDefault }]}
|
|
|
|
>
|
2021-01-04 18:29:02 +01:00
|
|
|
<Text style={{ color: theme.secondary }}>URL</Text>
|
2021-01-19 01:13:45 +01:00
|
|
|
{' '}
|
2021-03-28 23:31:10 +02:00
|
|
|
{t('shared.search.empty.advanced.example.accountLink')}
|
2021-01-04 18:29:02 +01:00
|
|
|
</Text>
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</View>
|
2020-12-27 00:32:51 +01:00
|
|
|
</View>
|
2021-01-19 01:13:45 +01:00
|
|
|
)
|
|
|
|
}, [status])
|
2020-12-19 01:57:57 +01:00
|
|
|
const sectionHeader = useCallback(
|
2021-01-19 01:13:45 +01:00
|
|
|
({ section: { translation } }) => (
|
2020-12-19 01:57:57 +01:00
|
|
|
<View
|
2021-04-01 01:11:12 +02:00
|
|
|
style={[
|
|
|
|
styles.sectionHeader,
|
|
|
|
{ backgroundColor: theme.backgroundDefault }
|
|
|
|
]}
|
2020-12-19 01:57:57 +01:00
|
|
|
>
|
2021-04-01 01:11:12 +02:00
|
|
|
<Text
|
|
|
|
style={[styles.sectionHeaderText, { color: theme.primaryDefault }]}
|
|
|
|
>
|
2021-01-19 01:13:45 +01:00
|
|
|
{translation}
|
2020-12-19 01:57:57 +01:00
|
|
|
</Text>
|
|
|
|
</View>
|
|
|
|
),
|
|
|
|
[]
|
|
|
|
)
|
|
|
|
const sectionFooter = useCallback(
|
2021-01-19 01:13:45 +01:00
|
|
|
({ section: { data, translation } }) =>
|
2020-12-19 01:57:57 +01:00
|
|
|
!data.length ? (
|
|
|
|
<View
|
2021-04-01 01:11:12 +02:00
|
|
|
style={[
|
|
|
|
styles.sectionFooter,
|
|
|
|
{ backgroundColor: theme.backgroundDefault }
|
|
|
|
]}
|
2020-12-19 01:57:57 +01:00
|
|
|
>
|
|
|
|
<Text style={[styles.sectionFooterText, { color: theme.secondary }]}>
|
2021-01-19 01:13:45 +01:00
|
|
|
<Trans
|
2021-04-01 01:11:12 +02:00
|
|
|
i18nKey='screenTabs:shared.search.notFound'
|
2021-03-14 00:47:55 +01:00
|
|
|
values={{ searchTerm: text, type: translation }}
|
2021-01-19 01:13:45 +01:00
|
|
|
components={{ bold: <Text style={styles.emptyFontBold} /> }}
|
|
|
|
/>
|
2020-12-19 01:57:57 +01:00
|
|
|
</Text>
|
|
|
|
</View>
|
|
|
|
) : null,
|
2021-03-14 00:47:55 +01:00
|
|
|
[text]
|
2020-12-19 01:57:57 +01:00
|
|
|
)
|
2021-01-19 01:13:45 +01:00
|
|
|
const listItem = useCallback(({ item, section }) => {
|
2020-12-19 01:57:57 +01:00
|
|
|
switch (section.title) {
|
|
|
|
case 'accounts':
|
2021-01-24 02:25:43 +01:00
|
|
|
return <ComponentAccount account={item} origin='search' />
|
2020-12-19 01:57:57 +01:00
|
|
|
case 'hashtags':
|
2021-01-24 02:25:43 +01:00
|
|
|
return <ComponentHashtag hashtag={item} origin='search' />
|
2020-12-19 01:57:57 +01:00
|
|
|
case 'statuses':
|
2021-01-24 02:25:43 +01:00
|
|
|
return <TimelineDefault item={item} disableDetails origin='search' />
|
2020-12-19 01:57:57 +01:00
|
|
|
default:
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
}, [])
|
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={styles.base}
|
|
|
|
renderItem={listItem}
|
|
|
|
stickySectionHeadersEnabled
|
2021-03-14 00:47:55 +01:00
|
|
|
sections={data || []}
|
2021-01-04 18:29:02 +01:00
|
|
|
ListEmptyComponent={listEmpty}
|
|
|
|
keyboardShouldPersistTaps='always'
|
|
|
|
renderSectionHeader={sectionHeader}
|
|
|
|
renderSectionFooter={sectionFooter}
|
|
|
|
keyExtractor={(item, index) => item + index}
|
|
|
|
SectionSeparatorComponent={ComponentSeparator}
|
|
|
|
ItemSeparatorComponent={ComponentSeparator}
|
|
|
|
/>
|
2020-12-27 00:32:51 +01:00
|
|
|
</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
|
|
|
},
|
2020-12-27 00:32:51 +01:00
|
|
|
loading: { flex: 1, alignItems: 'center' },
|
2020-12-29 00:21:05 +01:00
|
|
|
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: {
|
2020-12-29 00:21:05 +01:00
|
|
|
...StyleConstants.FontStyle.M,
|
2020-12-19 01:57:57 +01:00
|
|
|
fontWeight: StyleConstants.Font.Weight.Bold,
|
|
|
|
textAlign: 'center'
|
|
|
|
},
|
|
|
|
sectionFooter: {
|
|
|
|
padding: StyleConstants.Spacing.S
|
|
|
|
},
|
|
|
|
sectionFooterText: {
|
2020-12-29 00:21:05 +01:00
|
|
|
...StyleConstants.FontStyle.S,
|
2020-12-19 01:57:57 +01:00
|
|
|
textAlign: 'center'
|
2020-12-18 19:02:18 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2021-01-30 01:29:15 +01:00
|
|
|
export default TabSharedSearch
|