mirror of https://github.com/tooot-app/app
Fix safe area view and keyboard view
This commit is contained in:
parent
188b97fbd8
commit
5cf6eaa8d9
|
@ -7,7 +7,6 @@ import React from 'react'
|
|||
import { Feather } from '@expo/vector-icons'
|
||||
import store from 'src/stacks/common/store'
|
||||
import { Provider } from 'react-redux'
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context'
|
||||
import Toast from 'react-native-toast-message'
|
||||
import { StatusBar } from 'expo-status-bar'
|
||||
|
||||
|
@ -25,7 +24,6 @@ export const Index: React.FC = () => {
|
|||
<Provider store={store}>
|
||||
<StatusBar style='auto' />
|
||||
|
||||
<SafeAreaProvider>
|
||||
<NavigationContainer>
|
||||
<Tab.Navigator
|
||||
screenOptions={({ route }) => ({
|
||||
|
@ -84,7 +82,6 @@ export const Index: React.FC = () => {
|
|||
|
||||
<Toast ref={(ref: any) => Toast.setRef(ref)} />
|
||||
</NavigationContainer>
|
||||
</SafeAreaProvider>
|
||||
</Provider>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
import React, { ReactNode, useReducer } from 'react'
|
||||
import { Alert, Pressable, Text } from 'react-native'
|
||||
import React, { ReactNode, useEffect, useReducer, useState } from 'react'
|
||||
import {
|
||||
Alert,
|
||||
Keyboard,
|
||||
KeyboardAvoidingView,
|
||||
Pressable,
|
||||
Text
|
||||
} from 'react-native'
|
||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||
import { createNativeStackNavigator } from 'react-native-screens/native-stack'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
|
||||
|
@ -24,11 +31,6 @@ export type PostState = {
|
|||
}
|
||||
| undefined
|
||||
emojis: mastodon.Emoji[] | undefined
|
||||
height: {
|
||||
view: number
|
||||
editor: number
|
||||
keyboard: number
|
||||
}
|
||||
}
|
||||
|
||||
export type PostAction =
|
||||
|
@ -52,10 +54,6 @@ export type PostAction =
|
|||
type: 'emojis'
|
||||
payload: PostState['emojis']
|
||||
}
|
||||
| {
|
||||
type: 'height'
|
||||
payload: Partial<PostState['height']>
|
||||
}
|
||||
|
||||
const postInitialState: PostState = {
|
||||
text: {
|
||||
|
@ -66,12 +64,7 @@ const postInitialState: PostState = {
|
|||
selection: { start: 0, end: 0 },
|
||||
overlay: null,
|
||||
tag: undefined,
|
||||
emojis: undefined,
|
||||
height: {
|
||||
view: 0,
|
||||
editor: 0,
|
||||
keyboard: 0
|
||||
}
|
||||
emojis: undefined
|
||||
}
|
||||
const postReducer = (state: PostState, action: PostAction): PostState => {
|
||||
switch (action.type) {
|
||||
|
@ -85,8 +78,6 @@ const postReducer = (state: PostState, action: PostAction): PostState => {
|
|||
return { ...state, tag: action.payload }
|
||||
case 'emojis':
|
||||
return { ...state, emojis: action.payload }
|
||||
case 'height':
|
||||
return { ...state, height: { ...state.height, ...action.payload } }
|
||||
default:
|
||||
throw new Error('Unexpected action')
|
||||
}
|
||||
|
@ -95,9 +86,32 @@ const postReducer = (state: PostState, action: PostAction): PostState => {
|
|||
const PostToot: React.FC = () => {
|
||||
const navigation = useNavigation()
|
||||
|
||||
const [hasKeyboard, setHasKeyboard] = useState(false)
|
||||
useEffect(() => {
|
||||
Keyboard.addListener('keyboardWillShow', _keyboardDidShow)
|
||||
Keyboard.addListener('keyboardWillHide', _keyboardDidHide)
|
||||
|
||||
// cleanup function
|
||||
return () => {
|
||||
Keyboard.removeListener('keyboardWillShow', _keyboardDidShow)
|
||||
Keyboard.removeListener('keyboardWillHide', _keyboardDidHide)
|
||||
}
|
||||
}, [])
|
||||
const _keyboardDidShow = () => {
|
||||
setHasKeyboard(true)
|
||||
}
|
||||
const _keyboardDidHide = () => {
|
||||
setHasKeyboard(false)
|
||||
}
|
||||
|
||||
const [postState, postDispatch] = useReducer(postReducer, postInitialState)
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView behavior='padding' style={{ flex: 1 }}>
|
||||
<SafeAreaView
|
||||
style={{ flex: 1 }}
|
||||
edges={hasKeyboard ? ['left', 'right'] : ['left', 'right', 'bottom']}
|
||||
>
|
||||
<Stack.Navigator>
|
||||
<Stack.Screen
|
||||
name='PostMain'
|
||||
|
@ -166,6 +180,8 @@ const PostToot: React.FC = () => {
|
|||
)}
|
||||
</Stack.Screen>
|
||||
</Stack.Navigator>
|
||||
</SafeAreaView>
|
||||
</KeyboardAvoidingView>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import React, { createElement, Dispatch, useCallback, useEffect } from 'react'
|
||||
import React, {
|
||||
createElement,
|
||||
Dispatch,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useState
|
||||
} from 'react'
|
||||
import {
|
||||
Keyboard,
|
||||
Pressable,
|
||||
|
@ -7,7 +13,6 @@ import {
|
|||
TextInput,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||
import { Feather } from '@expo/vector-icons'
|
||||
import { debounce, differenceWith, isEqual } from 'lodash'
|
||||
|
||||
|
@ -24,27 +29,7 @@ export interface Props {
|
|||
}
|
||||
|
||||
const PostMain: React.FC<Props> = ({ postState, postDispatch }) => {
|
||||
useEffect(() => {
|
||||
Keyboard.addListener('keyboardDidShow', _keyboardDidShow)
|
||||
Keyboard.addListener('keyboardDidHide', _keyboardDidHide)
|
||||
|
||||
return () => {
|
||||
Keyboard.removeListener('keyboardDidShow', _keyboardDidShow)
|
||||
Keyboard.removeListener('keyboardDidHide', _keyboardDidHide)
|
||||
}
|
||||
}, [])
|
||||
const _keyboardDidShow = (props: any) => {
|
||||
postDispatch({
|
||||
type: 'height',
|
||||
payload: { keyboard: props.endCoordinates.height }
|
||||
})
|
||||
}
|
||||
const _keyboardDidHide = () => {
|
||||
postDispatch({
|
||||
type: 'height',
|
||||
payload: { keyboard: 0 }
|
||||
})
|
||||
}
|
||||
const [editorMinHeight, setEditorMinHeight] = useState(0)
|
||||
|
||||
const { data: emojisData } = useQuery(['Emojis'], emojisFetch)
|
||||
useEffect(() => {
|
||||
|
@ -54,15 +39,10 @@ const PostMain: React.FC<Props> = ({ postState, postDispatch }) => {
|
|||
}, [emojisData])
|
||||
|
||||
const debouncedSuggestions = useCallback(
|
||||
debounce(
|
||||
tag =>
|
||||
(() => {
|
||||
console.log(tag)
|
||||
debounce(tag => {
|
||||
postDispatch({ type: 'overlay', payload: 'suggestions' })
|
||||
postDispatch({ type: 'tag', payload: tag })
|
||||
})(),
|
||||
300
|
||||
),
|
||||
}, 500),
|
||||
[]
|
||||
)
|
||||
let prevTags: PostState['tag'][] = []
|
||||
|
@ -87,7 +67,6 @@ const PostMain: React.FC<Props> = ({ postState, postDispatch }) => {
|
|||
newType = 'url'
|
||||
break
|
||||
}
|
||||
// @ts-ignore
|
||||
tags.push({
|
||||
type: newType,
|
||||
text: props.getMatchedText(),
|
||||
|
@ -99,7 +78,18 @@ const PostMain: React.FC<Props> = ({ postState, postDispatch }) => {
|
|||
|
||||
const changedTag = differenceWith(prevTags, tags, isEqual)
|
||||
// quick delete causes flicking of suggestion box
|
||||
if (changedTag.length && tags.length && !disableDebounce) {
|
||||
if (
|
||||
changedTag.length > 0 &&
|
||||
tags.length > 0 &&
|
||||
content.length > 0 &&
|
||||
!disableDebounce
|
||||
) {
|
||||
console.log('changedTag length')
|
||||
console.log(changedTag.length)
|
||||
console.log('tags length')
|
||||
console.log(tags.length)
|
||||
console.log('changed Tag')
|
||||
console.log(changedTag)
|
||||
if (changedTag[0]!.type !== 'url') {
|
||||
debouncedSuggestions(changedTag[0])
|
||||
}
|
||||
|
@ -147,26 +137,15 @@ const PostMain: React.FC<Props> = ({ postState, postDispatch }) => {
|
|||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<SafeAreaView
|
||||
style={styles.main}
|
||||
edges={['left', 'right', 'bottom']}
|
||||
onLayout={({ nativeEvent }) =>
|
||||
postDispatch({
|
||||
type: 'height',
|
||||
payload: { view: nativeEvent.layout.height }
|
||||
})
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={{ height: postState.height.view - postState.height.keyboard }}
|
||||
>
|
||||
<View style={{ flex: 1 }}>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.textInput,
|
||||
{
|
||||
flex: postState.overlay ? 0 : 1,
|
||||
minHeight: postState.height.editor + 14
|
||||
minHeight: editorMinHeight + 14
|
||||
}
|
||||
]}
|
||||
autoCapitalize='none'
|
||||
|
@ -177,10 +156,7 @@ const PostMain: React.FC<Props> = ({ postState, postDispatch }) => {
|
|||
placeholder='想说点什么'
|
||||
onChangeText={content => onChangeText({ content })}
|
||||
onContentSizeChange={({ nativeEvent }) => {
|
||||
postDispatch({
|
||||
type: 'height',
|
||||
payload: { editor: nativeEvent.contentSize.height }
|
||||
})
|
||||
setEditorMinHeight(nativeEvent.contentSize.height)
|
||||
}}
|
||||
onSelectionChange={({
|
||||
nativeEvent: {
|
||||
|
@ -232,7 +208,6 @@ const PostMain: React.FC<Props> = ({ postState, postDispatch }) => {
|
|||
<Text>{postState.text.count}</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue