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'
incomingStatus: Mastodon.Status
replyToStatus?: Mastodon.Status
queryKey?: [
'Timeline',
{

View File

@ -19,8 +19,17 @@ export default {
edit: 'Toot'
},
alert: {
title: 'Tooting failed',
button: 'Try again'
default: {
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: '发嘟嘟'
},
alert: {
title: '发布失败',
button: '返回重试'
default: {
title: '发布失败',
button: '返回重试'
},
removeReply: {
title: '回复的嘟文不存在',
description: '回复的嘟文可能已被删除。确认移除回复嘟文的关联?',
cancel: '$t(common:buttons.cancel)',
confirm: '移除关联'
}
}
}
},

View File

@ -10,9 +10,9 @@ import {
} from '@utils/queryHooks/timeline'
import analytics from '@components/analytics'
import { StackNavigationProp } from '@react-navigation/stack'
import deleteItem from '@utils/queryHooks/timeline/deleteItem'
import { displayMessage } from '@components/Message'
import { useTheme } from '@utils/styles/ThemeManager'
import apiInstance from '@api/instance'
export interface Props {
navigation: StackNavigationProp<Nav.RootStackParamList, 'Screen-Actions'>
@ -106,26 +106,30 @@ const ActionsStatus: React.FC<Props> = ({
page: queryKey && queryKey[1].page
}
)
dismiss()
const res = await mutation.mutateAsync({
type: 'deleteItem',
source: 'statuses',
queryKey,
id: status.id
})
deleteItem({
queryClient,
rootQueryKey,
id: status.id
})
if (res.body.id) {
// @ts-ignore
navigation.navigate('Screen-Compose', {
type: 'edit',
incomingStatus: res.body,
queryKey
})
let replyToStatus: Mastodon.Status
if (status.in_reply_to_id) {
replyToStatus = await apiInstance<Mastodon.Status>({
method: 'get',
url: `statuses/${status.in_reply_to_id}`
}).then(res => res.body)
}
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()
})
.catch(error => {
Sentry.Native.captureException(error)
haptics('Error')
composeDispatch({ type: 'posting', payload: false })
Alert.alert(t('heading.right.alert.title'), undefined, [
{
text: t('heading.right.alert.button')
}
])
if (error.removeReply) {
Alert.alert(
t('heading.right.alert.removeReply.title'),
t('heading.right.alert.removeReply.description'),
[
{
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}

View File

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

View File

@ -9,7 +9,17 @@ const composePost = async (
const formData = new FormData()
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) {

View File

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

View File

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