diff --git a/src/Index.tsx b/src/Index.tsx
index d8cbc5e2..5cffe4a8 100644
--- a/src/Index.tsx
+++ b/src/Index.tsx
@@ -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,66 +24,64 @@ export const Index: React.FC = () => {
-
-
- ({
- tabBarIcon: ({ focused, color, size }) => {
- let name: string
- switch (route.name) {
- case 'Local':
- name = 'home'
- break
- case 'Public':
- name = 'globe'
- break
- case 'PostRoot':
- name = 'plus'
- break
- case 'Notifications':
- name = 'bell'
- break
- case 'Me':
- name = focused ? 'smile' : 'meh'
- break
- default:
- name = 'alert-octagon'
- break
- }
- return
+
+ ({
+ tabBarIcon: ({ focused, color, size }) => {
+ let name: string
+ switch (route.name) {
+ case 'Local':
+ name = 'home'
+ break
+ case 'Public':
+ name = 'globe'
+ break
+ case 'PostRoot':
+ name = 'plus'
+ break
+ case 'Notifications':
+ name = 'bell'
+ break
+ case 'Me':
+ name = focused ? 'smile' : 'meh'
+ break
+ default:
+ name = 'alert-octagon'
+ break
+ }
+ return
+ }
+ })}
+ tabBarOptions={{
+ activeTintColor: 'black',
+ inactiveTintColor: 'gray',
+ showLabel: false
+ }}
+ >
+
+
+ ({
+ tabPress: e => {
+ e.preventDefault()
+ const {
+ length,
+ [length - 1]: last
+ } = navigation.dangerouslyGetState().history
+ navigation.navigate(last.key.split(new RegExp(/(.*?)-/))[1], {
+ screen: 'PostToot'
+ })
}
})}
- tabBarOptions={{
- activeTintColor: 'black',
- inactiveTintColor: 'gray',
- showLabel: false
- }}
- >
-
-
- ({
- tabPress: e => {
- e.preventDefault()
- const {
- length,
- [length - 1]: last
- } = navigation.dangerouslyGetState().history
- navigation.navigate(last.key.split(new RegExp(/(.*?)-/))[1], {
- screen: 'PostToot'
- })
- }
- })}
- />
-
-
-
+ />
+
+
+
- Toast.setRef(ref)} />
-
-
+ Toast.setRef(ref)} />
+
)
}
diff --git a/src/stacks/Shared/PostToot.tsx b/src/stacks/Shared/PostToot.tsx
index e4e1882e..8ab8cf55 100644
--- a/src/stacks/Shared/PostToot.tsx
+++ b/src/stacks/Shared/PostToot.tsx
@@ -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
- }
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,77 +86,102 @@ 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 (
-
- (
-
- Alert.alert('确认取消编辑?', '', [
- { text: '继续编辑', style: 'cancel' },
- {
- text: '退出编辑',
- style: 'destructive',
- onPress: () => navigation.goBack()
- }
- ])
- }
- >
- 退出编辑
-
- ),
- headerCenter: () => <>>,
- headerRight: () => (
- {
- if (postState.text.count < 0) {
- Alert.alert('字数超限', '', [
- {
- text: '返回继续编辑'
- }
- ])
- } else {
- const res = await client({
- method: 'post',
- instance: 'local',
- endpoint: 'statuses',
- headers: {
- 'Idempotency-Key':
- Date.now().toString() + Math.random().toString()
- },
- query: { status: postState.text.raw }
- })
- if (res.body.id) {
- Alert.alert('发布成功', '', [
+
+
+
+ (
+
+ Alert.alert('确认取消编辑?', '', [
+ { text: '继续编辑', style: 'cancel' },
{
- text: '好的',
+ text: '退出编辑',
+ style: 'destructive',
onPress: () => navigation.goBack()
}
])
- } else {
- Alert.alert('发布失败', '', [
- {
- text: '返回重试'
- }
- ])
}
- }
- }}
- >
- 发嘟嘟
-
- )
- }}
- >
- {props => (
-
- )}
-
-
+ >
+ 退出编辑
+
+ ),
+ headerCenter: () => <>>,
+ headerRight: () => (
+ {
+ if (postState.text.count < 0) {
+ Alert.alert('字数超限', '', [
+ {
+ text: '返回继续编辑'
+ }
+ ])
+ } else {
+ const res = await client({
+ method: 'post',
+ instance: 'local',
+ endpoint: 'statuses',
+ headers: {
+ 'Idempotency-Key':
+ Date.now().toString() + Math.random().toString()
+ },
+ query: { status: postState.text.raw }
+ })
+ if (res.body.id) {
+ Alert.alert('发布成功', '', [
+ {
+ text: '好的',
+ onPress: () => navigation.goBack()
+ }
+ ])
+ } else {
+ Alert.alert('发布失败', '', [
+ {
+ text: '返回重试'
+ }
+ ])
+ }
+ }
+ }}
+ >
+ 发嘟嘟
+
+ )
+ }}
+ >
+ {props => (
+
+ )}
+
+
+
+
)
}
diff --git a/src/stacks/Shared/PostToot/PostMain.tsx b/src/stacks/Shared/PostToot/PostMain.tsx
index 27d36d0e..ec5cdc41 100644
--- a/src/stacks/Shared/PostToot/PostMain.tsx
+++ b/src/stacks/Shared/PostToot/PostMain.tsx
@@ -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 = ({ 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 = ({ postState, postDispatch }) => {
}, [emojisData])
const debouncedSuggestions = useCallback(
- debounce(
- tag =>
- (() => {
- console.log(tag)
- postDispatch({ type: 'overlay', payload: 'suggestions' })
- postDispatch({ type: 'tag', payload: tag })
- })(),
- 300
- ),
+ debounce(tag => {
+ postDispatch({ type: 'overlay', payload: 'suggestions' })
+ postDispatch({ type: 'tag', payload: tag })
+ }, 500),
[]
)
let prevTags: PostState['tag'][] = []
@@ -87,7 +67,6 @@ const PostMain: React.FC = ({ postState, postDispatch }) => {
newType = 'url'
break
}
- // @ts-ignore
tags.push({
type: newType,
text: props.getMatchedText(),
@@ -99,7 +78,18 @@ const PostMain: React.FC = ({ 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,92 +137,77 @@ const PostMain: React.FC = ({ postState, postDispatch }) => {
}
})
}, [])
+
return (
-
- postDispatch({
- type: 'height',
- payload: { view: nativeEvent.layout.height }
- })
- }
- >
-
+ onChangeText({ content })}
+ onContentSizeChange={({ nativeEvent }) => {
+ setEditorMinHeight(nativeEvent.contentSize.height)
+ }}
+ onSelectionChange={({
+ nativeEvent: {
+ selection: { start, end }
+ }
+ }) => {
+ postDispatch({ type: 'selection', payload: { start, end } })
+ }}
+ scrollEnabled
>
- onChangeText({ content })}
- onContentSizeChange={({ nativeEvent }) => {
- postDispatch({
- type: 'height',
- payload: { editor: nativeEvent.contentSize.height }
- })
- }}
- onSelectionChange={({
- nativeEvent: {
- selection: { start, end }
- }
- }) => {
- postDispatch({ type: 'selection', payload: { start, end } })
- }}
- scrollEnabled
- >
- {postState.text.formatted}
-
- {postState.overlay === 'suggestions' ? (
-
-
-
- ) : (
- <>>
- )}
- {postState.overlay === 'emojis' ? (
-
-
-
- ) : (
- <>>
- )}
- Keyboard.dismiss()}>
-
-
-
- {
- if (postState.emojis?.length && postState.overlay === null) {
- postDispatch({ type: 'overlay', payload: 'emojis' })
- }
- }}
+ {postState.text.formatted}
+
+ {postState.overlay === 'suggestions' ? (
+
+
- {postState.text.count}
-
-
-
+
+ ) : (
+ <>>
+ )}
+ {postState.overlay === 'emojis' ? (
+
+
+
+ ) : (
+ <>>
+ )}
+ Keyboard.dismiss()}>
+
+
+
+ {
+ if (postState.emojis?.length && postState.overlay === null) {
+ postDispatch({ type: 'overlay', payload: 'emojis' })
+ }
+ }}
+ />
+ {postState.text.count}
+
+
)
}