diff --git a/packages/chat/src/components/message.tsx b/packages/chat/src/components/message.tsx index 3ea2f1e..2490a00 100644 --- a/packages/chat/src/components/message.tsx +++ b/packages/chat/src/components/message.tsx @@ -27,9 +27,6 @@ import MessageContextMenu from "./messageContextMenu"; import Media from "./media"; import { useStorage } from "@tensamin/storage/context"; import { useMTP } from "@tensamin/mtp"; -import { useChat } from "../context"; -import { decryptChatText } from "@tensamin/crypto/chatSecret"; -import { log, toast } from "@tensamin/shared/log"; function MessageComponent({ grouped, @@ -39,12 +36,13 @@ function MessageComponent({ grouped: boolean; message: RawMessage & { failed?: boolean; + decryptionFailed?: boolean; }; user: User | null; }) { - const [decryptionFailed, setDecryptionFailed] = useState(false); const actuallyFailed = - (message.failed && message.MessageState === "awaiting") || decryptionFailed; + (message.failed && message.MessageState === "awaiting") || + message.decryptionFailed; // Fade-in const [hasFadedIn, setHasFadedIn] = useState(false); @@ -115,38 +113,18 @@ function MessageComponent({ }; }, [message.MessageState, load, messageStateReadUpdate]); - // Message decryption - const { chatSecret } = useChat(); - const [decryptedContent, setDecryptedContent] = useState( - undefined, - ); - useEffect(() => { - if (!chatSecret) return; - - decryptChatText(chatSecret, message.Content).then( - setDecryptedContent, - (err) => { - toast("error", "Failed to decrypt message", String(err)); - log(1, "chat", "red", err); - setDecryptionFailed(true); - }, - ); - }, [chatSecret, message.Content]); - // Check if message is a url const [isValidURL, setIsValidURL] = useState(false); useEffect(() => { - if (!decryptedContent) return; - try { - if (decryptedContent.split(" ").length > 1) throw new Error(); + if (message.Content.split(" ").length > 1) throw new Error(); - new URL(decryptedContent); + new URL(message.Content); setIsValidURL(true); } catch { setIsValidURL(false); } - }, [decryptedContent]); + }, [message.Content]); return (
)} - {decryptedContent ? ( + {message.Content ? ( {isValidURL ? ( - + ) : ( - + )} - ) : decryptionFailed ? ( - ) : ( { prev.message.SentBySelf === next.message.SentBySelf && prev.message.MessageState === next.message.MessageState && prev.message.failed === next.message.failed && + prev.message.decryptionFailed === next.message.decryptionFailed && prev.grouped === next.grouped && prev.user === next.user ); diff --git a/packages/chat/src/context.tsx b/packages/chat/src/context.tsx index 789d023..27dfd61 100644 --- a/packages/chat/src/context.tsx +++ b/packages/chat/src/context.tsx @@ -246,10 +246,20 @@ export default function Provider({ children }: { children: ReactNode }) { try { return { ...message, - Content: await decryptChatText(currentChatSecret, message.Content), + Content: await decryptChatText( + currentChatSecret, + message.Content, + ), + }; + } catch (err) { + log(1, "chat", "red", "Failed to decrypt historical message", err, { + SendTime: message.SendTime, + }); + return { + ...message, + Content: "Failed to decrypt message", + decryptionFailed: true, }; - } catch { - return message; } }), ); @@ -352,12 +362,18 @@ export default function Provider({ children }: { children: ReactNode }) { if (!data.Message || !currentChatSecret) return; void decryptChatText(currentChatSecret, data.Message.Content) - .catch(() => data.Message?.Content ?? "") + .catch((err) => { + log(1, "chat", "red", "Failed to decrypt live message", err, { + SendTime: data.Message?.SendTime, + }); + return null; + }) .then((content) => { if (!data.Message) return; addLiveMessage({ ...data.Message, - Content: content, + Content: content ?? "Failed to decrypt message", + decryptionFailed: content === null, SentBySelf: false, }); }); @@ -455,7 +471,14 @@ export default function Provider({ children }: { children: ReactNode }) { }, ); }); - }, [addLiveMessage, currentChatSecret, load, send, subscribePush, userIdValue]); + }, [ + addLiveMessage, + currentChatSecret, + load, + send, + subscribePush, + userIdValue, + ]); return ( diff --git a/packages/chat/src/values.ts b/packages/chat/src/values.ts index 0d7af81..c269cc4 100644 --- a/packages/chat/src/values.ts +++ b/packages/chat/src/values.ts @@ -3,7 +3,9 @@ import { mtp } from "@tensamin/shared/data"; export type RawMessages = z.infer["Messages"]; -export type RawMessage = RawMessages[number]; +export type RawMessage = RawMessages[number] & { + decryptionFailed?: boolean; +}; export type LiveMessage = RawMessage & { failed?: boolean;