fix: GIF CSP + edit history HTML rendering + unhandled rejection cleanup

- nginx (LXC 106, live): added https://*.giphy.com to connect-src CSP —
  browser was blocking fetch() to media2.giphy.com CDN with CSP violation
- EditHistoryModal: render formatted_body as sanitized HTML (via
  html-react-parser + sanitizeCustomHtml) with linkification for plain
  text, matching how messages render in the timeline
- useAsyncCallback + ThumbnailContent + ImageContent + VideoContent +
  ClientConfigLoader: use .catch(() => undefined) instead of void to
  silence unhandled promise rejections from fire-and-forget useEffect
  calls — errors already captured in AsyncState.Error for UI display

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 10:34:46 -04:00
parent 7bafefa5e7
commit 7b01cfebf5
6 changed files with 25 additions and 18 deletions
@@ -113,7 +113,7 @@ export const ImageContent = as<'div', ImageContentProps>(
};
useEffect(() => {
if (autoPlay) void loadSrc().catch(() => undefined);
if (autoPlay) loadSrc().catch(() => undefined);
}, [autoPlay, loadSrc]);
return (
@@ -37,7 +37,7 @@ export function ThumbnailContent({ info, renderImage }: ThumbnailContentProps) {
);
useEffect(() => {
void loadThumbSrc().catch(() => undefined);
loadThumbSrc().catch(() => undefined);
}, [loadThumbSrc]);
return thumbSrcState.status === AsyncStatus.Success ? renderImage(thumbSrcState.data) : null;
@@ -106,7 +106,7 @@ export const VideoContent = as<'div', VideoContentProps>(
};
useEffect(() => {
if (autoPlay) void loadSrc().catch(() => undefined);
if (autoPlay) loadSrc().catch(() => undefined);
}, [autoPlay, loadSrc]);
return (