diff --git a/resources/js/layouts/app-layout.tsx b/resources/js/layouts/app-layout.tsx
index 6dbd86b3a..13e4a37a7 100644
--- a/resources/js/layouts/app-layout.tsx
+++ b/resources/js/layouts/app-layout.tsx
@@ -1,5 +1,5 @@
import { Head, usePage, usePoll } from '@inertiajs/react';
-import { useCallback, useEffect, useState } from 'react';
+import { lazy, Suspense, useCallback, useEffect, useState } from 'react';
import { AppAside } from '@/components/app-aside';
import {
AppNav,
@@ -12,7 +12,6 @@ import {
CommitComposerDialog,
focusVisibleComposer,
} from '@/components/commit-composer-dialog';
-import { CommitImageViewer } from '@/components/commit-image-viewer';
import { CommitStarPolling } from '@/components/commit-star-polling';
import { DeletedPageDialog } from '@/components/deleted-page-dialog';
import { endStream, GoLiveDialog } from '@/components/go-live-dialog';
@@ -33,14 +32,21 @@ import { signIn } from '@/lib/auth';
import { backgroundPollOptions } from '@/lib/background-poll';
import type { IssueKind } from '@/lib/issue-commands';
import type { SearchAction } from '@/lib/search-actions';
+import type { CommitPhoto } from '@/lib/commit-photo';
import { cn } from '@/lib/utils';
import type { AppLayoutProps } from '@/types';
+// The lightbox is only needed once a photo opens, so it loads then instead of on every page.
+const CommitImageViewer = lazy(async () => ({
+ default: (await import('@/components/commit-image-viewer'))
+ .CommitImageViewer,
+}));
+
export default function AppLayout({ children }: AppLayoutProps) {
const {
component,
- props: { auth },
- } = usePage();
+ props: { auth, photo },
+ } = usePage<{ photo?: CommitPhoto }>();
const { isLayoutOpen } = useNavOpen();
const [isShowingShortcuts, setIsShowingShortcuts] = useState(false);
const [isSearching, setIsSearching] = useState(false);
@@ -49,6 +55,12 @@ export default function AppLayout({ children }: AppLayoutProps) {
null,
);
const [isGoingLive, setIsGoingLive] = useState(false);
+ // Stays mounted after the photo closes, so the lightbox can animate out.
+ const [hasShownPhoto, setHasShownPhoto] = useState(false);
+
+ if (photo !== undefined && !hasShownPhoto) {
+ setHasShownPhoto(true);
+ }
const showShortcuts = useCallback(() => setIsShowingShortcuts(true), []);
const openSearch = useCallback(() => setIsSearching(true), []);
const isGuest = auth.user === null;
@@ -153,7 +165,11 @@ export default function AppLayout({ children }: AppLayoutProps) {
{deletedPage === null ? (
-
+ hasShownPhoto && (
+
+
+
+ )
) : (
)}