Fine tune compose more

This commit is contained in:
Zhiyuan Zheng 2020-12-06 22:32:36 +01:00
parent e5eaf162f4
commit 37ad208f8b
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
8 changed files with 92 additions and 66 deletions

View File

@ -34,10 +34,10 @@ export type PostState = {
active: boolean active: boolean
total: number total: number
options: { options: {
'0': string | undefined
'1': string | undefined '1': string | undefined
'2': string | undefined '2': string | undefined
'3': string | undefined '3': string | undefined
'4': string | undefined
} }
multiple: boolean multiple: boolean
expire: expire:

View File

@ -96,6 +96,30 @@ const ComposeActions: React.FC<Props> = ({
postState.attachmentUploadProgress postState.attachmentUploadProgress
]) ])
const emojiColor = useMemo(() => {
if (!postState.emoji.emojis) return theme.disabled
if (postState.emoji.active) {
return theme.primary
} else {
return theme.secondary
}
}, [postState.emoji.active, postState.emoji.emojis])
const emojiOnPress = useCallback(() => {
if (postState.emoji.emojis) {
if (postState.emoji.active) {
postDispatch({
type: 'emoji',
payload: { ...postState.emoji, active: false }
})
} else {
postDispatch({
type: 'emoji',
payload: { ...postState.emoji, active: true }
})
}
}
}, [postState.emoji.active, postState.emoji.emojis])
return ( return (
<Pressable <Pressable
style={[ style={[
@ -148,25 +172,8 @@ const ComposeActions: React.FC<Props> = ({
<Feather <Feather
name='smile' name='smile'
size={24} size={24}
color={ color={emojiColor}
postState.emoji.emojis?.length ? theme.secondary : theme.disabled onPress={emojiOnPress}
}
{...(postState.emoji.emojis && {
onPress: () => {
if (postState.emoji.active) {
postDispatch({
type: 'emoji',
payload: { ...postState.emoji, active: false }
})
} else {
Keyboard.dismiss()
postDispatch({
type: 'emoji',
payload: { ...postState.emoji, active: true }
})
}
}
})}
/> />
<Text <Text
style={[ style={[

View File

@ -150,6 +150,7 @@ const ComposeAttachments: React.FC<Props> = ({ postState, postDispatch }) => {
renderItem={renderAttachment} renderItem={renderAttachment}
ListFooterComponent={listFooter} ListFooterComponent={listFooter}
showsHorizontalScrollIndicator={false} showsHorizontalScrollIndicator={false}
keyboardShouldPersistTaps='handled'
/> />
</View> </View>
) )

View File

@ -31,6 +31,7 @@ const ComposeEmojis: React.FC<Props> = ({
<View style={styles.base}> <View style={styles.base}>
<SectionList <SectionList
horizontal horizontal
keyboardShouldPersistTaps='handled'
sections={postState.emoji.emojis!} sections={postState.emoji.emojis!}
keyExtractor={item => item.shortcode} keyExtractor={item => item.shortcode}
renderSectionHeader={({ section: { title } }) => ( renderSectionHeader={({ section: { title } }) => (

View File

@ -1,12 +1,5 @@
import React, { Dispatch, useEffect, useState } from 'react' import React, { Dispatch, useEffect, useState } from 'react'
import { import { ActionSheetIOS, StyleSheet, TextInput, View } from 'react-native'
ActionSheetIOS,
Pressable,
StyleSheet,
Text,
TextInput,
View
} from 'react-native'
import { Feather } from '@expo/vector-icons' import { Feather } from '@expo/vector-icons'
import { PostAction, PostState } from '../Compose' import { PostAction, PostState } from '../Compose'
@ -41,35 +34,51 @@ const ComposePoll: React.FC<Props> = ({ postState, postDispatch }) => {
return ( return (
<View style={[styles.base, { borderColor: theme.border }]}> <View style={[styles.base, { borderColor: theme.border }]}>
<View style={styles.options}> <View style={styles.options}>
{[...Array(postState.poll.total)].map((e, i) => ( {[...Array(postState.poll.total)].map((e, i) => {
<View key={i} style={styles.option}> const restOptions = Object.keys(postState.poll.options).filter(
<Feather o => parseInt(o) !== i && parseInt(o) < postState.poll.total
name={postState.poll.multiple ? 'square' : 'circle'} )
size={StyleConstants.Font.Size.L} let hasConflict = false
color={theme.secondary} restOptions.forEach(o => {
/> // @ts-ignore
<TextInput if (postState.poll.options[o] === postState.poll.options[i]) {
{...(i === 0 && firstRender && { autoFocus: true })} hasConflict = true
style={[ }
styles.textInput, })
{ borderColor: theme.border, color: theme.primary } return (
]} <View key={i} style={styles.option}>
placeholder={`选项 ${i}`} <Feather
placeholderTextColor={theme.secondary} name={postState.poll.multiple ? 'square' : 'circle'}
maxLength={50} size={StyleConstants.Font.Size.L}
value={postState.poll.options[i]} color={theme.secondary}
onChangeText={e => />
postDispatch({ <TextInput
type: 'poll', {...(i === 0 && firstRender && { autoFocus: true })}
payload: { style={[
...postState.poll, styles.textInput,
options: { ...postState.poll.options, [i]: e } {
borderColor: theme.border,
color: hasConflict ? theme.error : theme.primary
} }
}) ]}
} placeholder={`选项`}
/> placeholderTextColor={theme.secondary}
</View> maxLength={50}
))} // @ts-ignore
value={postState.poll.options[i]}
onChangeText={e =>
postDispatch({
type: 'poll',
payload: {
...postState.poll,
options: { ...postState.poll.options, [i]: e }
}
})
}
/>
</View>
)
})}
</View> </View>
<View style={styles.controlAmount}> <View style={styles.controlAmount}>
<View style={styles.firstButton}> <View style={styles.firstButton}>

View File

@ -92,6 +92,7 @@ const ComposeRoot: React.FC<Props> = ({ postState, postDispatch }) => {
progressViewStyle='bar' progressViewStyle='bar'
/> />
<FlatList <FlatList
keyboardShouldPersistTaps='handled'
ListHeaderComponent={ ListHeaderComponent={
<ComposeTextInput <ComposeTextInput
postState={postState} postState={postState}
@ -237,8 +238,8 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
paddingTop: StyleConstants.Spacing.S, paddingTop: StyleConstants.Spacing.S,
paddingBottom: StyleConstants.Spacing.S, paddingBottom: StyleConstants.Spacing.S,
paddingLeft: StyleConstants.Spacing.Global.PagePadding, marginLeft: StyleConstants.Spacing.Global.PagePadding,
paddingRight: StyleConstants.Spacing.Global.PagePadding, marginRight: StyleConstants.Spacing.Global.PagePadding,
borderBottomWidth: StyleSheet.hairlineWidth borderBottomWidth: StyleSheet.hairlineWidth
}, },
accountAvatar: { accountAvatar: {
@ -259,8 +260,8 @@ const styles = StyleSheet.create({
flex: 1, flex: 1,
paddingTop: StyleConstants.Spacing.S, paddingTop: StyleConstants.Spacing.S,
paddingBottom: StyleConstants.Spacing.S, paddingBottom: StyleConstants.Spacing.S,
paddingLeft: StyleConstants.Spacing.Global.PagePadding, marginLeft: StyleConstants.Spacing.Global.PagePadding,
paddingRight: StyleConstants.Spacing.Global.PagePadding, marginRight: StyleConstants.Spacing.Global.PagePadding,
borderBottomWidth: StyleSheet.hairlineWidth borderBottomWidth: StyleSheet.hairlineWidth
}, },
hashtagText: { hashtagText: {

View File

@ -62,7 +62,7 @@ const styles = StyleSheet.create({
paddingBottom: StyleConstants.Spacing.M, paddingBottom: StyleConstants.Spacing.M,
marginLeft: StyleConstants.Spacing.Global.PagePadding, marginLeft: StyleConstants.Spacing.Global.PagePadding,
marginRight: StyleConstants.Spacing.Global.PagePadding, marginRight: StyleConstants.Spacing.Global.PagePadding,
borderBottomWidth: 0.5 // borderBottomWidth: 0.5
} }
}) })

View File

@ -3,6 +3,7 @@ import React, { createElement, Dispatch } from 'react'
import { Text } from 'react-native' import { Text } from 'react-native'
import { RefetchOptions } from 'react-query/types/core/query' import { RefetchOptions } from 'react-query/types/core/query'
import Autolinker from 'src/modules/autolinker' import Autolinker from 'src/modules/autolinker'
import { useTheme } from 'src/utils/styles/ThemeManager'
import { PostAction, PostState } from '../Compose' import { PostAction, PostState } from '../Compose'
export interface Params { export interface Params {
@ -12,6 +13,16 @@ export interface Params {
disableDebounce?: boolean disableDebounce?: boolean
} }
const TagText = ({ text }: { text: string }) => {
const { theme } = useTheme()
return (
<Text style={{ color: theme.link }} key={Math.random()}>
{text}
</Text>
)
}
const debouncedSuggestions = debounce( const debouncedSuggestions = debounce(
(postDispatch, tag) => { (postDispatch, tag) => {
postDispatch({ type: 'tag', payload: tag }) postDispatch({ type: 'tag', payload: tag })
@ -77,11 +88,7 @@ const formatText = ({
const prevPart = parts.shift() const prevPart = parts.shift()
children.push(prevPart) children.push(prevPart)
contentLength = contentLength + (prevPart ? prevPart.length : 0) contentLength = contentLength + (prevPart ? prevPart.length : 0)
children.push( children.push(<TagText text={tag!.text} />)
<Text style={{ color: 'red' }} key={Math.random()}>
{tag!.text}
</Text>
)
switch (tag!.type) { switch (tag!.type) {
case 'url': case 'url':
contentLength = contentLength + 23 contentLength = contentLength + 23