hedgedoc/frontend/src/components/markdown-renderer/extensions/image-placeholder/image-placeholder.tsx
Philip Molares 1c16e25e14 feat(frontend): replace forkawesome with bootstrap icons
These icon replace fork awesome. A linter informs the user about the deprecation.

See https://github.com/hedgedoc/hedgedoc/issues/2929

Co-authored-by: Philip Molares <philip.molares@udo.edu>
Co-authored-by: Tilman Vatteroth <git@tilmanvatteroth.de>
Signed-off-by: Philip Molares <philip.molares@udo.edu>
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
2023-02-24 14:31:17 +01:00

114 lines
3.9 KiB
TypeScript

/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { cypressId } from '../../../../utils/cypress-attribute'
import { UiIcon } from '../../../common/icons/ui-icon'
import { acceptedMimeTypes } from '../../../common/upload-image-mimetypes'
import { useOnImageUpload } from './hooks/use-on-image-upload'
import { usePlaceholderSizeStyle } from './hooks/use-placeholder-size-style'
import styles from './image-placeholder.module.scss'
import React, { useCallback, useMemo, useRef, useState } from 'react'
import { Button } from 'react-bootstrap'
import { Upload as IconUpload } from 'react-bootstrap-icons'
import { Trans, useTranslation } from 'react-i18next'
export interface PlaceholderImageFrameProps {
alt?: string
title?: string
width?: string | number
height?: string | number
lineIndex?: number
placeholderIndexInLine?: number
}
/**
* Shows a placeholder for an actual image with the possibility to upload images via button or drag'n'drop.
*
* @param alt The alt text of the image. Will be shown in the placeholder
* @param title The title text of the image. Will be shown in the placeholder
* @param width The width of the placeholder
* @param height The height of the placeholder
* @param lineIndex The index of the line in the markdown content where the placeholder is defined
* @param placeholderIndexInLine The index of the placeholder in the markdown line
*/
export const ImagePlaceholder: React.FC<PlaceholderImageFrameProps> = ({
alt,
title,
width,
height,
lineIndex,
placeholderIndexInLine
}) => {
useTranslation()
const fileInputReference = useRef<HTMLInputElement>(null)
const onImageUpload = useOnImageUpload(lineIndex, placeholderIndexInLine)
const [showDragStatus, setShowDragStatus] = useState(false)
const onDropHandler = useCallback(
(event: React.DragEvent<HTMLSpanElement>) => {
event.preventDefault()
if (event?.dataTransfer?.files?.length > 0) {
onImageUpload(event.dataTransfer.files[0])
}
},
[onImageUpload]
)
const onDragOverHandler = useCallback((event: React.DragEvent<HTMLSpanElement>) => {
event.preventDefault()
setShowDragStatus(true)
}, [])
const onDragLeave = useCallback(() => {
setShowDragStatus(false)
}, [])
const onChangeHandler = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const fileList = event.target.files
if (!fileList || fileList.length < 1) {
return
}
onImageUpload(fileList[0])
},
[onImageUpload]
)
const uploadButtonClicked = useCallback(() => fileInputReference.current?.click(), [])
const containerStyle = usePlaceholderSizeStyle(width, height)
const containerDragClasses = useMemo(() => (showDragStatus ? 'bg-primary text-white' : 'text-dark'), [showDragStatus])
return (
<span
{...cypressId('image-placeholder-image-drop')}
className={`${styles['image-drop']} d-inline-flex flex-column align-items-center ${containerDragClasses} p-1`}
style={containerStyle}
onDrop={onDropHandler}
onDragOver={onDragOverHandler}
onDragLeave={onDragLeave}>
<input
type='file'
className='d-none'
accept={acceptedMimeTypes}
onChange={onChangeHandler}
ref={fileInputReference}
/>
<div className={'align-items-center flex-column justify-content-center flex-fill d-flex'}>
<div className={'d-flex flex-column'}>
<span className='my-2'>
<Trans i18nKey={'editor.embeddings.placeholderImage.placeholderText'} />
</span>
<span className={styles['altText']}>{alt ?? title ?? ''}</span>
</div>
</div>
<Button size={'sm'} variant={'primary'} onClick={uploadButtonClicked}>
<UiIcon icon={IconUpload} className='my-2' />
<Trans i18nKey={'editor.embeddings.placeholderImage.upload'} className='my-2' />
</Button>
</span>
)
}