This commit is contained in:
Zhiyuan Zheng 2021-03-09 00:47:40 +01:00
parent e5effd6b65
commit 6b048e4b2a
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
9 changed files with 96 additions and 34 deletions

View File

@ -17,6 +17,7 @@ declare namespace Nav {
| { | {
type: 'edit' type: 'edit'
incomingStatus: Mastodon.Status incomingStatus: Mastodon.Status
replyToStatus?: Mastodon.Status
queryKey?: [ queryKey?: [
'Timeline', 'Timeline',
{ {

View File

@ -19,8 +19,17 @@ export default {
edit: 'Toot' edit: 'Toot'
}, },
alert: { alert: {
title: 'Tooting failed', default: {
button: 'Try again' title: 'Tooting failed',
button: 'Try again'
},
removeReply: {
title: 'Replied toot could not be found',
description:
'Replied toot could have been deleted. Do you want to remove it from your reference?',
cancel: '$t(common:buttons.cancel)',
confirm: 'Remove reference'
}
} }
} }
}, },

View File

@ -19,8 +19,16 @@ export default {
edit: '发嘟嘟' edit: '发嘟嘟'
}, },
alert: { alert: {
title: '发布失败', default: {
button: '返回重试' title: '发布失败',
button: '返回重试'
},
removeReply: {
title: '回复的嘟文不存在',
description: '回复的嘟文可能已被删除。确认移除回复嘟文的关联?',
cancel: '$t(common:buttons.cancel)',
confirm: '移除关联'
}
} }
} }
}, },

View File

@ -10,9 +10,9 @@ import {
} from '@utils/queryHooks/timeline' } from '@utils/queryHooks/timeline'
import analytics from '@components/analytics' import analytics from '@components/analytics'
import { StackNavigationProp } from '@react-navigation/stack' import { StackNavigationProp } from '@react-navigation/stack'
import deleteItem from '@utils/queryHooks/timeline/deleteItem'
import { displayMessage } from '@components/Message' import { displayMessage } from '@components/Message'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import apiInstance from '@api/instance'
export interface Props { export interface Props {
navigation: StackNavigationProp<Nav.RootStackParamList, 'Screen-Actions'> navigation: StackNavigationProp<Nav.RootStackParamList, 'Screen-Actions'>
@ -106,26 +106,30 @@ const ActionsStatus: React.FC<Props> = ({
page: queryKey && queryKey[1].page page: queryKey && queryKey[1].page
} }
) )
dismiss() let replyToStatus: Mastodon.Status
const res = await mutation.mutateAsync({ if (status.in_reply_to_id) {
type: 'deleteItem', replyToStatus = await apiInstance<Mastodon.Status>({
source: 'statuses', method: 'get',
queryKey, url: `statuses/${status.in_reply_to_id}`
id: status.id }).then(res => res.body)
})
deleteItem({
queryClient,
rootQueryKey,
id: status.id
})
if (res.body.id) {
// @ts-ignore
navigation.navigate('Screen-Compose', {
type: 'edit',
incomingStatus: res.body,
queryKey
})
} }
mutation
.mutateAsync({
type: 'deleteItem',
source: 'statuses',
queryKey,
id: status.id
})
.then(res => {
dismiss()
// @ts-ignore
navigation.navigate('Screen-Compose', {
type: 'edit',
incomingStatus: res.body,
...(replyToStatus && { replyToStatus }),
queryKey
})
})
} }
} }
] ]

View File

@ -298,14 +298,38 @@ const ScreenCompose: React.FC<ScreenComposeProp> = ({
navigation.goBack() navigation.goBack()
}) })
.catch(error => { .catch(error => {
Sentry.Native.captureException(error) if (error.removeReply) {
haptics('Error') Alert.alert(
composeDispatch({ type: 'posting', payload: false }) t('heading.right.alert.removeReply.title'),
Alert.alert(t('heading.right.alert.title'), undefined, [ t('heading.right.alert.removeReply.description'),
{ [
text: t('heading.right.alert.button') {
} text: t('heading.right.alert.removeReply.cancel'),
]) onPress: () => {
composeDispatch({ type: 'posting', payload: false })
},
style: 'destructive'
},
{
text: t('heading.right.alert.removeReply.confirm'),
onPress: () => {
composeDispatch({ type: 'removeReply' })
composeDispatch({ type: 'posting', payload: false })
},
style: 'default'
}
]
)
} else {
Sentry.Native.captureException(error)
haptics('Error')
composeDispatch({ type: 'posting', payload: false })
Alert.alert(t('heading.right.alert.default.title'), undefined, [
{
text: t('heading.right.alert.default.button')
}
])
}
}) })
}} }}
loading={composeState.posting} loading={composeState.posting}

View File

@ -45,7 +45,8 @@ const composeParseState = (
'public', 'public',
...(params.incomingStatus.visibility === 'direct' && { ...(params.incomingStatus.visibility === 'direct' && {
visibilityLock: true visibilityLock: true
}) }),
...(params.replyToStatus && { replyToStatus: params.replyToStatus })
} }
case 'reply': case 'reply':
const actualStatus = params.incomingStatus.reblog || params.incomingStatus const actualStatus = params.incomingStatus.reblog || params.incomingStatus

View File

@ -9,7 +9,17 @@ const composePost = async (
const formData = new FormData() const formData = new FormData()
if (composeState.replyToStatus) { if (composeState.replyToStatus) {
formData.append('in_reply_to_id', composeState.replyToStatus!.id) try {
await apiInstance<Mastodon.Status>({
method: 'get',
url: `statuses/${composeState.replyToStatus.id}`
})
} catch (err) {
if (err.status == 404) {
return Promise.reject({ removeReply: true })
}
}
formData.append('in_reply_to_id', composeState.replyToStatus.id)
} }
if (composeState.spoiler.active) { if (composeState.spoiler.active) {

View File

@ -103,6 +103,8 @@ const composeReducer = (
...state, ...state,
textInputFocus: { ...state.textInputFocus, ...action.payload } textInputFocus: { ...state.textInputFocus, ...action.payload }
} }
case 'removeReply':
return { ...state, replyToStatus: undefined }
default: default:
throw new Error('Unexpected action') throw new Error('Unexpected action')
} }

View File

@ -132,3 +132,6 @@ export type ComposeAction =
type: 'textInputFocus' type: 'textInputFocus'
payload: Partial<ComposeState['textInputFocus']> payload: Partial<ComposeState['textInputFocus']>
} }
| {
type: 'removeReply'
}