2022-09-18 23:54:50 +02:00
|
|
|
import { ComponentEmojis } from '@components/Emojis'
|
2022-12-28 23:41:36 +01:00
|
|
|
import { EmojisState } from '@components/Emojis/Context'
|
|
|
|
import haptics from '@components/haptics'
|
2022-04-30 17:44:39 +02:00
|
|
|
import { HeaderLeft, HeaderRight } from '@components/Header'
|
2021-08-21 01:45:43 +02:00
|
|
|
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
2021-01-30 01:29:15 +01:00
|
|
|
import ComposeRoot from '@screens/Compose/Root'
|
2022-12-07 23:56:00 +01:00
|
|
|
import { formatText } from '@screens/Compose/utils/processText'
|
2022-12-28 23:41:36 +01:00
|
|
|
import { useQueryClient } from '@tanstack/react-query'
|
|
|
|
import { handleError } from '@utils/api/helpers'
|
2023-01-11 21:35:50 +01:00
|
|
|
import { RootStackScreenProps } from '@utils/navigation/navigators'
|
2022-12-28 23:41:36 +01:00
|
|
|
import { useInstanceQuery } from '@utils/queryHooks/instance'
|
|
|
|
import { usePreferencesQuery } from '@utils/queryHooks/preferences'
|
2023-01-03 23:57:23 +01:00
|
|
|
import { searchLocalStatus } from '@utils/queryHooks/search'
|
2021-02-05 13:45:02 +01:00
|
|
|
import {
|
2022-12-28 23:41:36 +01:00
|
|
|
getAccountStorage,
|
|
|
|
getGlobalStorage,
|
|
|
|
setAccountStorage,
|
|
|
|
setGlobalStorage
|
|
|
|
} from '@utils/storage/actions'
|
2020-12-29 16:19:04 +01:00
|
|
|
import { StyleConstants } from '@utils/styles/constants'
|
|
|
|
import { useTheme } from '@utils/styles/ThemeManager'
|
2022-12-28 23:41:36 +01:00
|
|
|
import * as StoreReview from 'expo-store-review'
|
2021-02-07 00:39:11 +01:00
|
|
|
import { filter } from 'lodash'
|
2022-12-29 00:36:35 +01:00
|
|
|
import React, { useEffect, useMemo, useReducer, useState } from 'react'
|
2021-01-19 01:13:45 +01:00
|
|
|
import { useTranslation } from 'react-i18next'
|
2022-09-18 23:54:50 +02:00
|
|
|
import { Alert, Keyboard, Platform } from 'react-native'
|
2022-12-28 23:41:36 +01:00
|
|
|
import ComposeDraftsList, { removeDraft } from './DraftsList'
|
|
|
|
import ComposeEditAttachment from './EditAttachment'
|
|
|
|
import { uploadAttachment } from './Root/Footer/addAttachment'
|
|
|
|
import ComposeContext from './utils/createContext'
|
|
|
|
import composeInitialState from './utils/initialState'
|
|
|
|
import composeParseState from './utils/parseState'
|
|
|
|
import composePost from './utils/post'
|
|
|
|
import composeReducer from './utils/reducer'
|
2021-01-30 01:29:15 +01:00
|
|
|
|
2020-11-15 20:29:43 +01:00
|
|
|
const Stack = createNativeStackNavigator()
|
2020-11-08 01:10:38 +01:00
|
|
|
|
2021-08-29 15:25:38 +02:00
|
|
|
const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
|
2021-01-07 22:18:14 +01:00
|
|
|
route: { params },
|
|
|
|
navigation
|
|
|
|
}) => {
|
2022-12-23 15:53:40 +01:00
|
|
|
const { t } = useTranslation(['common', 'screenCompose'])
|
2022-02-12 14:51:01 +01:00
|
|
|
const { colors } = useTheme()
|
2020-12-20 17:53:24 +01:00
|
|
|
const queryClient = useQueryClient()
|
2020-12-06 23:51:13 +01:00
|
|
|
|
2020-11-15 23:33:01 +01:00
|
|
|
const [hasKeyboard, setHasKeyboard] = useState(false)
|
|
|
|
useEffect(() => {
|
2022-09-18 23:54:50 +02:00
|
|
|
const keyboardShown = Keyboard.addListener('keyboardWillShow', () => setHasKeyboard(true))
|
|
|
|
const keyboardHidden = Keyboard.addListener('keyboardWillHide', () => setHasKeyboard(false))
|
2020-11-15 23:33:01 +01:00
|
|
|
|
|
|
|
return () => {
|
2021-10-10 21:58:36 +02:00
|
|
|
keyboardShown.remove()
|
|
|
|
keyboardHidden.remove()
|
2020-11-15 23:33:01 +01:00
|
|
|
}
|
|
|
|
}, [])
|
|
|
|
|
2022-12-28 23:41:36 +01:00
|
|
|
const { data: preferences } = usePreferencesQuery()
|
|
|
|
|
2021-02-07 00:39:11 +01:00
|
|
|
const initialReducerState = useMemo(() => {
|
|
|
|
if (params) {
|
|
|
|
return composeParseState(params)
|
|
|
|
} else {
|
|
|
|
return {
|
|
|
|
...composeInitialState,
|
|
|
|
timestamp: Date.now(),
|
2021-05-17 23:33:07 +02:00
|
|
|
attachments: {
|
|
|
|
...composeInitialState.attachments,
|
|
|
|
sensitive:
|
2022-12-28 23:41:36 +01:00
|
|
|
preferences?.['posting:default:sensitive'] !== undefined
|
|
|
|
? preferences['posting:default:sensitive']
|
2021-05-17 23:33:07 +02:00
|
|
|
: false
|
|
|
|
},
|
2022-12-28 23:41:36 +01:00
|
|
|
visibility: preferences?.['posting:default:visibility'] || 'public'
|
2021-02-07 00:39:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}, [])
|
|
|
|
|
2022-09-18 23:54:50 +02:00
|
|
|
const [composeState, composeDispatch] = useReducer(composeReducer, initialReducerState)
|
2020-12-07 12:31:40 +01:00
|
|
|
|
2022-12-28 23:41:36 +01:00
|
|
|
const { data: dataInstance } = useInstanceQuery()
|
|
|
|
const maxTootChars = dataInstance?.configuration?.statuses.max_characters || 500
|
2021-02-07 00:39:11 +01:00
|
|
|
const totalTextCount =
|
2022-09-18 23:54:50 +02:00
|
|
|
(composeState.spoiler.active ? composeState.spoiler.count : 0) + composeState.text.count
|
2021-02-07 00:39:11 +01:00
|
|
|
|
|
|
|
// If compose state is dirty, then disallow add back drafts
|
|
|
|
useEffect(() => {
|
|
|
|
composeDispatch({
|
|
|
|
type: 'dirty',
|
|
|
|
payload:
|
|
|
|
totalTextCount !== 0 ||
|
|
|
|
composeState.attachments.uploads.length !== 0 ||
|
|
|
|
(composeState.poll.active === true &&
|
|
|
|
filter(composeState.poll.options, o => {
|
|
|
|
return o !== undefined && o.length > 0
|
|
|
|
}).length > 0)
|
|
|
|
})
|
|
|
|
}, [
|
|
|
|
totalTextCount,
|
|
|
|
composeState.attachments.uploads.length,
|
|
|
|
composeState.poll.active,
|
|
|
|
composeState.poll.options
|
|
|
|
])
|
|
|
|
|
2020-12-07 12:31:40 +01:00
|
|
|
useEffect(() => {
|
|
|
|
switch (params?.type) {
|
2022-05-02 22:31:22 +02:00
|
|
|
case 'share':
|
|
|
|
if (params.text) {
|
|
|
|
formatText({
|
|
|
|
textInput: 'text',
|
|
|
|
composeDispatch,
|
|
|
|
content: params.text,
|
|
|
|
disableDebounce: true
|
|
|
|
})
|
|
|
|
}
|
2022-06-05 17:58:18 +02:00
|
|
|
if (params.media?.length) {
|
|
|
|
for (const m of params.media) {
|
|
|
|
uploadAttachment({
|
|
|
|
composeDispatch,
|
2022-08-07 01:18:10 +02:00
|
|
|
media: { uri: m.uri, fileName: 'temp.jpg', type: m.mime }
|
2022-06-05 17:58:18 +02:00
|
|
|
})
|
|
|
|
}
|
2022-05-02 22:31:22 +02:00
|
|
|
}
|
|
|
|
break
|
2020-12-07 12:31:40 +01:00
|
|
|
case 'edit':
|
2022-04-30 17:44:39 +02:00
|
|
|
case 'deleteEdit':
|
2020-12-07 12:31:40 +01:00
|
|
|
if (params.incomingStatus.spoiler_text) {
|
|
|
|
formatText({
|
2020-12-11 00:29:22 +01:00
|
|
|
textInput: 'spoiler',
|
2020-12-07 12:31:40 +01:00
|
|
|
composeDispatch,
|
|
|
|
content: params.incomingStatus.spoiler_text,
|
|
|
|
disableDebounce: true
|
|
|
|
})
|
|
|
|
}
|
|
|
|
formatText({
|
2020-12-11 00:29:22 +01:00
|
|
|
textInput: 'text',
|
2020-12-07 12:31:40 +01:00
|
|
|
composeDispatch,
|
|
|
|
content: params.incomingStatus.text!,
|
|
|
|
disableDebounce: true
|
|
|
|
})
|
|
|
|
break
|
|
|
|
case 'reply':
|
2022-09-18 23:54:50 +02:00
|
|
|
const actualStatus = params.incomingStatus.reblog || params.incomingStatus
|
2021-02-27 17:25:01 +01:00
|
|
|
if (actualStatus.spoiler_text) {
|
|
|
|
formatText({
|
|
|
|
textInput: 'spoiler',
|
|
|
|
composeDispatch,
|
|
|
|
content: actualStatus.spoiler_text,
|
|
|
|
disableDebounce: true
|
|
|
|
})
|
|
|
|
}
|
2021-03-11 22:27:38 +01:00
|
|
|
params.accts.length && // When replying to myself only, do not add space or even format text
|
|
|
|
formatText({
|
|
|
|
textInput: 'text',
|
|
|
|
composeDispatch,
|
|
|
|
content: params.accts.map(acct => `@${acct}`).join(' ') + ' ',
|
|
|
|
disableDebounce: true
|
|
|
|
})
|
2023-01-03 23:57:23 +01:00
|
|
|
searchLocalStatus(params.incomingStatus.uri).then(status => {
|
2023-01-01 17:20:35 +01:00
|
|
|
if (status?.uri === params.incomingStatus.uri) {
|
|
|
|
composeDispatch({ type: 'updateReply', payload: status })
|
2023-01-01 16:44:55 +01:00
|
|
|
}
|
|
|
|
})
|
2021-02-27 17:25:01 +01:00
|
|
|
break
|
2020-12-21 21:47:15 +01:00
|
|
|
case 'conversation':
|
|
|
|
formatText({
|
|
|
|
textInput: 'text',
|
|
|
|
composeDispatch,
|
2022-11-17 21:48:22 +01:00
|
|
|
content:
|
2022-11-28 14:42:01 +01:00
|
|
|
(params.text ? `${params.text}\n` : '') +
|
2022-11-17 21:48:22 +01:00
|
|
|
params.accts.map(acct => `@${acct}`).join(' ') +
|
|
|
|
' ',
|
2020-12-21 21:47:15 +01:00
|
|
|
disableDebounce: true
|
|
|
|
})
|
|
|
|
break
|
2020-12-07 12:31:40 +01:00
|
|
|
}
|
|
|
|
}, [params?.type])
|
2020-11-15 22:33:09 +01:00
|
|
|
|
2021-02-07 00:39:11 +01:00
|
|
|
const saveDraft = () => {
|
2022-12-28 23:41:36 +01:00
|
|
|
const payload = {
|
|
|
|
timestamp: composeState.timestamp,
|
|
|
|
spoiler: composeState.spoiler.raw,
|
|
|
|
text: composeState.text.raw,
|
|
|
|
poll: composeState.poll,
|
|
|
|
attachments: composeState.attachments,
|
|
|
|
visibility: composeState.visibility,
|
|
|
|
visibilityLock: composeState.visibilityLock,
|
|
|
|
replyToStatus: composeState.replyToStatus
|
|
|
|
}
|
|
|
|
|
|
|
|
const currentDrafts = getAccountStorage.object('drafts') || []
|
|
|
|
const draftIndex = currentDrafts?.findIndex(
|
|
|
|
({ timestamp }) => timestamp === composeState.timestamp
|
2021-02-07 00:39:11 +01:00
|
|
|
)
|
2022-12-28 23:41:36 +01:00
|
|
|
if (draftIndex === -1) {
|
|
|
|
currentDrafts?.unshift(payload)
|
|
|
|
} else {
|
|
|
|
currentDrafts[draftIndex] = payload
|
|
|
|
}
|
|
|
|
setAccountStorage([{ key: 'drafts', value: currentDrafts }])
|
2021-02-07 00:39:11 +01:00
|
|
|
}
|
|
|
|
useEffect(() => {
|
|
|
|
const autoSave = composeState.dirty
|
|
|
|
? setInterval(() => {
|
|
|
|
saveDraft()
|
2021-04-01 18:39:53 +02:00
|
|
|
}, 1000)
|
2022-12-28 23:41:36 +01:00
|
|
|
: removeDraft(composeState.timestamp)
|
|
|
|
return () => (autoSave ? clearInterval(autoSave) : undefined)
|
2021-02-07 00:39:11 +01:00
|
|
|
}, [composeState])
|
2020-12-06 23:51:13 +01:00
|
|
|
|
2022-12-29 00:36:35 +01:00
|
|
|
const headerRightDisabled = () => {
|
2021-02-08 00:23:32 +01:00
|
|
|
if (totalTextCount > maxTootChars) {
|
|
|
|
return true
|
|
|
|
}
|
2022-09-18 23:54:50 +02:00
|
|
|
if (composeState.attachments.uploads.filter(upload => upload.uploading).length > 0) {
|
2021-02-08 00:23:32 +01:00
|
|
|
return true
|
|
|
|
}
|
2022-09-18 23:54:50 +02:00
|
|
|
if (composeState.attachments.uploads.length === 0 && composeState.text.raw.length === 0) {
|
2021-02-08 00:23:32 +01:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
2022-12-29 00:36:35 +01:00
|
|
|
}
|
2021-03-18 23:32:31 +01:00
|
|
|
|
2022-09-18 23:54:50 +02:00
|
|
|
const inputProps: EmojisState['inputProps'] = [
|
|
|
|
{
|
|
|
|
value: [
|
|
|
|
composeState.text.raw,
|
2022-09-20 22:23:01 +02:00
|
|
|
content => {
|
|
|
|
formatText({ textInput: 'text', composeDispatch, content })
|
|
|
|
}
|
2022-09-18 23:54:50 +02:00
|
|
|
],
|
|
|
|
selection: [
|
|
|
|
composeState.text.selection,
|
|
|
|
selection => composeDispatch({ type: 'text', payload: { selection } })
|
|
|
|
],
|
2022-09-19 22:01:13 +02:00
|
|
|
isFocused: composeState.textInputFocus.isFocused.text,
|
2022-09-23 00:21:41 +02:00
|
|
|
maxLength: maxTootChars - (composeState.spoiler.active ? composeState.spoiler.count : 0),
|
|
|
|
ref: composeState.textInputFocus.refs.text
|
2022-09-19 22:01:13 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
value: [
|
|
|
|
composeState.spoiler.raw,
|
|
|
|
content => formatText({ textInput: 'spoiler', composeDispatch, content })
|
|
|
|
],
|
|
|
|
selection: [
|
|
|
|
composeState.spoiler.selection,
|
|
|
|
selection => composeDispatch({ type: 'spoiler', payload: { selection } })
|
|
|
|
],
|
|
|
|
isFocused: composeState.textInputFocus.isFocused.spoiler,
|
2022-09-23 00:21:41 +02:00
|
|
|
maxLength: maxTootChars - composeState.text.count,
|
|
|
|
ref: composeState.textInputFocus.refs.spoiler
|
2022-09-18 23:54:50 +02:00
|
|
|
}
|
|
|
|
]
|
|
|
|
|
2020-11-08 01:10:38 +01:00
|
|
|
return (
|
2022-09-18 23:54:50 +02:00
|
|
|
<ComponentEmojis
|
|
|
|
inputProps={inputProps}
|
|
|
|
customButton
|
|
|
|
customBehavior={Platform.OS === 'ios' ? 'padding' : undefined}
|
|
|
|
customEdges={hasKeyboard ? ['top'] : ['top', 'bottom']}
|
2021-01-14 00:43:35 +01:00
|
|
|
>
|
2022-09-18 23:54:50 +02:00
|
|
|
<ComposeContext.Provider value={{ composeState, composeDispatch }}>
|
|
|
|
<Stack.Navigator initialRouteName='Screen-Compose-Root'>
|
|
|
|
<Stack.Screen
|
|
|
|
name='Screen-Compose-Root'
|
|
|
|
component={ComposeRoot}
|
|
|
|
options={{
|
2022-12-29 00:36:35 +01:00
|
|
|
title: `${totalTextCount} / ${maxTootChars}`,
|
2022-09-18 23:54:50 +02:00
|
|
|
headerTitleStyle: {
|
|
|
|
fontWeight:
|
|
|
|
totalTextCount > maxTootChars
|
|
|
|
? StyleConstants.Font.Weight.Bold
|
|
|
|
: StyleConstants.Font.Weight.Normal,
|
|
|
|
fontSize: StyleConstants.Font.Size.M
|
|
|
|
},
|
|
|
|
headerTintColor: totalTextCount > maxTootChars ? colors.red : colors.secondary,
|
2022-12-29 00:36:35 +01:00
|
|
|
headerLeft: () => (
|
|
|
|
<HeaderLeft
|
|
|
|
type='text'
|
|
|
|
content={t('common:buttons.cancel')}
|
|
|
|
onPress={() => {
|
|
|
|
if (!composeState.dirty) {
|
|
|
|
navigation.goBack()
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
Alert.alert(t('screenCompose:heading.left.alert.title'), undefined, [
|
|
|
|
{
|
|
|
|
text: t('screenCompose:heading.left.alert.buttons.delete'),
|
|
|
|
style: 'destructive',
|
|
|
|
onPress: () => {
|
|
|
|
removeDraft(composeState.timestamp)
|
|
|
|
navigation.goBack()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
text: t('screenCompose:heading.left.alert.buttons.save'),
|
|
|
|
onPress: () => {
|
|
|
|
saveDraft()
|
|
|
|
navigation.goBack()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
text: t('common:buttons.cancel'),
|
|
|
|
style: 'cancel'
|
|
|
|
}
|
|
|
|
])
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
),
|
|
|
|
headerRight: () => (
|
|
|
|
<HeaderRight
|
|
|
|
type='text'
|
|
|
|
content={t(
|
|
|
|
`screenCompose:heading.right.button.${
|
|
|
|
(params?.type &&
|
|
|
|
(params.type === 'conversation'
|
|
|
|
? params.visibility === 'direct'
|
|
|
|
? params.type
|
|
|
|
: 'default'
|
|
|
|
: params.type)) ||
|
|
|
|
'default'
|
|
|
|
}`
|
|
|
|
)}
|
|
|
|
onPress={() => {
|
|
|
|
composeDispatch({ type: 'posting', payload: true })
|
|
|
|
|
|
|
|
composePost(params, composeState)
|
|
|
|
.then(res => {
|
|
|
|
haptics('Success')
|
|
|
|
if (Platform.OS === 'ios' && Platform.constants.osVersion === '13.3') {
|
|
|
|
// https://github.com/tooot-app/app/issues/59
|
|
|
|
} else {
|
|
|
|
const currentCount = getGlobalStorage.number(
|
|
|
|
'app.count_till_store_review'
|
|
|
|
)
|
|
|
|
if (currentCount === 10) {
|
|
|
|
StoreReview?.isAvailableAsync()
|
|
|
|
.then(() => StoreReview.requestReview())
|
|
|
|
.catch(() => {})
|
2023-01-04 22:39:29 +01:00
|
|
|
setGlobalStorage('app.count_till_store_review', (currentCount || 0) + 1)
|
2022-12-29 00:36:35 +01:00
|
|
|
} else {
|
|
|
|
setGlobalStorage('app.count_till_store_review', (currentCount || 0) + 1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (params?.type) {
|
2023-01-04 22:39:29 +01:00
|
|
|
case 'edit': // doesn't work
|
2023-01-06 01:01:10 +01:00
|
|
|
// mutateTimeline.mutate({
|
|
|
|
// type: 'editItem',
|
|
|
|
// status: res,
|
|
|
|
// navigationState: params.navigationState
|
|
|
|
// })
|
|
|
|
// break
|
2022-12-29 00:36:35 +01:00
|
|
|
case 'deleteEdit':
|
2023-01-04 22:39:29 +01:00
|
|
|
for (const navState of params.navigationState) {
|
|
|
|
navState && queryClient.invalidateQueries(navState)
|
2022-12-29 00:36:35 +01:00
|
|
|
}
|
|
|
|
break
|
2023-01-11 21:11:43 +01:00
|
|
|
case 'conversation':
|
|
|
|
case 'reply':
|
2023-01-11 21:35:50 +01:00
|
|
|
if (params.navigationState) {
|
|
|
|
for (const navState of params.navigationState) {
|
|
|
|
navState &&
|
|
|
|
navState[1].page !== 'Following' &&
|
|
|
|
queryClient.invalidateQueries(navState)
|
|
|
|
}
|
2023-01-11 21:11:43 +01:00
|
|
|
}
|
|
|
|
break
|
2022-12-29 00:36:35 +01:00
|
|
|
}
|
|
|
|
removeDraft(composeState.timestamp)
|
|
|
|
navigation.goBack()
|
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
if (error?.removeReply) {
|
|
|
|
Alert.alert(
|
|
|
|
t('screenCompose:heading.right.alert.removeReply.title'),
|
|
|
|
t('screenCompose:heading.right.alert.removeReply.description'),
|
|
|
|
[
|
|
|
|
{
|
|
|
|
text: t('common:buttons.cancel'),
|
|
|
|
onPress: () => {
|
|
|
|
composeDispatch({ type: 'posting', payload: false })
|
|
|
|
},
|
|
|
|
style: 'destructive'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
text: t('screenCompose:heading.right.alert.removeReply.confirm'),
|
|
|
|
onPress: () => {
|
|
|
|
composeDispatch({ type: 'removeReply' })
|
|
|
|
composeDispatch({ type: 'posting', payload: false })
|
|
|
|
},
|
|
|
|
style: 'default'
|
|
|
|
}
|
|
|
|
]
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
haptics('Error')
|
|
|
|
handleError({ message: 'Posting error', captureResponse: true })
|
|
|
|
composeDispatch({ type: 'posting', payload: false })
|
|
|
|
Alert.alert(
|
|
|
|
t('screenCompose:heading.right.alert.default.title'),
|
|
|
|
undefined,
|
|
|
|
[{ text: t('screenCompose:heading.right.alert.default.button') }]
|
|
|
|
)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}}
|
|
|
|
loading={composeState.posting}
|
|
|
|
disabled={headerRightDisabled()}
|
|
|
|
/>
|
|
|
|
)
|
2022-09-18 23:54:50 +02:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
<Stack.Screen
|
|
|
|
name='Screen-Compose-DraftsList'
|
|
|
|
component={ComposeDraftsList}
|
2023-01-27 18:44:48 +01:00
|
|
|
options={{ presentation: 'modal', headerShadowVisible: false }}
|
2022-09-18 23:54:50 +02:00
|
|
|
/>
|
|
|
|
<Stack.Screen
|
|
|
|
name='Screen-Compose-EditAttachment'
|
|
|
|
component={ComposeEditAttachment}
|
2023-01-27 18:44:48 +01:00
|
|
|
options={{ presentation: 'modal', headerShadowVisible: false }}
|
2022-09-18 23:54:50 +02:00
|
|
|
/>
|
|
|
|
</Stack.Navigator>
|
|
|
|
</ComposeContext.Provider>
|
|
|
|
</ComponentEmojis>
|
2020-11-08 01:10:38 +01:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-01-30 01:29:15 +01:00
|
|
|
export default ScreenCompose
|