Skip to content

Commit

Permalink
lightbox
Browse files Browse the repository at this point in the history
  • Loading branch information
mimecuvalo committed Nov 24, 2023
1 parent 3436657 commit 31c8b5e
Show file tree
Hide file tree
Showing 11 changed files with 253 additions and 68 deletions.
191 changes: 171 additions & 20 deletions components/ContentThumb.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,43 @@
import { Link, styled } from 'components';
import { Link, Dialog, styled, IconButton, useTheme } from 'components';
import { THUMB_HEIGHT, THUMB_WIDTH } from 'util/constants';
import { constructNextImageURL, contentUrl } from 'util/url-factory';
import { defineMessages, useIntl } from 'i18n';

import { Content } from 'data/graphql-generated';
import { MouseEvent, useEffect, useState } from 'react';
import { ArrowBackIosNew, ArrowForwardIos, Close } from '@mui/icons-material';
import { Backdrop } from '@mui/material';
import Header from './content/Header';
import Image from 'next/image';

const ThumbLink = styled(Link)`
max-width: ${THUMB_WIDTH}px;
min-height: ${THUMB_HEIGHT}px;
width: ${THUMB_WIDTH}px;
height: ${THUMB_HEIGHT}px;
display: flex;
align-items: center;
justify-content: center;
`;

const DialogImage = styled('img')`
max-height: 80vh;
max-width: 100%;
&:not(:last-child) {
margin-bottom: ${(props) => props.theme.spacing(1)};
}
`;

const DialogContent = styled('div')`
header {
align-self: center;
}
`;

const StyledThumb = styled('img')`
display: inline-block;
max-width: ${THUMB_WIDTH}px;
max-height: ${THUMB_HEIGHT}px;
width: ${THUMB_WIDTH}px;
height: ${THUMB_HEIGHT}px;
object-fit: cover;
`;

