Fix 404 error after deleting status from detail view (#35800) (#35881)
Some checks failed
Check i18n / check-i18n (push) Waiting to run
Chromatic / Run Chromatic (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
JavaScript Linting / lint (push) Waiting to run
JavaScript Testing / test (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.2) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Crowdin / Upload translations / upload-translations (push) Has been cancelled

This commit is contained in:
Kazuki Nagasawa 2025-08-29 05:50:19 +09:00 committed by GitHub
parent d880f397df
commit d93572ea90
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 56 additions and 8 deletions

View File

@ -1,7 +1,10 @@
import { defineMessages } from 'react-intl';
import { browserHistory } from 'mastodon/components/router'; import { browserHistory } from 'mastodon/components/router';
import api from '../api'; import api from '../api';
import { showAlert } from './alerts';
import { ensureComposeIsVisible, setComposeToStatus } from './compose'; import { ensureComposeIsVisible, setComposeToStatus } from './compose';
import { importFetchedStatus, importFetchedAccount } from './importer'; import { importFetchedStatus, importFetchedAccount } from './importer';
import { fetchContext } from './statuses_typed'; import { fetchContext } from './statuses_typed';
@ -40,6 +43,10 @@ export const STATUS_TRANSLATE_SUCCESS = 'STATUS_TRANSLATE_SUCCESS';
export const STATUS_TRANSLATE_FAIL = 'STATUS_TRANSLATE_FAIL'; export const STATUS_TRANSLATE_FAIL = 'STATUS_TRANSLATE_FAIL';
export const STATUS_TRANSLATE_UNDO = 'STATUS_TRANSLATE_UNDO'; export const STATUS_TRANSLATE_UNDO = 'STATUS_TRANSLATE_UNDO';
const messages = defineMessages({
deleteSuccess: { id: 'status.delete.success', defaultMessage: 'Post deleted' },
});
export function fetchStatusRequest(id, skipLoading) { export function fetchStatusRequest(id, skipLoading) {
return { return {
type: STATUS_FETCH_REQUEST, type: STATUS_FETCH_REQUEST,
@ -154,7 +161,7 @@ export function deleteStatus(id, withRedraft = false) {
dispatch(deleteStatusRequest(id)); dispatch(deleteStatusRequest(id));
api().delete(`/api/v1/statuses/${id}`, { params: { delete_media: !withRedraft } }).then(response => { return api().delete(`/api/v1/statuses/${id}`, { params: { delete_media: !withRedraft } }).then(response => {
dispatch(deleteStatusSuccess(id)); dispatch(deleteStatusSuccess(id));
dispatch(deleteFromTimelines(id)); dispatch(deleteFromTimelines(id));
dispatch(importFetchedAccount(response.data.account)); dispatch(importFetchedAccount(response.data.account));
@ -162,9 +169,14 @@ export function deleteStatus(id, withRedraft = false) {
if (withRedraft) { if (withRedraft) {
dispatch(redraft(status, response.data.text)); dispatch(redraft(status, response.data.text));
ensureComposeIsVisible(getState); ensureComposeIsVisible(getState);
} else {
dispatch(showAlert({ message: messages.deleteSuccess }));
} }
return response;
}).catch(error => { }).catch(error => {
dispatch(deleteStatusFail(id, error)); dispatch(deleteStatusFail(id, error));
throw error;
}); });
}; };
} }

View File

@ -117,7 +117,13 @@ const mapDispatchToProps = (dispatch, { contextType }) => ({
if (!deleteModal) { if (!deleteModal) {
dispatch(deleteStatus(status.get('id'), withRedraft)); dispatch(deleteStatus(status.get('id'), withRedraft));
} else { } else {
dispatch(openModal({ modalType: 'CONFIRM_DELETE_STATUS', modalProps: { statusId: status.get('id'), withRedraft } })); dispatch(openModal({
modalType: 'CONFIRM_DELETE_STATUS',
modalProps: {
statusId: status.get('id'),
withRedraft
}
}));
} }
}, },

View File

@ -251,12 +251,31 @@ class Status extends ImmutablePureComponent {
}; };
handleDeleteClick = (status, withRedraft = false) => { handleDeleteClick = (status, withRedraft = false) => {
const { dispatch } = this.props; const { dispatch, history } = this.props;
const handleDeleteSuccess = () => {
history.push('/');
};
if (!deleteModal) { if (!deleteModal) {
dispatch(deleteStatus(status.get('id'), withRedraft)); dispatch(deleteStatus(status.get('id'), withRedraft))
.then(() => {
if (!withRedraft) {
handleDeleteSuccess();
}
})
.catch(() => {
// Error handling - could show error message
});
} else { } else {
dispatch(openModal({ modalType: 'CONFIRM_DELETE_STATUS', modalProps: { statusId: status.get('id'), withRedraft } })); dispatch(openModal({
modalType: 'CONFIRM_DELETE_STATUS',
modalProps: {
statusId: status.get('id'),
withRedraft,
onDeleteSuccess: handleDeleteSuccess
}
}));
} }
}; };

View File

@ -40,14 +40,23 @@ export const ConfirmDeleteStatusModal: React.FC<
{ {
statusId: string; statusId: string;
withRedraft: boolean; withRedraft: boolean;
onDeleteSuccess?: () => void;
} & BaseConfirmationModalProps } & BaseConfirmationModalProps
> = ({ statusId, withRedraft, onClose }) => { > = ({ statusId, withRedraft, onClose, onDeleteSuccess }) => {
const intl = useIntl(); const intl = useIntl();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const onConfirm = useCallback(() => { const onConfirm = useCallback(() => {
dispatch(deleteStatus(statusId, withRedraft)); void dispatch(deleteStatus(statusId, withRedraft))
}, [dispatch, statusId, withRedraft]); .then(() => {
onDeleteSuccess?.();
onClose();
})
.catch(() => {
// Error handling - still close modal
onClose();
});
}, [dispatch, statusId, withRedraft, onDeleteSuccess, onClose]);
return ( return (
<ConfirmationModal <ConfirmationModal

View File

@ -870,6 +870,7 @@
"status.continued_thread": "Continued thread", "status.continued_thread": "Continued thread",
"status.copy": "Copy link to post", "status.copy": "Copy link to post",
"status.delete": "Delete", "status.delete": "Delete",
"status.delete.success": "Post deleted",
"status.detailed_status": "Detailed conversation view", "status.detailed_status": "Detailed conversation view",
"status.direct": "Privately mention @{name}", "status.direct": "Privately mention @{name}",
"status.direct_indicator": "Private mention", "status.direct_indicator": "Private mention",

View File

@ -845,6 +845,7 @@
"status.continued_thread": "続きのスレッド", "status.continued_thread": "続きのスレッド",
"status.copy": "投稿へのリンクをコピー", "status.copy": "投稿へのリンクをコピー",
"status.delete": "削除", "status.delete": "削除",
"status.delete.success": "投稿が削除されました!",
"status.detailed_status": "詳細な会話ビュー", "status.detailed_status": "詳細な会話ビュー",
"status.direct": "@{name}さんに非公開で投稿", "status.direct": "@{name}さんに非公開で投稿",
"status.direct_indicator": "非公開の返信", "status.direct_indicator": "非公開の返信",