feat(media): timeline images open the gallery lightbox at that event (#219)
CI / Build & Quality Checks (push) Canceled after 0s
CI / Trigger Desktop Build (push) Canceled after 0s
CI / Secret scan (gitleaks) (push) Canceled after 0s
CI / Docker image build & smoke test (push) Canceled after 0s
CI / Playwright smoke (e2e) (push) Canceled after 0s
CI / Build & Quality Checks (push) Canceled after 0s
CI / Trigger Desktop Build (push) Canceled after 0s
CI / Secret scan (gitleaks) (push) Canceled after 0s
CI / Docker image build & smoke test (push) Canceled after 0s
CI / Playwright smoke (e2e) (push) Canceled after 0s
Clicking an image in the room or thread timeline now opens the same viewer the media gallery uses — dark backdrop, sender + date, 1/N counter, ←/→ across the room's media, +/-/0 and wheel/double-click zoom, download, jump to message — positioned at the clicked event. RoomMediaLightbox feeds it from the detached media timeline (#163); when the event isn't in the loaded window it pages back (bounded, 6 pages) and shows the clicked image alone meanwhile, so the viewer opens instantly. ImageContent gains onOpenViewer (RenderMessageContent passes onOpenImageViewer); its built-in viewer remains for stickers, search results, pins, notifications and avatars. Verified headless: click → 'Media viewer' dialog focused, counter 1/2, '+' → 120 %, Jump to message present, Esc closes; an older image 10 pages up → found at 10/45 after paging. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -70,6 +70,8 @@ type RenderMessageContentProps = {
|
||||
linkifyOpts: Opts;
|
||||
outlineAttachment?: boolean;
|
||||
eventId?: string;
|
||||
/** [Gitea #219] Open the room's shared media lightbox at this event. */
|
||||
onOpenImageViewer?: () => void;
|
||||
};
|
||||
export function RenderMessageContent({
|
||||
displayName,
|
||||
@@ -85,6 +87,7 @@ export function RenderMessageContent({
|
||||
linkifyOpts,
|
||||
outlineAttachment,
|
||||
eventId,
|
||||
onOpenImageViewer,
|
||||
}: RenderMessageContentProps) {
|
||||
const renderUrlsPreview = (urls: string[]) => {
|
||||
// Cap previews per message so a link-dump doesn't spawn dozens of preview
|
||||
@@ -241,6 +244,7 @@ export function RenderMessageContent({
|
||||
autoPlay={mediaAutoLoad}
|
||||
renderImage={(p) => <Image {...p} loading="lazy" />}
|
||||
renderViewer={(p) => <ImageViewer {...p} />}
|
||||
onOpenViewer={onOpenImageViewer}
|
||||
/>
|
||||
)}
|
||||
outlined={outlineAttachment}
|
||||
|
||||
@@ -59,6 +59,9 @@ export type ImageContentProps = {
|
||||
spoilerReason?: string;
|
||||
renderViewer: (props: RenderViewerProps) => ReactNode;
|
||||
renderImage: (props: RenderImageProps) => ReactNode;
|
||||
// [Gitea #219] When given, a click opens THIS instead of the built-in
|
||||
// viewer — the room timeline hands it to the shared media lightbox.
|
||||
onOpenViewer?: () => void;
|
||||
};
|
||||
export const ImageContent = as<'div', ImageContentProps>(
|
||||
(
|
||||
@@ -74,6 +77,7 @@ export const ImageContent = as<'div', ImageContentProps>(
|
||||
spoilerReason,
|
||||
renderViewer,
|
||||
renderImage,
|
||||
onOpenViewer,
|
||||
...props
|
||||
},
|
||||
ref,
|
||||
@@ -182,7 +186,7 @@ export const ImageContent = as<'div', ImageContentProps>(
|
||||
src: srcState.data,
|
||||
onLoad: handleLoad,
|
||||
onError: handleError,
|
||||
onClick: () => setViewer(true),
|
||||
onClick: () => (onOpenViewer ? onOpenViewer() : setViewer(true)),
|
||||
tabIndex: 0,
|
||||
})}
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user