const messages = defineMessages({
Expand All @@ -27,24 +48,56 @@ export default function Thumb({
className,
item,
currentContent: currentContentProp,
isOpen,
onOpen,
onClose,
handlePrev,
handleNext,
}: {
className?: string;
item: Content;
currentContent?: Content;
isOpen: boolean;
onOpen: () => void;
onClose: () => void;
handlePrev: () => void;
handleNext: () => void;
}) {
const intl = useIntl();
const [isDialogOpen, setIsDialogOpen] = useState(false);
const theme = useTheme();

useEffect(() => setIsDialogOpen(isOpen), [isOpen]);

const currentContent = currentContentProp || { forceRefresh: false };
const thumbAltText = intl.formatMessage(messages.thumbnail);

const thumb = (
const thumb =
// TODO(mime): is loading lazy necessary here for next.js? i forget
<StyledThumb
loading="lazy"
src={item.thumb ? constructNextImageURL(item.thumb, 640 /* size */) : '/img/pixel.gif'}
alt={thumbAltText}
/>
);
item.thumb.startsWith('/resource') ? (
<Image
loading="lazy"
src={
item.thumb
? item.thumb.startsWith('/resource')
? `https://${process.env.NEXT_PUBLIC_S3_AWS_S3_BUCKET_NAME}${item.thumb.replace('/resource', '')}`
: item.thumb
: '/img/pixel.gif'
}
width={THUMB_WIDTH}
height={THUMB_HEIGHT}
alt={thumbAltText}
style={{
objectFit: 'cover',
}}
/>
) : (
<StyledThumb
loading="lazy"
src={item.thumb ? constructNextImageURL(item.thumb, 640 /* size */) : '/img/pixel.gif'}
alt={thumbAltText}
/>
);

// We're using the fancy new "loading" attribute for images to lazy load thumbs. Woo!
// return !isEditing && item.externalLink ? (
Expand All @@ -62,14 +115,112 @@ export default function Thumb({
// </ThumbLink>
// );

const handleClick = (evt: MouseEvent) => {
evt.preventDefault();

setIsDialogOpen(true);
onOpen();
};
const handleClose = () => {
setIsDialogOpen(false);
onClose();
};

const isPhotosSectionAndHasPhotos = item.section === 'photos' && !!item.prefetchImages?.length;

return (
<ThumbLink
href={contentUrl(item)}
className={className}
title={item.title}
target={item.forceRefresh || currentContent.forceRefresh ? '_self' : ''}
>
{thumb}
</ThumbLink>
<>
<ThumbLink
href={contentUrl(item)}
className={className}
title={item.title}
target={item.forceRefresh || currentContent.forceRefresh ? '_self' : ''}
onClick={isPhotosSectionAndHasPhotos ? handleClick : undefined}
>
{thumb}
</ThumbLink>

{isPhotosSectionAndHasPhotos && (
<Dialog
open={isDialogOpen}
onClose={handleClose}
maxWidth="lg"
slots={{ backdrop: Backdrop }}
slotProps={{
backdrop: {
sx: {
backdropFilter: 'blur(3px)',
backgroundColor: 'rgba(0,0,30,0.4)',
},
},
}}
PaperProps={{
sx: {
background: 'transparent',
boxShadow: 'none',
alignItems: 'center',
width: theme.breakpoints.values.lg,
},
}}
>
<IconButton
onClick={handleClose}
size="large"
sx={{
backgroundColor: '#fff !important',
position: 'fixed',
top: theme.spacing(4),
right: theme.spacing(4),
}}
>
<Close width={32} height={32} />
</IconButton>

<IconButton
onClick={handlePrev}
size="large"
sx={{
backgroundColor: '#fff !important',
position: 'fixed',
marginTop: theme.spacing(-2),
top: '50%',
left: theme.spacing(4),
}}
>
<ArrowBackIosNew width={32} height={32} />
</IconButton>

<IconButton
onClick={handleNext}
size="large"
sx={{
backgroundColor: '#fff !important',
position: 'fixed',
marginTop: theme.spacing(-2),
top: '50%',
right: theme.spacing(4),
}}
>
<ArrowForwardIos width={32} height={32} />
</IconButton>

<DialogContent
onClick={handleClose}
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
}}
>
<Header content={item} />
{item.prefetchImages?.map((image) => <DialogImage key={image} src={image} alt={item.title} />)}
{/* <Simple content={item} /> */}
</DialogContent>
</Dialog>
)}
</>
);
}
21 changes: 3 additions & 18 deletions components/Help.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
import {
Checkbox,
IconButton,
List,
ListItem,
ListItemText,
Menu,
MenuItem,
SwipeableDrawer,
Typography,
} from '@mui/material';
import { Checkbox, IconButton, List, ListItem, ListItemText, Menu, MenuItem, Drawer, Typography } from '@mui/material';
import { F, defineMessages, useIntl } from 'i18n';
import { MouseEvent, useContext, useEffect, useState } from 'react';
import { styled, useTheme } from '@mui/material/styles';
Expand Down Expand Up @@ -148,12 +138,7 @@ export default function Help() {
</MenuItem>
</Menu>

<SwipeableDrawer
anchor="right"
open={isExperimentsOpen}
onClose={() => setIsExperimentsOpen(false)}
onOpen={() => setIsExperimentsOpen(true)}
>
<Drawer anchor="right" open={isExperimentsOpen} onClose={() => setIsExperimentsOpen(false)}>
<Typography variant="h1" style={{ padding: `0 ${theme.spacing(1)}` }}>
Experiments
</Typography>
Expand All @@ -170,7 +155,7 @@ export default function Help() {
</ListItem>
))}
</List>
</SwipeableDrawer>
</Drawer>
</HelpContainer>
);
}
1 change: 0 additions & 1 deletion components/ItemWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ const StyledItemWrapper = styled('div', { label: 'ItemWrapper' })`
& img {
max-width: calc(100% + 16px);
margin: ${(props) => props.theme.spacing(0, -1)};
height: auto;
}
& img:not([alt='thumbnail']) {
Expand Down
7 changes: 3 additions & 4 deletions components/content/SiteMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import baseTheme from 'styles';
import constants from 'util/constants';
import { transientOptions } from 'util/css';
import { useRouter } from 'next/router';
import { SwipeableDrawer, useMediaQuery } from '@mui/material';
import { Drawer, useMediaQuery } from '@mui/material';

export const SITE_MAP_WIDTH = 175;

Expand All @@ -35,7 +35,7 @@ const Nav = styled('nav', transientOptions)`
3px 3px ${(props) => props.theme.palette.primary.light};
`;

const SwipeableDrawerStyled = styled(SwipeableDrawer)`
const DrawerStyled = styled(Drawer)`
height: calc(100vh - ${(props) => props.theme.spacing(1)} * 2);
width: ${SITE_MAP_WIDTH}px;
overflow: auto;
Expand Down Expand Up @@ -266,7 +266,7 @@ export default function SiteMap({ content, username }: { content?: Content; user
}

const items = generateItems(siteMap);
const DrawerComponent = isTablet ? SwipeableDrawerStyled : Nav;
const DrawerComponent = isTablet ? DrawerStyled : Nav;

return (
<>
Expand All @@ -293,7 +293,6 @@ export default function SiteMap({ content, username }: { content?: Content; user
anchor="left"
open={isDrawerOpen}
onClose={() => setIsDrawerOpen(false)}
onOpen={() => setIsDrawerOpen(true)}
PaperProps={{ sx: { width: '100%' } }}
>
<ul>
Expand Down
Loading

1 comment on commit 31c8b5e

@vercel
Copy link

@vercel vercel bot commented on 31c8b5e Nov 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.