mirror of
https://github.com/tooot-app/app
synced 2025-03-10 16:40:07 +01:00
Fine tune compose more
This commit is contained in:
parent
e5eaf162f4
commit
37ad208f8b
@ -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:
|
||||||
|
@ -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={[
|
||||||
|
@ -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>
|
||||||
)
|
)
|
||||||
|
@ -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 } }) => (
|
||||||
|
@ -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}>
|
||||||
|
@ -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: {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user