v3: performance pass, bundle size pass, i18n pass, docker pass

This commit is contained in:
khannurien
2026-04-08 13:19:39 +00:00
parent 20b9bfe7b4
commit 1321e374bf
21 changed files with 502 additions and 301 deletions

View File

@@ -1,13 +1,16 @@
import { type ReactNode, useState } from "react";
import { lazy, type ReactNode, Suspense, useState } from "react";
import { Link, useNavigate } from "react-router";
import { t } from "@lingui/core/macro";
import { Trans } from "@lingui/react/macro";
import { useAuth } from "../hooks/useAuth.ts";
import { useWS } from "../hooks/useWS.ts";
import { DumpCreateModal } from "./DumpCreateModal.tsx";
import { NotificationBell } from "./NotificationBell.tsx";
import { UserMenu } from "./UserMenu.tsx";
const DumpCreateModal = lazy(() =>
import("./DumpCreateModal.tsx").then((m) => ({ default: m.DumpCreateModal }))
);
export function AppHeader(
{ centerSlot, disableNew, initialDumpUrl }: {
centerSlot?: ReactNode;
@@ -88,10 +91,12 @@ export function AppHeader(
)}
{createModalOpen && (
<DumpCreateModal
onClose={() => setCreateModalOpen(false)}
initialUrl={initialDumpUrl}
/>
<Suspense>
<DumpCreateModal
onClose={() => setCreateModalOpen(false)}
initialUrl={initialDumpUrl}
/>
</Suspense>
)}
</>
);

View File

@@ -118,6 +118,21 @@ function AudioFilePreview(
);
}
function VideoThumb({ src, fallback }: { src: string; fallback: string }) {
const [failed, setFailed] = useState(false);
if (failed) {
return <span className="rich-content-compact-icon">{fallback}</span>;
}
return (
<img
src={src}
alt=""
className="rich-content-compact-thumbnail"
onError={() => setFailed(true)}
/>
);
}
function mimeIcon(mime: string): string {
if (mime.startsWith("video/")) return "🎬";
if (mime.startsWith("audio/")) return "🎵";
@@ -148,6 +163,7 @@ export default function FilePreview(
);
}
if (mime.startsWith("video/")) {
const thumbUrl = `${API_URL}/api/thumbnails/${dump.id}`;
return (
<button
type="button"
@@ -160,15 +176,7 @@ export default function FilePreview(
play({ kind: "file", fileUrl, mimeType: mime, title: dump.title });
}}
>
<video
src={fileUrl}
preload="metadata"
className="rich-content-compact-thumbnail"
muted
onLoadedMetadata={(e) => {
(e.target as HTMLVideoElement).currentTime = 0.1;
}}
/>
<VideoThumb src={thumbUrl} fallback={mimeIcon(mime)} />
<span className="rich-content-play-overlay"></span>
</button>
);
@@ -217,12 +225,9 @@ export default function FilePreview(
>
<video
src={fileUrl}
preload="metadata"
preload="none"
className="file-preview-video-thumb"
muted
onLoadedMetadata={(e) => {
(e.target as HTMLVideoElement).currentTime = 0.1;
}}
/>
<span className="rich-content-play-overlay">
{videoPlaying ? "⏸" : "▶"}