parent
2c7e98acdf
commit
4121d99a73
|
@ -36,6 +36,7 @@ img {
|
|||
img {
|
||||
display: block;
|
||||
margin-bottom: 0.5em;
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
blockquote,
|
||||
|
|
|
@ -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) => {
|
|||
</Show>
|
||||
|
||||
<Show when={body()}>
|
||||
<div id="shoutBody" class={styles.shoutBody}>
|
||||
<div id="shoutBody" class={styles.shoutBody} onClick={handleArticleBodyClick}>
|
||||
<Show when={!body().startsWith('<')} fallback={<div innerHTML={body()} />}>
|
||||
<MD body={body()} />
|
||||
</Show>
|
||||
|
@ -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={
|
||||
<button>
|
||||
<Icon name="ellipsis" class={clsx(styles.icon)} />
|
||||
|
@ -490,6 +504,9 @@ export const FullArticle = (props: Props) => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Show when={selectedImage()}>
|
||||
<Lightbox image={selectedImage()} onClose={handleLightboxClose} />
|
||||
</Show>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
52
src/components/_shared/Lightbox/Lightbox.module.scss
Normal file
52
src/components/_shared/Lightbox/Lightbox.module.scss
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
56
src/components/_shared/Lightbox/Lightbox.tsx
Normal file
56
src/components/_shared/Lightbox/Lightbox.tsx
Normal file
|
@ -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 (
|
||||
<div class={clsx(styles.Lightbox, props.class)} onClick={closeLightbox}>
|
||||
<span class={styles.close} onClick={closeLightbox}>
|
||||
<Icon name="close-white" />
|
||||
</span>
|
||||
<div class={styles.zoomControls}>
|
||||
<button class={styles.control} onClick={(event) => zoomOut(event)}>
|
||||
<b>-</b>
|
||||
</button>
|
||||
<button class={styles.control} onClick={(event) => zoomIn(event)}>
|
||||
<b>+</b>
|
||||
</button>
|
||||
</div>
|
||||
<img
|
||||
class={styles.image}
|
||||
src={props.image}
|
||||
style={lightboxStyle()}
|
||||
alt={''}
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
1
src/components/_shared/Lightbox/index.ts
Normal file
1
src/components/_shared/Lightbox/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export { Lightbox } from './Lightbox'
|
|
@ -69,9 +69,6 @@ const useProfileForm = () => {
|
|||
})
|
||||
}
|
||||
}
|
||||
createEffect(() => {
|
||||
console.log('!!! FL:', form.links)
|
||||
})
|
||||
|
||||
return { form, submit, updateFormField, slugError }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user