mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(publish): retry failed comments without duplicate replies
This commit is contained in:
@@ -356,8 +356,11 @@ vi.mock('../../lib/utils/thread-scroll-utils', () => ({
|
||||
vi.mock('../../hooks/use-delete-failed-post', () => ({
|
||||
default: () => ({
|
||||
canDeleteFailedPost: false,
|
||||
canRetryFailedPost: false,
|
||||
isDeletingFailedPost: false,
|
||||
isRetryingFailedPost: false,
|
||||
onDeleteFailedPost: vi.fn(),
|
||||
onRetryFailedPost: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
|
||||
@@ -3,11 +3,14 @@ import useIsMobile from '../hooks/use-is-mobile';
|
||||
|
||||
interface FailedPublishNoticeProps {
|
||||
isDeleting: boolean;
|
||||
isRetrying?: boolean;
|
||||
onDelete: () => void;
|
||||
onRetry?: () => void;
|
||||
}
|
||||
|
||||
const FailedPublishNotice = ({ isDeleting, onDelete }: FailedPublishNoticeProps) => {
|
||||
const FailedPublishNotice = ({ isDeleting, isRetrying = false, onDelete, onRetry }: FailedPublishNoticeProps) => {
|
||||
const isMobile = useIsMobile();
|
||||
const isBusy = isDeleting || isRetrying;
|
||||
|
||||
return (
|
||||
<span className={styles.failedPublishNotice}>
|
||||
@@ -18,9 +21,18 @@ const FailedPublishNotice = ({ isDeleting, onDelete }: FailedPublishNoticeProps)
|
||||
<br />
|
||||
</>
|
||||
)}
|
||||
{onRetry && (
|
||||
<span className={styles.failedDeletePostAction}>
|
||||
[
|
||||
<button type='button' className={styles.failedDeletePostButton} disabled={isBusy} onClick={onRetry}>
|
||||
Retry Publish
|
||||
</button>
|
||||
]
|
||||
</span>
|
||||
)}{' '}
|
||||
<span className={styles.failedDeletePostAction}>
|
||||
[
|
||||
<button type='button' className={styles.failedDeletePostButton} disabled={isDeleting} onClick={onDelete}>
|
||||
<button type='button' className={styles.failedDeletePostButton} disabled={isBusy} onClick={onDelete}>
|
||||
Delete Post
|
||||
</button>
|
||||
]
|
||||
|
||||
@@ -747,8 +747,15 @@ const Reply = ({
|
||||
|
||||
const commentMediaInfo = useCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight);
|
||||
const hasThumbnail = getHasThumbnail(commentMediaInfo, link);
|
||||
const { canDeleteFailedPost, isDeletingFailedPost, onDeleteFailedPost } = useDeleteFailedPost(post);
|
||||
const failedPublishNotice = canDeleteFailedPost ? <FailedPublishNotice isDeleting={isDeletingFailedPost} onDelete={onDeleteFailedPost} /> : undefined;
|
||||
const { canDeleteFailedPost, canRetryFailedPost, isDeletingFailedPost, isRetryingFailedPost, onDeleteFailedPost, onRetryFailedPost } = useDeleteFailedPost(post);
|
||||
const failedPublishNotice = canDeleteFailedPost ? (
|
||||
<FailedPublishNotice
|
||||
isDeleting={isDeletingFailedPost}
|
||||
isRetrying={isRetryingFailedPost}
|
||||
onDelete={onDeleteFailedPost}
|
||||
onRetry={canRetryFailedPost ? onRetryFailedPost : undefined}
|
||||
/>
|
||||
) : undefined;
|
||||
|
||||
return (
|
||||
<div className={`${styles.replyDesktop} ${disableDeferredLayout ? styles.pretextVirtualizedReply : ''}`}>
|
||||
@@ -927,8 +934,16 @@ const PostDesktop = ({
|
||||
|
||||
const stateString = useStateString(resolvedPost) || t('downloading_board');
|
||||
const hasFailedState = state === 'failed';
|
||||
const { canDeleteFailedPost, isDeletingFailedPost, onDeleteFailedPost } = useDeleteFailedPost(resolvedPost);
|
||||
const failedPublishNotice = canDeleteFailedPost ? <FailedPublishNotice isDeleting={isDeletingFailedPost} onDelete={onDeleteFailedPost} /> : undefined;
|
||||
const { canDeleteFailedPost, canRetryFailedPost, isDeletingFailedPost, isRetryingFailedPost, onDeleteFailedPost, onRetryFailedPost } =
|
||||
useDeleteFailedPost(resolvedPost);
|
||||
const failedPublishNotice = canDeleteFailedPost ? (
|
||||
<FailedPublishNotice
|
||||
isDeleting={isDeletingFailedPost}
|
||||
isRetrying={isRetryingFailedPost}
|
||||
onDelete={onDeleteFailedPost}
|
||||
onRetry={canRetryFailedPost ? onRetryFailedPost : undefined}
|
||||
/>
|
||||
) : undefined;
|
||||
|
||||
const commentMediaInfo = useCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight);
|
||||
const hasThumbnail = getHasThumbnail(commentMediaInfo, link);
|
||||
|
||||
@@ -519,8 +519,15 @@ const Reply = ({
|
||||
const route = boardPath ? `/${boardPath}/thread/${cid}` : `/thread/${cid}`;
|
||||
const isRouteLinkToReply = cid ? location.pathname.startsWith(route) : false;
|
||||
const { hidden } = useHide({ cid });
|
||||
const { canDeleteFailedPost, isDeletingFailedPost, onDeleteFailedPost } = useDeleteFailedPost(post);
|
||||
const failedPublishNotice = canDeleteFailedPost ? <FailedPublishNotice isDeleting={isDeletingFailedPost} onDelete={onDeleteFailedPost} /> : undefined;
|
||||
const { canDeleteFailedPost, canRetryFailedPost, isDeletingFailedPost, isRetryingFailedPost, onDeleteFailedPost, onRetryFailedPost } = useDeleteFailedPost(post);
|
||||
const failedPublishNotice = canDeleteFailedPost ? (
|
||||
<FailedPublishNotice
|
||||
isDeleting={isDeletingFailedPost}
|
||||
isRetrying={isRetryingFailedPost}
|
||||
onDelete={onDeleteFailedPost}
|
||||
onRetry={canRetryFailedPost ? onRetryFailedPost : undefined}
|
||||
/>
|
||||
) : undefined;
|
||||
|
||||
return (
|
||||
<div className={`${styles.replyMobile} ${disableDeferredLayout ? styles.pretextVirtualizedReply : ''}`}>
|
||||
@@ -648,8 +655,16 @@ const PostMobile = ({
|
||||
const stateString = useStateString(resolvedPost) || t('loading_post');
|
||||
const hasFailedState = state === 'failed';
|
||||
const isReply = !!parentCid;
|
||||
const { canDeleteFailedPost, isDeletingFailedPost, onDeleteFailedPost } = useDeleteFailedPost(resolvedPost);
|
||||
const failedPublishNotice = canDeleteFailedPost ? <FailedPublishNotice isDeleting={isDeletingFailedPost} onDelete={onDeleteFailedPost} /> : undefined;
|
||||
const { canDeleteFailedPost, canRetryFailedPost, isDeletingFailedPost, isRetryingFailedPost, onDeleteFailedPost, onRetryFailedPost } =
|
||||
useDeleteFailedPost(resolvedPost);
|
||||
const failedPublishNotice = canDeleteFailedPost ? (
|
||||
<FailedPublishNotice
|
||||
isDeleting={isDeletingFailedPost}
|
||||
isRetrying={isRetryingFailedPost}
|
||||
onDelete={onDeleteFailedPost}
|
||||
onRetry={canRetryFailedPost ? onRetryFailedPost : undefined}
|
||||
/>
|
||||
) : undefined;
|
||||
|
||||
// Author-deleted replies are hidden from thread replies; moderator removals still render their placeholder.
|
||||
const filteredReplies = useMemo(() => filterRepliesForDisplay(freshRepliesForRender), [freshRepliesForRender]);
|
||||
|
||||
Reference in New Issue
Block a user