Expand image button (#570)

added full-screen image modal when clicking on img's

Co-authored-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
Philip Molares 2020-09-19 20:12:57 +02:00 committed by GitHub
parent 553cd3577d
commit cac9b7ea37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 55 additions and 7 deletions

View file

@ -39,6 +39,7 @@
- Added shortcodes for [fork-awesome icons](https://forkaweso.me/Fork-Awesome/icons/) (e.g. `:fa-picture-o:`) - Added shortcodes for [fork-awesome icons](https://forkaweso.me/Fork-Awesome/icons/) (e.g. `:fa-picture-o:`)
- The code button now adds code fences even if the user selected nothing beforehand - The code button now adds code fences even if the user selected nothing beforehand
- Code blocks with 'csv' as language render as tables. - Code blocks with 'csv' as language render as tables.
- All images can be clicked to show them in full screen.
- Code blocks with 'vega-lite' as language are rendered as [vega-lite diagrams](https://vega.github.io/vega-lite/examples/). - Code blocks with 'vega-lite' as language are rendered as [vega-lite diagrams](https://vega.github.io/vega-lite/examples/).
### Changed ### Changed

BIN
public/highres.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 MiB

View file

@ -8,14 +8,15 @@ import { ShowIf } from '../show-if/show-if'
export interface CommonModalProps { export interface CommonModalProps {
show: boolean show: boolean
onHide: () => void onHide: () => void
titleI18nKey: string titleI18nKey?: string
title?: string
closeButton?: boolean closeButton?: boolean
icon?: IconName icon?: IconName
size?: 'lg' | 'sm' | 'xl' size?: 'lg' | 'sm' | 'xl'
additionalClasses?: string additionalClasses?: string
} }
export const CommonModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18nKey, closeButton, icon, additionalClasses, size, children }) => { export const CommonModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18nKey, title, closeButton, icon, additionalClasses, size, children }) => {
useTranslation() useTranslation()
return ( return (
@ -25,7 +26,10 @@ export const CommonModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18
<ShowIf condition={!!icon}> <ShowIf condition={!!icon}>
<ForkAwesomeIcon icon={icon as IconName}/>&nbsp; <ForkAwesomeIcon icon={icon as IconName}/>&nbsp;
</ShowIf> </ShowIf>
<Trans i18nKey={titleI18nKey}/> { titleI18nKey
? <Trans i18nKey={titleI18nKey}/>
: <span>{title}</span>
}
</Modal.Title> </Modal.Title>
</Modal.Header> </Modal.Header>
{ children } { children }

View file

@ -103,6 +103,10 @@ digraph D {
} }
\`\`\` \`\`\`
## High Res Image
![Wheat Field with Cypresses](/highres.jpg)
## Sequence Diagram (deprecated) ## Sequence Diagram (deprecated)
\`\`\`sequence \`\`\`sequence

View file

@ -0,0 +1,31 @@
import React, { Fragment, useState } from 'react'
import { Modal } from 'react-bootstrap'
import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon'
export const Frame: React.FC<React.ImgHTMLAttributes<HTMLImageElement>> = ({ alt, ...props }) => {
const [showFullscreenImage, setShowFullscreenImage] = useState(false)
return (
<Fragment>
<img alt={alt} {...props} className={'cursor-zoom-in'} onClick={() => setShowFullscreenImage(true)}/>
<Modal
animation={true}
centered={true}
dialogClassName={'text-dark'}
show={showFullscreenImage}
onHide={() => setShowFullscreenImage(false)}
closeButton={true}
size={'xl'}
>
<Modal.Header closeButton={true}>
<Modal.Title className={'h6'}>
<ForkAwesomeIcon icon={'picture-o'}/>
&nbsp;
<span>{alt ?? ''}</span>
</Modal.Title>
</Modal.Header>
<img alt={alt} {...props} className={'w-100 cursor-zoom-out'} onClick={() => setShowFullscreenImage(false)}/>
</Modal>
</Fragment>
)
}

View file

@ -2,8 +2,9 @@ import React, { useEffect, useState } from 'react'
import { useSelector } from 'react-redux' import { useSelector } from 'react-redux'
import { getProxiedUrl } from '../../../../api/media' import { getProxiedUrl } from '../../../../api/media'
import { ApplicationState } from '../../../../redux' import { ApplicationState } from '../../../../redux'
import { Frame } from './frame'
export const ImageFrame: React.FC<React.ImgHTMLAttributes<HTMLImageElement>> = ({ alt, src, title, ...props }) => { export const ImageFrame: React.FC<React.ImgHTMLAttributes<HTMLImageElement>> = ({ src, title, alt, ...props }) => {
const [imageUrl, setImageUrl] = useState('') const [imageUrl, setImageUrl] = useState('')
const imageProxyEnabled = useSelector((state: ApplicationState) => state.config.useImageProxy) const imageProxyEnabled = useSelector((state: ApplicationState) => state.config.useImageProxy)
@ -18,11 +19,11 @@ export const ImageFrame: React.FC<React.ImgHTMLAttributes<HTMLImageElement>> = (
if (imageProxyEnabled) { if (imageProxyEnabled) {
return ( return (
<img alt={alt} src={imageUrl} title={title ?? ''} {...props}/> <Frame src={imageUrl} title={title ?? alt ?? ''} alt={alt} {...props}/>
) )
} }
return ( return (
<img alt={alt} src={src ?? ''} title={title ?? ''} {...props}/> <Frame src={src ?? ''} title={title ?? alt ?? ''} alt={alt} {...props}/>
) )
} }

View file

@ -7,7 +7,6 @@ export class ImageReplacer extends ComponentReplacer {
public getReplacement (node: DomElement): React.ReactElement | undefined { public getReplacement (node: DomElement): React.ReactElement | undefined {
if (node.name === 'img' && node.attribs) { if (node.name === 'img' && node.attribs) {
return <ImageFrame return <ImageFrame
id={node.attribs.id} id={node.attribs.id}
className={node.attribs.class} className={node.attribs.class}
src={node.attribs.src} src={node.attribs.src}

View file

@ -48,3 +48,11 @@ body {
.font-style-normal { .font-style-normal {
font-style: normal; font-style: normal;
} }
.cursor-zoom-in {
cursor: zoom-in;
}
.cursor-zoom-out {
cursor: zoom-out;
}