mirror of
https://github.com/block/buzz.git
synced 2026-11-01 23:11:58 +00:00
Extract message send recovery helper
Signed-off-by: kenny lopez <klopez4212@gmail.com>
This commit is contained in:
@@ -3,9 +3,15 @@ import {
|
||||
type ImetaMedia,
|
||||
mergeOutgoingTags,
|
||||
} from "@/features/messages/lib/imetaMediaMarkdown";
|
||||
import type { QueuedMediaAttachment } from "@/features/messages/lib/backgroundMediaUploadStore";
|
||||
import {
|
||||
type QueuedMediaAttachment,
|
||||
saveQueuedAttachmentsForDraft,
|
||||
} from "@/features/messages/lib/backgroundMediaUploadStore";
|
||||
import type { PreparedBackgroundLinkPreviews } from "@/features/messages/lib/linkPreviewPreparationStore";
|
||||
import type { DraftMentionRef } from "@/features/messages/lib/useDrafts";
|
||||
import type {
|
||||
DraftMentionRef,
|
||||
UseDraftsResult,
|
||||
} from "@/features/messages/lib/useDrafts";
|
||||
import { normalizePubkey } from "@/shared/lib/pubkey";
|
||||
import { MENTION_REFERENCE_TAG } from "@/shared/lib/resolveMentionNames";
|
||||
|
||||
@@ -96,3 +102,98 @@ export function isManagedAgentRunning(agent: ManagedAgent) {
|
||||
export function isProviderBackedAgent(agent: ManagedAgent) {
|
||||
return agent.backend.type === "provider";
|
||||
}
|
||||
|
||||
type RestoreComposerAfterFailureOptions = {
|
||||
content?: string;
|
||||
withoutMedia?: boolean;
|
||||
};
|
||||
|
||||
export function createMentionSendFailureRecovery({
|
||||
contentRef,
|
||||
draft,
|
||||
drafts,
|
||||
getCurrentChannelId,
|
||||
hasUnsavedMedia,
|
||||
isMounted,
|
||||
isSendCancelled,
|
||||
restoreDraftMentionRefs,
|
||||
restoreQueuedAttachments,
|
||||
setContent,
|
||||
setPendingImeta,
|
||||
setRichTextContent,
|
||||
setSpoileredAttachmentUrls,
|
||||
}: {
|
||||
contentRef: { current: string };
|
||||
draft: PendingNonMemberMentionSend;
|
||||
drafts: Pick<UseDraftsResult, "loadDraft" | "persistDraft">;
|
||||
getCurrentChannelId: () => string | null;
|
||||
hasUnsavedMedia: () => boolean;
|
||||
isMounted: () => boolean;
|
||||
isSendCancelled: () => boolean;
|
||||
restoreDraftMentionRefs: (refs: DraftMentionRef[]) => void;
|
||||
restoreQueuedAttachments: (attachments: QueuedMediaAttachment[]) => void;
|
||||
setContent: (content: string) => void;
|
||||
setPendingImeta: (pendingImeta: ImetaMedia[]) => void;
|
||||
setRichTextContent: (content: string) => void;
|
||||
setSpoileredAttachmentUrls?: (urls: Set<string>) => void;
|
||||
}) {
|
||||
const persistCanceledDraft = ({
|
||||
content = draft.savedContent,
|
||||
withoutMedia = false,
|
||||
}: RestoreComposerAfterFailureOptions = {}) => {
|
||||
if (isSendCancelled() || !draft.recoveryDraftKey) return;
|
||||
const existing = drafts.loadDraft(draft.recoveryDraftKey);
|
||||
if (
|
||||
existing &&
|
||||
(existing.content !== draft.savedContent ||
|
||||
existing.channelId !==
|
||||
(draft.capturedChannelId ?? draft.recoveryDraftKey) ||
|
||||
JSON.stringify(existing.pendingImeta) !==
|
||||
JSON.stringify(draft.savedImeta) ||
|
||||
JSON.stringify(existing.spoileredAttachmentUrls) !==
|
||||
JSON.stringify([...draft.savedSpoileredAttachmentUrls]))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
drafts.persistDraft(
|
||||
draft.recoveryDraftKey,
|
||||
content,
|
||||
draft.capturedChannelId ?? draft.recoveryDraftKey,
|
||||
withoutMedia ? [] : draft.savedImeta,
|
||||
withoutMedia ? [] : [...draft.savedSpoileredAttachmentUrls],
|
||||
draft.savedMentionRefs,
|
||||
);
|
||||
};
|
||||
|
||||
return ({
|
||||
content = draft.savedContent,
|
||||
withoutMedia = false,
|
||||
}: RestoreComposerAfterFailureOptions = {}) => {
|
||||
if (isSendCancelled()) return;
|
||||
persistCanceledDraft({ content, withoutMedia });
|
||||
const currentChannelId = getCurrentChannelId();
|
||||
const canRestoreCurrentComposer =
|
||||
isMounted() &&
|
||||
(draft.capturedChannelId === currentChannelId ||
|
||||
currentChannelId === null) &&
|
||||
contentRef.current.trim().length === 0 &&
|
||||
!hasUnsavedMedia();
|
||||
if (!canRestoreCurrentComposer && draft.recoveryDraftKey) {
|
||||
saveQueuedAttachmentsForDraft(
|
||||
draft.recoveryDraftKey,
|
||||
withoutMedia ? [] : draft.queuedAttachments,
|
||||
);
|
||||
}
|
||||
if (!canRestoreCurrentComposer) return;
|
||||
|
||||
setContent(content);
|
||||
contentRef.current = content;
|
||||
setRichTextContent(content);
|
||||
setPendingImeta(withoutMedia ? [] : draft.savedImeta);
|
||||
restoreQueuedAttachments(withoutMedia ? [] : draft.queuedAttachments);
|
||||
restoreDraftMentionRefs(draft.savedMentionRefs);
|
||||
setSpoileredAttachmentUrls?.(
|
||||
new Set(withoutMedia ? [] : draft.savedSpoileredAttachmentUrls),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import type { AcpRuntime, ChannelType, ManagedAgent } from "@/shared/api/types";
|
||||
import { normalizePubkey, truncatePubkey } from "@/shared/lib/pubkey";
|
||||
import { buildCustomEmojiTags } from "@/shared/lib/customEmojiTags";
|
||||
import {
|
||||
createMentionSendFailureRecovery,
|
||||
getErrorMessage,
|
||||
isManagedAgentRunning,
|
||||
isProviderBackedAgent,
|
||||
@@ -495,70 +496,21 @@ export function useMentionSendFlow({
|
||||
let mediaMessageSent = false;
|
||||
let linkMessageSent = false;
|
||||
let remainingTextContent = draft.savedContent;
|
||||
const persistCanceledDraft = ({
|
||||
content = draft.savedContent,
|
||||
withoutMedia = false,
|
||||
}: {
|
||||
content?: string;
|
||||
withoutMedia?: boolean;
|
||||
} = {}) => {
|
||||
if (isSendCancelled() || !draft.recoveryDraftKey) return;
|
||||
const existing = drafts.loadDraft(draft.recoveryDraftKey);
|
||||
if (
|
||||
existing &&
|
||||
(existing.content !== draft.savedContent ||
|
||||
existing.channelId !==
|
||||
(draft.capturedChannelId ?? draft.recoveryDraftKey) ||
|
||||
JSON.stringify(existing.pendingImeta) !==
|
||||
JSON.stringify(draft.savedImeta) ||
|
||||
JSON.stringify(existing.spoileredAttachmentUrls) !==
|
||||
JSON.stringify([...draft.savedSpoileredAttachmentUrls]))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
drafts.persistDraft(
|
||||
draft.recoveryDraftKey,
|
||||
content,
|
||||
draft.capturedChannelId ?? draft.recoveryDraftKey,
|
||||
withoutMedia ? [] : draft.savedImeta,
|
||||
withoutMedia ? [] : [...draft.savedSpoileredAttachmentUrls],
|
||||
draft.savedMentionRefs,
|
||||
);
|
||||
};
|
||||
const restoreComposerAfterFailure = ({
|
||||
content = draft.savedContent,
|
||||
withoutMedia = false,
|
||||
}: {
|
||||
content?: string;
|
||||
withoutMedia?: boolean;
|
||||
} = {}) => {
|
||||
if (isSendCancelled()) return;
|
||||
persistCanceledDraft({ content, withoutMedia });
|
||||
const canRestoreCurrentComposer =
|
||||
isMountedRef.current &&
|
||||
(draft.capturedChannelId === channelIdRef.current ||
|
||||
channelIdRef.current === null) &&
|
||||
contentRef.current.trim().length === 0 &&
|
||||
!hasUnsavedMedia();
|
||||
if (!canRestoreCurrentComposer && draft.recoveryDraftKey) {
|
||||
saveQueuedAttachmentsForDraft(
|
||||
draft.recoveryDraftKey,
|
||||
withoutMedia ? [] : draft.queuedAttachments,
|
||||
);
|
||||
}
|
||||
if (!canRestoreCurrentComposer) {
|
||||
return;
|
||||
}
|
||||
setContent(content);
|
||||
contentRef.current = content;
|
||||
richText.setContent(content);
|
||||
setPendingImeta(withoutMedia ? [] : draft.savedImeta);
|
||||
restoreQueuedAttachments(withoutMedia ? [] : draft.queuedAttachments);
|
||||
mentions.restoreDraftMentionRefs(draft.savedMentionRefs);
|
||||
setSpoileredAttachmentUrls?.(
|
||||
new Set(withoutMedia ? [] : draft.savedSpoileredAttachmentUrls),
|
||||
);
|
||||
};
|
||||
const restoreComposerAfterFailure = createMentionSendFailureRecovery({
|
||||
contentRef,
|
||||
draft,
|
||||
drafts,
|
||||
getCurrentChannelId: () => channelIdRef.current,
|
||||
hasUnsavedMedia,
|
||||
isMounted: () => isMountedRef.current,
|
||||
isSendCancelled,
|
||||
restoreDraftMentionRefs: mentions.restoreDraftMentionRefs,
|
||||
restoreQueuedAttachments,
|
||||
setContent,
|
||||
setPendingImeta,
|
||||
setRichTextContent: richText.setContent,
|
||||
setSpoileredAttachmentUrls,
|
||||
});
|
||||
const finishSend = async (
|
||||
uploaded: ImetaMedia[],
|
||||
signal?: AbortSignal,
|
||||
|
||||
Reference in New Issue
Block a user