Skip to content

Commit

Permalink
Add view transition to image embed
Browse files Browse the repository at this point in the history
  • Loading branch information
SupertigerDev committed Jan 24, 2025
1 parent 41bdffc commit 2cfb298
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 17 deletions.
7 changes: 7 additions & 0 deletions src/common/transitionViewIfSupported.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const transitionViewIfSupported = (updateCb: () => void) => {
if (document.startViewTransition) {
document.startViewTransition(updateCb);
} else {
updateCb();
}
};
50 changes: 35 additions & 15 deletions src/components/ui/ImageEmbed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { RawAttachment } from "@/chat-api/RawData";
import { createSignal, onCleanup, onMount } from "solid-js";
import env from "@/common/env";
import { ImagePreviewModal } from "./ImagePreviewModal";
import { transitionViewIfSupported } from "@/common/transitionViewIfSupported";

const ImageEmbedContainer = styled(FlexRow)`
user-select: none;
Expand Down Expand Up @@ -44,6 +45,7 @@ interface ImageEmbedProps {
export function ImageEmbed(props: ImageEmbedProps) {
const { paneWidth, height, hasFocus } = useWindowProperties();
const { createPortal } = useCustomPortal();
const [previewModalOpened, setPreviewModalOpened] = createSignal(false);

const isGif = () => props.attachment.path?.endsWith(".gif");
const url = (ignoreFocus?: boolean) => {
Expand All @@ -68,25 +70,43 @@ export function ImageEmbed(props: ImageEmbedProps) {
const maxHeight = props.maxHeight
? clamp((props.customHeight || height()) / 2, props.maxHeight)
: (props.customHeight || height()) / 2;
return clampImageSize(
props.attachment.width!,
props.attachment.height!,
maxWidth,
maxHeight
);

return {
...clampImageSize(
props.attachment.width!,
props.attachment.height!,
maxWidth,
maxHeight
),
...(previewModalOpened()
? { "view-transition-name": "embed-image" }
: {}),
};
};

const onClicked = () => {
if (props.ignoreClick) return;
createPortal((close) => (
<ImagePreviewModal
close={close}
url={url(true)}
origUrl={props.attachment.origSrc}
width={props.attachment.width}
height={props.attachment.height}
/>
));
setPreviewModalOpened(true);
transitionViewIfSupported(() => {
setPreviewModalOpened(false);
createPortal((close) => (
<ImagePreviewModal
close={() => {
transitionViewIfSupported(() => {
close();
setPreviewModalOpened(true);
setTimeout(() => {
setPreviewModalOpened(false);
}, 100);
});
}}
url={url(true)}
origUrl={props.attachment.origSrc}
width={props.attachment.width}
height={props.attachment.height}
/>
));
});
};

return (
Expand Down
5 changes: 3 additions & 2 deletions src/components/ui/ImagePreviewModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const ImagePreviewContainer = styled(FlexRow)`
img {
max-width: 100%;
max-height: 100%;
view-transition-name: embed-image;
}
`;
const ImagePreview = styled(FlexRow)`
Expand Down Expand Up @@ -66,8 +67,8 @@ export function ImagePreviewModal(props: {
}) {
let imageRef: HTMLImageElement | undefined;
let zoomistContainerRef: HTMLImageElement | undefined;
let location = useLocation();
let navigate = useNavigate();
const location = useLocation();
const navigate = useNavigate();
const { createPortal } = useCustomPortal();

createEffect(
Expand Down

0 comments on commit 2cfb298

Please sign in to comment.