mirror of
https://github.com/tooot-app/app
synced 2025-01-06 14:57:14 +01:00
Remove flat list in compose view
This commit is contained in:
parent
554825a9ea
commit
ac9738d358
@ -141,6 +141,9 @@ const ComposeActions: React.FC = () => {
|
|||||||
<View
|
<View
|
||||||
accessibilityRole='toolbar'
|
accessibilityRole='toolbar'
|
||||||
style={{
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 0,
|
||||||
|
width: '100%',
|
||||||
height: 45,
|
height: 45,
|
||||||
borderTopWidth: StyleSheet.hairlineWidth,
|
borderTopWidth: StyleSheet.hairlineWidth,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
import ComponentAccount from '@components/Account'
|
|
||||||
import haptics from '@components/haptics'
|
|
||||||
import ComponentHashtag from '@components/Hashtag'
|
|
||||||
import React, { useContext, useEffect } from 'react'
|
|
||||||
import ComposeContext from '../utils/createContext'
|
|
||||||
import { formatText } from '../utils/processText'
|
|
||||||
|
|
||||||
type Props = { item: Mastodon.Account & Mastodon.Tag }
|
|
||||||
|
|
||||||
const ComposeRootSuggestion: React.FC<Props> = ({ item }) => {
|
|
||||||
const { composeState, composeDispatch } = useContext(ComposeContext)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (composeState.text.raw.length === 0) {
|
|
||||||
composeDispatch({ type: 'tag', payload: undefined })
|
|
||||||
}
|
|
||||||
}, [composeState.text.raw.length])
|
|
||||||
|
|
||||||
const onPress = () => {
|
|
||||||
const focusedInput = composeState.textInputFocus.current
|
|
||||||
const updatedText = (): string => {
|
|
||||||
const main = item.acct ? `@${item.acct}` : `#${item.name}`
|
|
||||||
const textInput = composeState.textInputFocus.current
|
|
||||||
if (composeState.tag) {
|
|
||||||
const contentFront = composeState[textInput].raw.slice(0, composeState.tag.index)
|
|
||||||
const contentRear = composeState[textInput].raw.slice(composeState.tag.lastIndex)
|
|
||||||
|
|
||||||
const spaceFront =
|
|
||||||
composeState[textInput].raw.length === 0 || /\s/g.test(contentFront.slice(-1)) ? '' : ' '
|
|
||||||
const spaceRear = /\s/g.test(contentRear[0]) ? '' : ' '
|
|
||||||
|
|
||||||
return [contentFront, spaceFront, main, spaceRear, contentRear].join('')
|
|
||||||
} else {
|
|
||||||
return composeState[textInput].raw
|
|
||||||
}
|
|
||||||
}
|
|
||||||
formatText({
|
|
||||||
textInput: focusedInput,
|
|
||||||
composeDispatch,
|
|
||||||
content: updatedText(),
|
|
||||||
disableDebounce: true
|
|
||||||
})
|
|
||||||
haptics('Light')
|
|
||||||
}
|
|
||||||
|
|
||||||
return item.acct ? (
|
|
||||||
<ComponentAccount account={item} props={{ onPress }} />
|
|
||||||
) : (
|
|
||||||
<ComponentHashtag hashtag={item} onPress={onPress} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ComposeRootSuggestion
|
|
135
src/screens/Compose/Root/Suggestions.tsx
Normal file
135
src/screens/Compose/Root/Suggestions.tsx
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import ComponentAccount from '@components/Account'
|
||||||
|
import haptics from '@components/haptics'
|
||||||
|
import ComponentHashtag from '@components/Hashtag'
|
||||||
|
import Icon from '@components/Icon'
|
||||||
|
import ComponentSeparator from '@components/Separator'
|
||||||
|
import { useSearchQuery } from '@utils/queryHooks/search'
|
||||||
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
|
import React, { Fragment, useContext, useEffect } from 'react'
|
||||||
|
import { View } from 'react-native'
|
||||||
|
import { Circle } from 'react-native-animated-spinkit'
|
||||||
|
import ComposeContext from '../utils/createContext'
|
||||||
|
import { formatText } from '../utils/processText'
|
||||||
|
|
||||||
|
const ComposeRootSuggestions: React.FC = () => {
|
||||||
|
const { composeState, composeDispatch } = useContext(ComposeContext)
|
||||||
|
|
||||||
|
const { colors } = useTheme()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (composeState.text.raw.length === 0) {
|
||||||
|
composeDispatch({ type: 'tag', payload: undefined })
|
||||||
|
}
|
||||||
|
}, [composeState.text.raw.length])
|
||||||
|
|
||||||
|
const mapSchemaToType = () => {
|
||||||
|
if (composeState.tag) {
|
||||||
|
switch (composeState.tag?.schema) {
|
||||||
|
case '@':
|
||||||
|
return 'accounts'
|
||||||
|
case '#':
|
||||||
|
return 'hashtags'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const { isFetching, data, refetch } = useSearchQuery({
|
||||||
|
type: mapSchemaToType(),
|
||||||
|
term: composeState.tag?.raw.substring(1),
|
||||||
|
limit: 10,
|
||||||
|
options: { enabled: false }
|
||||||
|
})
|
||||||
|
useEffect(() => {
|
||||||
|
if (
|
||||||
|
(composeState.tag?.schema === '@' || composeState.tag?.schema === '#') &&
|
||||||
|
composeState.tag?.raw
|
||||||
|
) {
|
||||||
|
refetch()
|
||||||
|
}
|
||||||
|
}, [composeState.tag])
|
||||||
|
|
||||||
|
const onPress = (content: string) => {
|
||||||
|
const focusedInput = composeState.textInputFocus.current
|
||||||
|
const updatedText = (): string => {
|
||||||
|
const textInput = composeState.textInputFocus.current
|
||||||
|
if (composeState.tag) {
|
||||||
|
const contentFront = composeState[textInput].raw.slice(0, composeState.tag.index)
|
||||||
|
const contentRear = composeState[textInput].raw.slice(composeState.tag.lastIndex)
|
||||||
|
|
||||||
|
const spaceFront =
|
||||||
|
contentFront.length === 0 ||
|
||||||
|
composeState[textInput].raw.length === 0 ||
|
||||||
|
/\s/g.test(contentFront.slice(-1))
|
||||||
|
? ''
|
||||||
|
: ' '
|
||||||
|
const spaceRear = /\s/g.test(contentRear[0]) ? '' : ' '
|
||||||
|
|
||||||
|
return [contentFront, spaceFront, content, spaceRear, contentRear].join('')
|
||||||
|
} else {
|
||||||
|
return composeState[textInput].raw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
formatText({
|
||||||
|
textInput: focusedInput,
|
||||||
|
composeDispatch,
|
||||||
|
content: updatedText(),
|
||||||
|
disableDebounce: true
|
||||||
|
})
|
||||||
|
haptics('Light')
|
||||||
|
}
|
||||||
|
|
||||||
|
const main = () => {
|
||||||
|
if (composeState.tag) {
|
||||||
|
switch (composeState.tag?.schema) {
|
||||||
|
case '@':
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
{data?.accounts?.map(account => (
|
||||||
|
<Fragment key={account.id}>
|
||||||
|
<ComponentAccount
|
||||||
|
account={account}
|
||||||
|
props={{ onPress: () => onPress(`@${account.acct}`) }}
|
||||||
|
children={
|
||||||
|
<Icon
|
||||||
|
name='Plus'
|
||||||
|
size={StyleConstants.Font.Size.L}
|
||||||
|
color={colors.secondary}
|
||||||
|
style={{ marginLeft: 8 }}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<ComponentSeparator />
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
case '#':
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
{data?.hashtags?.map(hashtag => (
|
||||||
|
<Fragment key={hashtag.name}>
|
||||||
|
<ComponentHashtag hashtag={hashtag} onPress={() => onPress(`#${hashtag.name}`)} />
|
||||||
|
<ComponentSeparator />
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isFetching ? (
|
||||||
|
<View
|
||||||
|
key='listEmpty'
|
||||||
|
style={{ flex: 1, alignItems: 'center', marginVertical: StyleConstants.Spacing.M }}
|
||||||
|
>
|
||||||
|
<Circle size={StyleConstants.Font.Size.M * 1.25} color={colors.secondary} />
|
||||||
|
</View>
|
||||||
|
) : (
|
||||||
|
<>{main()}</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ComposeRootSuggestions
|
@ -1,21 +1,13 @@
|
|||||||
import ComponentSeparator from '@components/Separator'
|
import React, { useEffect, useRef } from 'react'
|
||||||
import { useSearchQuery } from '@utils/queryHooks/search'
|
import { AccessibilityInfo, findNodeHandle, ScrollView, View } from 'react-native'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
|
||||||
import React, { useContext, useEffect, useRef } from 'react'
|
|
||||||
import { AccessibilityInfo, findNodeHandle, FlatList, View } from 'react-native'
|
|
||||||
import { Circle } from 'react-native-animated-spinkit'
|
|
||||||
import ComposePosting from '../Posting'
|
import ComposePosting from '../Posting'
|
||||||
import ComposeContext from '../utils/createContext'
|
|
||||||
import ComposeActions from './Actions'
|
import ComposeActions from './Actions'
|
||||||
import ComposeDrafts from './Drafts'
|
import ComposeDrafts from './Drafts'
|
||||||
import ComposeRootFooter from './Footer'
|
import ComposeRootFooter from './Footer'
|
||||||
import ComposeRootHeader from './Header'
|
import ComposeRootHeader from './Header'
|
||||||
import ComposeRootSuggestion from './Suggestion'
|
import ComposeRootSuggestion from './Suggestions'
|
||||||
|
|
||||||
const ComposeRoot = () => {
|
const ComposeRoot = () => {
|
||||||
const { colors } = useTheme()
|
|
||||||
|
|
||||||
const accessibleRefDrafts = useRef(null)
|
const accessibleRefDrafts = useRef(null)
|
||||||
const accessibleRefAttachments = useRef(null)
|
const accessibleRefAttachments = useRef(null)
|
||||||
|
|
||||||
@ -24,60 +16,17 @@ const ComposeRoot = () => {
|
|||||||
tagDrafts && AccessibilityInfo.setAccessibilityFocus(tagDrafts)
|
tagDrafts && AccessibilityInfo.setAccessibilityFocus(tagDrafts)
|
||||||
}, [accessibleRefDrafts.current])
|
}, [accessibleRefDrafts.current])
|
||||||
|
|
||||||
const { composeState } = useContext(ComposeContext)
|
|
||||||
|
|
||||||
const mapSchemaToType = () => {
|
|
||||||
if (composeState.tag) {
|
|
||||||
switch (composeState.tag?.schema) {
|
|
||||||
case '@':
|
|
||||||
return 'accounts'
|
|
||||||
case '#':
|
|
||||||
return 'hashtags'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const { isFetching, data, refetch } = useSearchQuery({
|
|
||||||
type: mapSchemaToType(),
|
|
||||||
term: composeState.tag?.raw.substring(1),
|
|
||||||
options: { enabled: false }
|
|
||||||
})
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (
|
|
||||||
(composeState.tag?.schema === '@' || composeState.tag?.schema === '#') &&
|
|
||||||
composeState.tag?.raw
|
|
||||||
) {
|
|
||||||
refetch()
|
|
||||||
}
|
|
||||||
}, [composeState.tag])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ flex: 1 }}>
|
<>
|
||||||
<FlatList
|
<ScrollView keyboardShouldPersistTaps='always' style={{ marginBottom: 50 }}>
|
||||||
renderItem={({ item }) => <ComposeRootSuggestion item={item} />}
|
<ComposeRootHeader />
|
||||||
ListEmptyComponent={
|
<ComposeRootSuggestion />
|
||||||
isFetching ? (
|
<ComposeRootFooter accessibleRefAttachments={accessibleRefAttachments} />
|
||||||
<View key='listEmpty' style={{ flex: 1, alignItems: 'center' }}>
|
</ScrollView>
|
||||||
<Circle size={StyleConstants.Font.Size.M * 1.25} color={colors.secondary} />
|
|
||||||
</View>
|
|
||||||
) : null
|
|
||||||
}
|
|
||||||
keyboardShouldPersistTaps='always'
|
|
||||||
ListHeaderComponent={ComposeRootHeader}
|
|
||||||
ListFooterComponent={
|
|
||||||
<ComposeRootFooter accessibleRefAttachments={accessibleRefAttachments} />
|
|
||||||
}
|
|
||||||
ItemSeparatorComponent={ComponentSeparator}
|
|
||||||
// @ts-ignore
|
|
||||||
data={data ? data[mapSchemaToType()] : undefined}
|
|
||||||
keyExtractor={() => Math.random().toString()}
|
|
||||||
/>
|
|
||||||
<ComposeActions />
|
|
||||||
<ComposeDrafts accessibleRefDrafts={accessibleRefDrafts} />
|
<ComposeDrafts accessibleRefDrafts={accessibleRefDrafts} />
|
||||||
<ComposePosting />
|
<ComposePosting />
|
||||||
</View>
|
<ComposeActions />
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user