mirror of https://github.com/tooot-app/app
Upload GIF using Android keyboard
https://github.com/tooot-app/app/issues/261
This commit is contained in:
parent
ed531d7371
commit
8c2004fe6c
|
@ -77,6 +77,7 @@
|
||||||
"react-native-flash-message": "0.2.1",
|
"react-native-flash-message": "0.2.1",
|
||||||
"react-native-gesture-handler": "2.4.1",
|
"react-native-gesture-handler": "2.4.1",
|
||||||
"react-native-htmlview": "0.16.0",
|
"react-native-htmlview": "0.16.0",
|
||||||
|
"react-native-image-keyboard": "^2.2.0",
|
||||||
"react-native-pager-view": "5.4.11",
|
"react-native-pager-view": "5.4.11",
|
||||||
"react-native-reanimated": "2.8.0",
|
"react-native-reanimated": "2.8.0",
|
||||||
"react-native-safe-area-context": "4.2.5",
|
"react-native-safe-area-context": "4.2.5",
|
||||||
|
|
|
@ -19,6 +19,7 @@ import * as SplashScreen from 'expo-splash-screen'
|
||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useState } from 'react'
|
||||||
import { AppState, LogBox, Platform } from 'react-native'
|
import { AppState, LogBox, Platform } from 'react-native'
|
||||||
import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
||||||
|
import 'react-native-image-keyboard'
|
||||||
import { enableFreeze } from 'react-native-screens'
|
import { enableFreeze } from 'react-native-screens'
|
||||||
import { QueryClientProvider } from 'react-query'
|
import { QueryClientProvider } from 'react-query'
|
||||||
import { Provider } from 'react-redux'
|
import { Provider } from 'react-redux'
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"buttons": {
|
"buttons": {
|
||||||
|
"OK": "OK",
|
||||||
"apply": "Apply",
|
"apply": "Apply",
|
||||||
"cancel": "Cancel"
|
"cancel": "Cancel"
|
||||||
},
|
},
|
||||||
|
|
|
@ -42,7 +42,13 @@
|
||||||
"placeholder": "Spoiler warning message"
|
"placeholder": "Spoiler warning message"
|
||||||
},
|
},
|
||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": "What's on your mind"
|
"placeholder": "What's on your mind",
|
||||||
|
"keyboardImage": {
|
||||||
|
"exceedMaximum": {
|
||||||
|
"title": "Maximum attachments amount reached",
|
||||||
|
"OK": "$t(common:buttons.OK)"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import apiInstance from '@api/instance'
|
|
||||||
import analytics from '@components/analytics'
|
import analytics from '@components/analytics'
|
||||||
import { HeaderLeft, HeaderRight } from '@components/Header'
|
import { HeaderLeft, HeaderRight } from '@components/Header'
|
||||||
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
||||||
|
|
|
@ -5,6 +5,7 @@ import Icon from '@components/Icon'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import { useActionSheet } from '@expo/react-native-action-sheet'
|
import { useActionSheet } from '@expo/react-native-action-sheet'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
|
import { getInstanceConfigurationStatusMaxAttachments } from '@utils/slices/instancesSlice'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import layoutAnimation from '@utils/styles/layoutAnimation'
|
import layoutAnimation from '@utils/styles/layoutAnimation'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
|
@ -17,8 +18,10 @@ import React, {
|
||||||
useRef
|
useRef
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { FlatList, Image, Pressable, StyleSheet, View } from 'react-native'
|
import { FlatList, Pressable, StyleSheet, View } from 'react-native'
|
||||||
import { Circle } from 'react-native-animated-spinkit'
|
import { Circle } from 'react-native-animated-spinkit'
|
||||||
|
import FastImage from 'react-native-fast-image'
|
||||||
|
import { useSelector } from 'react-redux'
|
||||||
import ComposeContext from '../../utils/createContext'
|
import ComposeContext from '../../utils/createContext'
|
||||||
import { ExtendedAttachment } from '../../utils/types'
|
import { ExtendedAttachment } from '../../utils/types'
|
||||||
import chooseAndUploadAttachment from './addAttachment'
|
import chooseAndUploadAttachment from './addAttachment'
|
||||||
|
@ -33,9 +36,14 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
const { showActionSheetWithOptions } = useActionSheet()
|
const { showActionSheetWithOptions } = useActionSheet()
|
||||||
const { composeState, composeDispatch } = useContext(ComposeContext)
|
const { composeState, composeDispatch } = useContext(ComposeContext)
|
||||||
const { t } = useTranslation('screenCompose')
|
const { t } = useTranslation('screenCompose')
|
||||||
const { colors, mode } = useTheme()
|
const { colors } = useTheme()
|
||||||
const navigation = useNavigation<any>()
|
const navigation = useNavigation<any>()
|
||||||
|
|
||||||
|
const maxAttachments = useSelector(
|
||||||
|
getInstanceConfigurationStatusMaxAttachments,
|
||||||
|
() => true
|
||||||
|
)
|
||||||
|
|
||||||
const flatListRef = useRef<FlatList>(null)
|
const flatListRef = useRef<FlatList>(null)
|
||||||
|
|
||||||
const sensitiveOnPress = useCallback(() => {
|
const sensitiveOnPress = useCallback(() => {
|
||||||
|
@ -124,7 +132,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
width: calculateWidth(item)
|
width: calculateWidth(item)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<FastImage
|
||||||
style={{ width: '100%', height: '100%' }}
|
style={{ width: '100%', height: '100%' }}
|
||||||
source={{
|
source={{
|
||||||
uri: item.local?.local_thumbnail || item.remote?.preview_url
|
uri: item.local?.local_thumbnail || item.remote?.preview_url
|
||||||
|
@ -320,7 +328,9 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||||
item.local?.uri || item.remote?.url || Math.random().toString()
|
item.local?.uri || item.remote?.url || Math.random().toString()
|
||||||
}
|
}
|
||||||
ListFooterComponent={
|
ListFooterComponent={
|
||||||
composeState.attachments.uploads.length < 4 ? listFooter : null
|
composeState.attachments.uploads.length < maxAttachments
|
||||||
|
? listFooter
|
||||||
|
: null
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,17 +1,25 @@
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
|
import { getInstanceConfigurationStatusMaxAttachments } from '@utils/slices/instancesSlice'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useContext } from 'react'
|
import React, { useContext } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { TextInput } from 'react-native'
|
import { Alert, TextInput } from 'react-native'
|
||||||
|
import { useSelector } from 'react-redux'
|
||||||
import formatText from '../../formatText'
|
import formatText from '../../formatText'
|
||||||
import ComposeContext from '../../utils/createContext'
|
import ComposeContext from '../../utils/createContext'
|
||||||
|
import { uploadAttachment } from '../Footer/addAttachment'
|
||||||
|
|
||||||
const ComposeTextInput: React.FC = () => {
|
const ComposeTextInput: React.FC = () => {
|
||||||
const { composeState, composeDispatch } = useContext(ComposeContext)
|
const { composeState, composeDispatch } = useContext(ComposeContext)
|
||||||
const { t } = useTranslation('screenCompose')
|
const { t } = useTranslation('screenCompose')
|
||||||
const { colors, mode } = useTheme()
|
const { colors, mode } = useTheme()
|
||||||
|
|
||||||
|
const maxAttachments = useSelector(
|
||||||
|
getInstanceConfigurationStatusMaxAttachments,
|
||||||
|
() => true
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextInput
|
<TextInput
|
||||||
keyboardAppearance={mode}
|
keyboardAppearance={mode}
|
||||||
|
@ -54,6 +62,36 @@ const ComposeTextInput: React.FC = () => {
|
||||||
}}
|
}}
|
||||||
ref={composeState.textInputFocus.refs.text}
|
ref={composeState.textInputFocus.refs.text}
|
||||||
scrollEnabled={false}
|
scrollEnabled={false}
|
||||||
|
onImageChange={({ nativeEvent }) => {
|
||||||
|
if (composeState.attachments.uploads.length >= maxAttachments) {
|
||||||
|
Alert.alert(
|
||||||
|
t(
|
||||||
|
'content.root.header.textInput.keyboardImage.exceedMaximum.title'
|
||||||
|
),
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: t(
|
||||||
|
'content.root.header.textInput.keyboardImage.exceedMaximum.OK'
|
||||||
|
),
|
||||||
|
style: 'default'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (nativeEvent.linkUri) {
|
||||||
|
uploadAttachment({
|
||||||
|
composeDispatch,
|
||||||
|
imageInfo: {
|
||||||
|
uri: nativeEvent.linkUri,
|
||||||
|
type: 'image',
|
||||||
|
width: 100,
|
||||||
|
height: 100
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<CustomText>{composeState.text.formatted}</CustomText>
|
<CustomText>{composeState.text.formatted}</CustomText>
|
||||||
</TextInput>
|
</TextInput>
|
||||||
|
|
|
@ -31,7 +31,7 @@ const AccountInformationAccount: React.FC<Props> = ({
|
||||||
const instanceUri = useSelector(getInstanceUri)
|
const instanceUri = useSelector(getInstanceUri)
|
||||||
|
|
||||||
const { data: relationship } = useRelationshipQuery({
|
const { data: relationship } = useRelationshipQuery({
|
||||||
id: account!.id,
|
id: account?.id || '',
|
||||||
options: { enabled: account !== undefined }
|
options: { enabled: account !== undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -6309,6 +6309,11 @@ react-native-htmlview@0.16.0:
|
||||||
entities "^1.1.1"
|
entities "^1.1.1"
|
||||||
htmlparser2-without-node-native "^3.9.2"
|
htmlparser2-without-node-native "^3.9.2"
|
||||||
|
|
||||||
|
react-native-image-keyboard@^2.2.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-native-image-keyboard/-/react-native-image-keyboard-2.2.0.tgz#dc3f90aaaac20a79315015a330e62e85547e0674"
|
||||||
|
integrity sha512-2JzKCXMBYiIUR6OtGV7F/lEWqwIU/6HS1CGOBulxwYNxoa7m1nZk45hNEZPP8SA5yE2pLNXEQePjc3WGAtXo3w==
|
||||||
|
|
||||||
react-native-iphone-x-helper@^1.3.1:
|
react-native-iphone-x-helper@^1.3.1:
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz#20c603e9a0e765fd6f97396638bdeb0e5a60b010"
|
resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz#20c603e9a0e765fd6f97396638bdeb0e5a60b010"
|
||||||
|
|
Loading…
Reference in New Issue