mirror of
https://github.com/tooot-app/app
synced 2025-04-22 06:07:23 +02:00
Updates
This commit is contained in:
parent
e9ea0ed71e
commit
811964e10f
@ -102,7 +102,11 @@ const Index: React.FC<Props> = ({ localCorrupt }) => {
|
|||||||
const queryNotification = useInfiniteQuery(
|
const queryNotification = useInfiniteQuery(
|
||||||
['Notifications', {}],
|
['Notifications', {}],
|
||||||
timelineFetch,
|
timelineFetch,
|
||||||
{ enabled: localInstance ? true : false }
|
{
|
||||||
|
enabled: localInstance ? true : false,
|
||||||
|
refetchInterval: 1000 * 60,
|
||||||
|
refetchIntervalInBackground: true
|
||||||
|
}
|
||||||
)
|
)
|
||||||
const prevNotification = useSelector(getLocalNotification)
|
const prevNotification = useSelector(getLocalNotification)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -41,6 +41,7 @@ const client = async ({
|
|||||||
instance === 'remote' ? instanceDomain || state.remote.url : state.local.url
|
instance === 'remote' ? instanceDomain || state.remote.url : state.local.url
|
||||||
|
|
||||||
return axios({
|
return axios({
|
||||||
|
timeout: method === 'post' ? 1000 * 60 : 1000 * 15,
|
||||||
method,
|
method,
|
||||||
baseURL: `https://${domain}/api/${version}/`,
|
baseURL: `https://${domain}/api/${version}/`,
|
||||||
url,
|
url,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { StyleConstants } from '@root/utils/styles/constants'
|
||||||
import React, { createElement } from 'react'
|
import React, { createElement } from 'react'
|
||||||
import { StyleProp, View, ViewStyle } from 'react-native'
|
import { StyleProp, View, ViewStyle } from 'react-native'
|
||||||
import * as FeatherIcon from 'react-native-feather'
|
import * as FeatherIcon from 'react-native-feather'
|
||||||
@ -8,7 +9,6 @@ export interface Props {
|
|||||||
color: string
|
color: string
|
||||||
fill?: string
|
fill?: string
|
||||||
strokeWidth?: number
|
strokeWidth?: number
|
||||||
inline?: boolean // When used in line of text, need to drag it down
|
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,7 +18,6 @@ const Icon: React.FC<Props> = ({
|
|||||||
color,
|
color,
|
||||||
fill,
|
fill,
|
||||||
strokeWidth = 2,
|
strokeWidth = 2,
|
||||||
inline = false,
|
|
||||||
style
|
style
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
@ -29,8 +28,7 @@ const Icon: React.FC<Props> = ({
|
|||||||
width: size,
|
width: size,
|
||||||
height: size,
|
height: size,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center'
|
||||||
marginBottom: inline ? -size * 0.125 : undefined
|
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
@ -27,8 +27,7 @@ const ParseEmojis: React.FC<Props> = ({
|
|||||||
},
|
},
|
||||||
image: {
|
image: {
|
||||||
width: StyleConstants.Font.Size[size],
|
width: StyleConstants.Font.Size[size],
|
||||||
height: StyleConstants.Font.Size[size],
|
height: StyleConstants.Font.Size[size]
|
||||||
marginBottom: -StyleConstants.Font.Size[size] * 0.125
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -51,7 +50,6 @@ const ParseEmojis: React.FC<Props> = ({
|
|||||||
{/* When emoji starts a paragraph, lineHeight will break */}
|
{/* When emoji starts a paragraph, lineHeight will break */}
|
||||||
{i === 0 ? <Text> </Text> : null}
|
{i === 0 ? <Text> </Text> : null}
|
||||||
<Image
|
<Image
|
||||||
// resizeMode='contain'
|
|
||||||
source={{ uri: emojis[emojiIndex].url }}
|
source={{ uri: emojis[emojiIndex].url }}
|
||||||
style={[styles.image]}
|
style={[styles.image]}
|
||||||
/>
|
/>
|
||||||
|
@ -9,6 +9,8 @@ import React, { useCallback, useMemo, useState } from 'react'
|
|||||||
import { Pressable, Text, View } from 'react-native'
|
import { Pressable, Text, View } from 'react-native'
|
||||||
import HTMLView from 'react-native-htmlview'
|
import HTMLView from 'react-native-htmlview'
|
||||||
import Animated, {
|
import Animated, {
|
||||||
|
measure,
|
||||||
|
useAnimatedRef,
|
||||||
useAnimatedStyle,
|
useAnimatedStyle,
|
||||||
useDerivedValue,
|
useDerivedValue,
|
||||||
useSharedValue,
|
useSharedValue,
|
||||||
@ -103,7 +105,6 @@ const renderNode = ({
|
|||||||
>
|
>
|
||||||
{!shouldBeTag ? (
|
{!shouldBeTag ? (
|
||||||
<Icon
|
<Icon
|
||||||
inline
|
|
||||||
color={theme.blue}
|
color={theme.blue}
|
||||||
name='ExternalLink'
|
name='ExternalLink'
|
||||||
size={StyleConstants.Font.Size[size]}
|
size={StyleConstants.Font.Size[size]}
|
||||||
@ -162,7 +163,13 @@ const ParseHTML: React.FC<Props> = ({
|
|||||||
)
|
)
|
||||||
const textComponent = useCallback(({ children }) => {
|
const textComponent = useCallback(({ children }) => {
|
||||||
if (children) {
|
if (children) {
|
||||||
return <ParseEmojis content={children.toString()} emojis={emojis} />
|
return (
|
||||||
|
<ParseEmojis
|
||||||
|
content={children.toString()}
|
||||||
|
emojis={emojis}
|
||||||
|
size={size}
|
||||||
|
/>
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -171,14 +178,15 @@ const ParseHTML: React.FC<Props> = ({
|
|||||||
({ children }) => {
|
({ children }) => {
|
||||||
const lineHeight = StyleConstants.Font.LineHeight[size]
|
const lineHeight = StyleConstants.Font.LineHeight[size]
|
||||||
|
|
||||||
|
const [lines, setLines] = useState<number | undefined>(undefined)
|
||||||
const [heightOriginal, setHeightOriginal] = useState<number>()
|
const [heightOriginal, setHeightOriginal] = useState<number>()
|
||||||
const [heightTruncated, setHeightTruncated] = useState<number>()
|
const [heightTruncated, setHeightTruncated] = useState<number>()
|
||||||
const [allowExpand, setAllowExpand] = useState(false)
|
const [expandAllow, setExpandAllow] = useState(false)
|
||||||
const [showAllText, setShowAllText] = useState(false)
|
const [expanded, setExpanded] = useState(false)
|
||||||
|
|
||||||
const viewHeight = useDerivedValue(() => {
|
const viewHeight = useDerivedValue(() => {
|
||||||
if (allowExpand) {
|
if (expandAllow) {
|
||||||
if (showAllText) {
|
if (expanded) {
|
||||||
return heightOriginal as number
|
return heightOriginal as number
|
||||||
} else {
|
} else {
|
||||||
return heightTruncated as number
|
return heightTruncated as number
|
||||||
@ -186,49 +194,29 @@ const ParseHTML: React.FC<Props> = ({
|
|||||||
} else {
|
} else {
|
||||||
return heightOriginal as number
|
return heightOriginal as number
|
||||||
}
|
}
|
||||||
}, [heightOriginal, heightTruncated, allowExpand, showAllText])
|
}, [heightOriginal, heightTruncated, expandAllow, expanded])
|
||||||
const ViewHeight = useAnimatedStyle(() => {
|
const ViewHeight = useAnimatedStyle(() => {
|
||||||
return {
|
return {
|
||||||
height: allowExpand
|
height: expandAllow
|
||||||
? showAllText
|
? expanded
|
||||||
? withTiming(viewHeight.value)
|
? withTiming(viewHeight.value)
|
||||||
: withTiming(viewHeight.value)
|
: withTiming(viewHeight.value)
|
||||||
: undefined
|
: viewHeight.value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const calNumberOfLines = useMemo(() => {
|
|
||||||
if (numberOfLines === 0) {
|
|
||||||
// For spoilers without calculation
|
|
||||||
return showAllText ? undefined : 1
|
|
||||||
} else {
|
|
||||||
if (heightOriginal) {
|
|
||||||
if (!heightTruncated) {
|
|
||||||
return numberOfLines
|
|
||||||
} else {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [heightOriginal, heightTruncated, allowExpand, showAllText])
|
|
||||||
|
|
||||||
const onLayout = useCallback(
|
const onLayout = useCallback(
|
||||||
({ nativeEvent }) => {
|
({ nativeEvent }) => {
|
||||||
if (numberOfLines === 0) {
|
if (!heightOriginal) {
|
||||||
// For spoilers without calculation
|
setHeightOriginal(nativeEvent.layout.height)
|
||||||
setAllowExpand(true)
|
setLines(numberOfLines === 0 ? 1 : numberOfLines)
|
||||||
} else {
|
} else {
|
||||||
if (!heightOriginal) {
|
if (!heightTruncated) {
|
||||||
setHeightOriginal(nativeEvent.layout.height)
|
setHeightTruncated(nativeEvent.layout.height)
|
||||||
|
setLines(undefined)
|
||||||
} else {
|
} else {
|
||||||
if (!heightTruncated) {
|
if (heightOriginal > heightTruncated) {
|
||||||
setHeightTruncated(nativeEvent.layout.height)
|
setExpandAllow(true)
|
||||||
} else {
|
|
||||||
if (heightOriginal > heightTruncated) {
|
|
||||||
setAllowExpand(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,21 +227,21 @@ const ParseHTML: React.FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<Animated.View style={[ViewHeight, { overflow: 'hidden' }]}>
|
<Animated.View style={[ViewHeight, { overflow: 'hidden' }]}>
|
||||||
<Text
|
<Animated.Text
|
||||||
|
children={children}
|
||||||
|
onLayout={onLayout}
|
||||||
|
numberOfLines={lines}
|
||||||
style={{
|
style={{
|
||||||
...StyleConstants.FontStyle[size],
|
...StyleConstants.FontStyle[size],
|
||||||
color: theme.primary,
|
color: theme.primary,
|
||||||
height: allowExpand ? heightOriginal : undefined
|
height: expandAllow ? heightOriginal : undefined
|
||||||
}}
|
}}
|
||||||
children={children}
|
|
||||||
numberOfLines={calNumberOfLines}
|
|
||||||
onLayout={onLayout}
|
|
||||||
/>
|
/>
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
{allowExpand ? (
|
{expandAllow ? (
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={() => setShowAllText(!showAllText)}
|
onPress={() => setExpanded(!expanded)}
|
||||||
style={{ marginTop: showAllText ? 0 : -lineHeight * 1.25 }}
|
style={{ marginTop: expanded ? 0 : -lineHeight * 1.25 }}
|
||||||
>
|
>
|
||||||
<LinearGradient
|
<LinearGradient
|
||||||
colors={[
|
colors={[
|
||||||
@ -273,7 +261,7 @@ const ParseHTML: React.FC<Props> = ({
|
|||||||
color: theme.primary
|
color: theme.primary
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{`${showAllText ? '折叠' : '展开'}${expandHint}`}
|
{`${expanded ? '折叠' : '展开'}${expandHint}`}
|
||||||
</Text>
|
</Text>
|
||||||
</LinearGradient>
|
</LinearGradient>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
|
@ -32,7 +32,7 @@ const RelationshipIncoming: React.FC<Props> = ({ id }) => {
|
|||||||
onSuccess: ({ body }) => {
|
onSuccess: ({ body }) => {
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
queryClient.setQueryData(relationshipQueryKey, body)
|
queryClient.setQueryData(relationshipQueryKey, body)
|
||||||
queryClient.invalidateQueries(['Notifications', {}])
|
queryClient.refetchQueries(['Notifications'])
|
||||||
},
|
},
|
||||||
onError: (err: any, { type }) => {
|
onError: (err: any, { type }) => {
|
||||||
haptics('Error')
|
haptics('Error')
|
||||||
|
@ -174,7 +174,23 @@ const Compose: React.FC<Props> = ({ route: { params }, navigation }) => {
|
|||||||
composePost(params, composeState)
|
composePost(params, composeState)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
haptics('Success')
|
haptics('Success')
|
||||||
queryClient.invalidateQueries(['Following'])
|
queryClient.invalidateQueries(['Following', {}])
|
||||||
|
if (
|
||||||
|
params?.type &&
|
||||||
|
(params.type === 'reply' || params.type === 'conversation')
|
||||||
|
) {
|
||||||
|
queryClient.invalidateQueries(
|
||||||
|
[
|
||||||
|
'Toot',
|
||||||
|
{
|
||||||
|
toot: params.incomingStatus.reblog
|
||||||
|
? params.incomingStatus.reblog.id
|
||||||
|
: params.incomingStatus.id
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{ exact: true, active: true }
|
||||||
|
)
|
||||||
|
}
|
||||||
navigation.goBack()
|
navigation.goBack()
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
@ -141,19 +141,18 @@ const ComposeAttachments: React.FC = () => {
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Chase
|
<Chase
|
||||||
size={StyleConstants.Font.Size.L * 2}
|
size={StyleConstants.Font.Size.L * 1.5}
|
||||||
color={theme.primaryOverlay}
|
color={theme.primaryOverlay}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<View style={styles.actions}>
|
||||||
<Button
|
<Button
|
||||||
type='icon'
|
type='icon'
|
||||||
content='X'
|
content='X'
|
||||||
spacing='M'
|
spacing='M'
|
||||||
round
|
round
|
||||||
overlay
|
overlay
|
||||||
style={styles.delete}
|
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
layoutAnimation()
|
layoutAnimation()
|
||||||
composeDispatch({
|
composeDispatch({
|
||||||
@ -169,14 +168,13 @@ const ComposeAttachments: React.FC = () => {
|
|||||||
spacing='M'
|
spacing='M'
|
||||||
round
|
round
|
||||||
overlay
|
overlay
|
||||||
style={styles.edit}
|
|
||||||
onPress={() =>
|
onPress={() =>
|
||||||
navigation.navigate('Screen-Shared-Compose-EditAttachment', {
|
navigation.navigate('Screen-Shared-Compose-EditAttachment', {
|
||||||
index
|
index
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
@ -294,15 +292,12 @@ const styles = StyleSheet.create({
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
},
|
},
|
||||||
delete: {
|
actions: {
|
||||||
position: 'absolute',
|
...StyleSheet.absoluteFillObject,
|
||||||
top: StyleConstants.Spacing.S,
|
justifyContent: 'space-between',
|
||||||
right: StyleConstants.Spacing.S
|
alignContent: 'flex-end',
|
||||||
},
|
alignItems: 'flex-end',
|
||||||
edit: {
|
padding: StyleConstants.Spacing.S
|
||||||
position: 'absolute',
|
|
||||||
bottom: StyleConstants.Spacing.S,
|
|
||||||
right: StyleConstants.Spacing.S
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -29,10 +29,16 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index, focus }) => {
|
|||||||
const theAttachmentRemote = composeState.attachments.uploads[index].remote!
|
const theAttachmentRemote = composeState.attachments.uploads[index].remote!
|
||||||
const theAttachmentLocal = composeState.attachments.uploads[index].local!
|
const theAttachmentLocal = composeState.attachments.uploads[index].local!
|
||||||
|
|
||||||
|
const imageWidthBase =
|
||||||
|
theAttachmentRemote.meta?.original?.aspect < 1
|
||||||
|
? Dimensions.get('screen').width *
|
||||||
|
theAttachmentRemote.meta?.original?.aspect
|
||||||
|
: Dimensions.get('screen').width
|
||||||
|
const padding = (Dimensions.get('screen').width - imageWidthBase) / 2
|
||||||
const imageDimensionis = {
|
const imageDimensionis = {
|
||||||
width: Dimensions.get('screen').width,
|
width: imageWidthBase,
|
||||||
height:
|
height:
|
||||||
Dimensions.get('screen').width /
|
imageWidthBase /
|
||||||
(theAttachmentRemote as Mastodon.AttachmentImage).meta?.original?.aspect!
|
(theAttachmentRemote as Mastodon.AttachmentImage).meta?.original?.aspect!
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,8 +81,14 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index, focus }) => {
|
|||||||
{
|
{
|
||||||
translateX: interpolate(
|
translateX: interpolate(
|
||||||
panX.value,
|
panX.value,
|
||||||
[-imageDimensionis.width / 2, imageDimensionis.width / 2],
|
[
|
||||||
[-imageDimensionis.width / 2, imageDimensionis.width / 2],
|
-imageDimensionis.width / 2 + padding,
|
||||||
|
imageDimensionis.width / 2 + padding
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-imageDimensionis.width / 2 + padding,
|
||||||
|
imageDimensionis.width / 2 + padding
|
||||||
|
],
|
||||||
Extrapolate.CLAMP
|
Extrapolate.CLAMP
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -94,7 +106,7 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index, focus }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<View style={{ overflow: 'hidden' }}>
|
<View style={{ overflow: 'hidden', flex: 1, alignItems: 'center' }}>
|
||||||
<Image
|
<Image
|
||||||
style={{
|
style={{
|
||||||
width: imageDimensionis.width,
|
width: imageDimensionis.width,
|
||||||
@ -126,13 +138,13 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index, focus }) => {
|
|||||||
/>
|
/>
|
||||||
<G transform='translate(967, 967)'>
|
<G transform='translate(967, 967)'>
|
||||||
<Circle
|
<Circle
|
||||||
stroke={theme.background}
|
stroke={theme.primaryOverlay}
|
||||||
strokeWidth='2'
|
strokeWidth='2'
|
||||||
cx='33'
|
cx='33'
|
||||||
cy='33'
|
cy='33'
|
||||||
r='33'
|
r='33'
|
||||||
/>
|
/>
|
||||||
<Circle fill={theme.background} cx='33' cy='33' r='2' />
|
<Circle fill={theme.primaryOverlay} cx='33' cy='33' r='2' />
|
||||||
</G>
|
</G>
|
||||||
</G>
|
</G>
|
||||||
</G>
|
</G>
|
||||||
|
@ -38,10 +38,19 @@ const ComposeEditAttachmentRoot: React.FC<Props> = ({
|
|||||||
return <ComposeEditAttachmentImage index={index} focus={focus} />
|
return <ComposeEditAttachmentImage index={index} focus={focus} />
|
||||||
case 'video':
|
case 'video':
|
||||||
case 'gifv':
|
case 'gifv':
|
||||||
|
const video = composeState.attachments.uploads[index]
|
||||||
return (
|
return (
|
||||||
<AttachmentVideo
|
<AttachmentVideo
|
||||||
sensitiveShown={false}
|
sensitiveShown={false}
|
||||||
video={theAttachment as Mastodon.AttachmentVideo}
|
video={
|
||||||
|
video.local
|
||||||
|
? ({
|
||||||
|
url: video.local.uri,
|
||||||
|
preview_url: video.local.local_thumbnail,
|
||||||
|
blurhash: video.remote?.blurhash
|
||||||
|
} as Mastodon.AttachmentVideo)
|
||||||
|
: (video.remote! as Mastodon.AttachmentVideo)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -56,7 +65,6 @@ const ComposeEditAttachmentRoot: React.FC<Props> = ({
|
|||||||
为附件添加文字说明
|
为附件添加文字说明
|
||||||
</Text>
|
</Text>
|
||||||
<TextInput
|
<TextInput
|
||||||
autoFocus
|
|
||||||
style={[styles.altTextInput, { borderColor: theme.border }]}
|
style={[styles.altTextInput, { borderColor: theme.border }]}
|
||||||
autoCapitalize='none'
|
autoCapitalize='none'
|
||||||
autoCorrect={false}
|
autoCorrect={false}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import client from '@api/client'
|
import client from '@api/client'
|
||||||
import * as ImagePicker from 'expo-image-picker'
|
import * as ImagePicker from 'expo-image-picker'
|
||||||
|
import * as Crypto from 'expo-crypto'
|
||||||
import { ImageInfo } from 'expo-image-picker/build/ImagePicker.types'
|
import { ImageInfo } from 'expo-image-picker/build/ImagePicker.types'
|
||||||
import * as VideoThumbnails from 'expo-video-thumbnails'
|
import * as VideoThumbnails from 'expo-video-thumbnails'
|
||||||
import { Dispatch } from 'react'
|
import { Dispatch } from 'react'
|
||||||
@ -11,13 +12,17 @@ export interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const addAttachment = async ({ composeDispatch }: Props): Promise<any> => {
|
const addAttachment = async ({ composeDispatch }: Props): Promise<any> => {
|
||||||
const uploadAttachment = (result: ImageInfo) => {
|
const uploadAttachment = async (result: ImageInfo) => {
|
||||||
|
const hash = await Crypto.digestStringAsync(
|
||||||
|
Crypto.CryptoDigestAlgorithm.SHA256,
|
||||||
|
result.uri + Math.random()
|
||||||
|
)
|
||||||
switch (result.type) {
|
switch (result.type) {
|
||||||
case 'image':
|
case 'image':
|
||||||
composeDispatch({
|
composeDispatch({
|
||||||
type: 'attachment/upload/start',
|
type: 'attachment/upload/start',
|
||||||
payload: {
|
payload: {
|
||||||
local: { ...result, local_thumbnail: result.uri },
|
local: { ...result, local_thumbnail: result.uri, hash },
|
||||||
uploading: true
|
uploading: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -28,7 +33,7 @@ const addAttachment = async ({ composeDispatch }: Props): Promise<any> => {
|
|||||||
composeDispatch({
|
composeDispatch({
|
||||||
type: 'attachment/upload/start',
|
type: 'attachment/upload/start',
|
||||||
payload: {
|
payload: {
|
||||||
local: { ...result, local_thumbnail: uri },
|
local: { ...result, local_thumbnail: uri, hash },
|
||||||
uploading: true
|
uploading: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -37,7 +42,7 @@ const addAttachment = async ({ composeDispatch }: Props): Promise<any> => {
|
|||||||
composeDispatch({
|
composeDispatch({
|
||||||
type: 'attachment/upload/start',
|
type: 'attachment/upload/start',
|
||||||
payload: {
|
payload: {
|
||||||
local: result,
|
local: { ...result, hash },
|
||||||
uploading: true
|
uploading: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -47,7 +52,7 @@ const addAttachment = async ({ composeDispatch }: Props): Promise<any> => {
|
|||||||
composeDispatch({
|
composeDispatch({
|
||||||
type: 'attachment/upload/start',
|
type: 'attachment/upload/start',
|
||||||
payload: {
|
payload: {
|
||||||
local: result,
|
local: { ...result, hash },
|
||||||
uploading: true
|
uploading: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -62,7 +67,7 @@ const addAttachment = async ({ composeDispatch }: Props): Promise<any> => {
|
|||||||
type: 'image/jpeg/jpg'
|
type: 'image/jpeg/jpg'
|
||||||
})
|
})
|
||||||
|
|
||||||
client({
|
return client({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
instance: 'local',
|
instance: 'local',
|
||||||
url: 'media',
|
url: 'media',
|
||||||
@ -74,25 +79,30 @@ const addAttachment = async ({ composeDispatch }: Props): Promise<any> => {
|
|||||||
type: 'attachment/upload/end',
|
type: 'attachment/upload/end',
|
||||||
payload: { remote: body, local: result }
|
payload: { remote: body, local: result }
|
||||||
})
|
})
|
||||||
return Promise.resolve()
|
|
||||||
} else {
|
} else {
|
||||||
|
composeDispatch({
|
||||||
|
type: 'attachment/upload/fail',
|
||||||
|
payload: hash
|
||||||
|
})
|
||||||
Alert.alert('上传失败', '', [
|
Alert.alert('上传失败', '', [
|
||||||
{
|
{
|
||||||
text: '返回重试',
|
text: '返回重试',
|
||||||
onPress: () => {}
|
onPress: () => {}
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
return Promise.reject()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
composeDispatch({
|
||||||
|
type: 'attachment/upload/fail',
|
||||||
|
payload: hash
|
||||||
|
})
|
||||||
Alert.alert('上传失败', '', [
|
Alert.alert('上传失败', '', [
|
||||||
{
|
{
|
||||||
text: '返回重试',
|
text: '返回重试',
|
||||||
onPress: () => {}
|
onPress: () => {}
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
return Promise.reject()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ const composePost = async (
|
|||||||
|
|
||||||
formData.append('visibility', composeState.visibility)
|
formData.append('visibility', composeState.visibility)
|
||||||
|
|
||||||
const res = await client({
|
return client({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
instance: 'local',
|
instance: 'local',
|
||||||
url: 'statuses',
|
url: 'statuses',
|
||||||
@ -63,12 +63,6 @@ const composePost = async (
|
|||||||
},
|
},
|
||||||
body: formData
|
body: formData
|
||||||
})
|
})
|
||||||
|
|
||||||
if (res.body.id) {
|
|
||||||
return Promise.resolve()
|
|
||||||
} else {
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default composePost
|
export default composePost
|
||||||
|
@ -40,6 +40,16 @@ const composeReducer = (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case 'attachment/upload/fail':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
attachments: {
|
||||||
|
...state.attachments,
|
||||||
|
uploads: state.attachments.uploads.filter(
|
||||||
|
upload => upload.local.hash !== action.payload
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
case 'attachment/delete':
|
case 'attachment/delete':
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
6
src/screens/Shared/Compose/utils/types.d.ts
vendored
6
src/screens/Shared/Compose/utils/types.d.ts
vendored
@ -1,6 +1,6 @@
|
|||||||
export type ExtendedAttachment = {
|
export type ExtendedAttachment = {
|
||||||
remote?: Mastodon.Attachment
|
remote?: Mastodon.Attachment
|
||||||
local?: ImageInfo & { local_thumbnail?: string }
|
local?: ImageInfo & { local_thumbnail?: string; hash?: string }
|
||||||
uploading?: boolean
|
uploading?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +94,10 @@ export type ComposeAction =
|
|||||||
type: 'attachment/upload/end'
|
type: 'attachment/upload/end'
|
||||||
payload: { remote: Mastodon.Attachment; local: ImageInfo }
|
payload: { remote: Mastodon.Attachment; local: ImageInfo }
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: 'attachment/upload/fail'
|
||||||
|
payload: ExtendedAttachment['local']['hash']
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: 'attachment/delete'
|
type: 'attachment/delete'
|
||||||
payload: NonNullable<ExtendedAttachment['remote']>['id']
|
payload: NonNullable<ExtendedAttachment['remote']>['id']
|
||||||
|
@ -9,7 +9,7 @@ export const StyleConstants = {
|
|||||||
FontStyle: {
|
FontStyle: {
|
||||||
S: { fontSize: 14, lineHeight: 18 },
|
S: { fontSize: 14, lineHeight: 18 },
|
||||||
M: { fontSize: 16, lineHeight: 22 },
|
M: { fontSize: 16, lineHeight: 22 },
|
||||||
L: { fontSize: 20, lineHeight: 30 }
|
L: { fontSize: 20, lineHeight: 26 }
|
||||||
},
|
},
|
||||||
|
|
||||||
Spacing: {
|
Spacing: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user