mirror of https://github.com/tooot-app/app
Remove flat list in compose view
This commit is contained in:
parent
554825a9ea
commit
ac9738d358
|
@ -141,6 +141,9 @@ const ComposeActions: React.FC = () => {
|
|||
<View
|
||||
accessibilityRole='toolbar'
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
width: '100%',
|
||||
height: 45,
|
||||
borderTopWidth: StyleSheet.hairlineWidth,
|
||||
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
|
|
@ -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 { useSearchQuery } from '@utils/queryHooks/search'
|
||||
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 React, { useEffect, useRef } from 'react'
|
||||
import { AccessibilityInfo, findNodeHandle, ScrollView, View } from 'react-native'
|
||||
import ComposePosting from '../Posting'
|
||||
import ComposeContext from '../utils/createContext'
|
||||
import ComposeActions from './Actions'
|
||||
import ComposeDrafts from './Drafts'
|
||||
import ComposeRootFooter from './Footer'
|
||||
import ComposeRootHeader from './Header'
|
||||
import ComposeRootSuggestion from './Suggestion'
|
||||
import ComposeRootSuggestion from './Suggestions'
|
||||
|
||||
const ComposeRoot = () => {
|
||||
const { colors } = useTheme()
|
||||
|
||||
const accessibleRefDrafts = useRef(null)
|
||||
const accessibleRefAttachments = useRef(null)
|
||||
|
||||
|
@ -24,60 +16,17 @@ const ComposeRoot = () => {
|
|||
tagDrafts && AccessibilityInfo.setAccessibilityFocus(tagDrafts)
|
||||
}, [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 (
|
||||
<View style={{ flex: 1 }}>
|
||||
<FlatList
|
||||
renderItem={({ item }) => <ComposeRootSuggestion item={item} />}
|
||||
ListEmptyComponent={
|
||||
isFetching ? (
|
||||
<View key='listEmpty' style={{ flex: 1, alignItems: 'center' }}>
|
||||
<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 />
|
||||
<>
|
||||
<ScrollView keyboardShouldPersistTaps='always' style={{ marginBottom: 50 }}>
|
||||
<ComposeRootHeader />
|
||||
<ComposeRootSuggestion />
|
||||
<ComposeRootFooter accessibleRefAttachments={accessibleRefAttachments} />
|
||||
</ScrollView>
|
||||
<ComposeDrafts accessibleRefDrafts={accessibleRefDrafts} />
|
||||
<ComposePosting />
|
||||
</View>
|
||||
<ComposeActions />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue