diff --git a/src/components/Article/Article.module.scss b/src/components/Article/Article.module.scss index 1ea954ba..ed15b000 100644 --- a/src/components/Article/Article.module.scss +++ b/src/components/Article/Article.module.scss @@ -36,6 +36,7 @@ img { img { display: block; margin-bottom: 0.5em; + cursor: zoom-in; } blockquote, diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index 5ea1a86d..39586bb4 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -27,6 +27,7 @@ import { createPopper } from '@popperjs/core' import { AuthorBadge } from '../Author/AuthorBadge' import { getImageUrl } from '../../utils/getImageUrl' import { FeedArticlePopup } from '../Feed/FeedArticlePopup' +import { Lightbox } from '../_shared/Lightbox' type Props = { article: Shout @@ -49,6 +50,8 @@ const scrollTo = (el: HTMLElement) => { } export const FullArticle = (props: Props) => { + const [selectedImage, setSelectedImage] = createSignal('') + const { t, formatDate } = useLocalize() const { user, @@ -169,7 +172,7 @@ export const FullArticle = (props: Props) => { document.body.appendChild(tooltip) if (element.hasAttribute('href')) { - element.setAttribute('href', 'javascript: void(0);') + element.setAttribute('href', 'javascript: void(0)') } const popperInstance = createPopper(element, tooltip, { @@ -230,7 +233,19 @@ export const FullArticle = (props: Props) => { }) }) - const [isActionPopupActive, setIsActionPopupActive] = createSignal(false) + const openLightbox = (image) => { + setSelectedImage(image) + } + const handleLightboxClose = () => { + setSelectedImage() + } + + const handleArticleBodyClick = (event) => { + if (event.target.tagName === 'IMG') { + const src = event.target.src + openLightbox(getImageUrl(src)) + } + } return ( <> @@ -313,7 +328,7 @@ export const FullArticle = (props: Props) => { -
+
}> @@ -433,7 +448,6 @@ export const FullArticle = (props: Props) => { description={getDescription(props.article.body)} imageUrl={props.article.cover} shareUrl={getShareUrl({ pathname: `/${props.article.slug}` })} - isVisible={(value) => setIsActionPopupActive(value)} trigger={
+ + + ) } diff --git a/src/components/_shared/Lightbox/Lightbox.module.scss b/src/components/_shared/Lightbox/Lightbox.module.scss new file mode 100644 index 00000000..834c8750 --- /dev/null +++ b/src/components/_shared/Lightbox/Lightbox.module.scss @@ -0,0 +1,52 @@ +.Lightbox { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgb(0 0 0 / 80%); + display: flex; + align-items: center; + justify-content: center; + z-index: 10000; + + .image { + max-width: 90%; + max-height: 80%; + cursor: pointer; + } + + .close { + position: absolute; + top: 20px; + right: 40px; + font-size: 30px; + color: white; + cursor: pointer; + width: 20px; + height: 20px; + } + + .zoomControls { + display: flex; + position: absolute; + bottom: 16px; + left: 50%; + height: 24px; + gap: 1rem; + transform: translateX(-50%); + + .control { + border-radius: 50%; + width: 24px; + height: 24px; + font-size: 20px; + line-height: 1; + display: flex; + align-items: center; + justify-content: center; + border: 2px solid #fff; + color: #fff; + } + } +} diff --git a/src/components/_shared/Lightbox/Lightbox.tsx b/src/components/_shared/Lightbox/Lightbox.tsx new file mode 100644 index 00000000..a90bf219 --- /dev/null +++ b/src/components/_shared/Lightbox/Lightbox.tsx @@ -0,0 +1,56 @@ +import { clsx } from 'clsx' +import styles from './Lightbox.module.scss' +import { createSignal } from 'solid-js' +import { Icon } from '../Icon' + +type Props = { + class?: string + image: string + onClose: () => void +} + +const ZOOM_STEP = 1.08 +export const Lightbox = (props: Props) => { + const [zoomLevel, setZoomLevel] = createSignal(1) + + const closeLightbox = () => { + props.onClose() + } + + const zoomIn = (event) => { + event.stopPropagation() + setZoomLevel(zoomLevel() * ZOOM_STEP) + } + const zoomOut = (event) => { + event.stopPropagation() + setZoomLevel(zoomLevel() / ZOOM_STEP) + } + + const lightboxStyle = () => ({ + transform: `scale(${zoomLevel()})`, + transition: 'transform 0.3s ease' + }) + + return ( +
+ + + +
+ + +
+ {''} event.stopPropagation()} + /> +
+ ) +} diff --git a/src/components/_shared/Lightbox/index.ts b/src/components/_shared/Lightbox/index.ts new file mode 100644 index 00000000..2b06237a --- /dev/null +++ b/src/components/_shared/Lightbox/index.ts @@ -0,0 +1 @@ +export { Lightbox } from './Lightbox' diff --git a/src/context/profile.tsx b/src/context/profile.tsx index 5c55b500..ed6f13c3 100644 --- a/src/context/profile.tsx +++ b/src/context/profile.tsx @@ -69,9 +69,6 @@ const useProfileForm = () => { }) } } - createEffect(() => { - console.log('!!! FL:', form.links) - }) return { form, submit, updateFormField, slugError } }