mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-20 18:25:21 -04:00

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>
114 lines
3.9 KiB
TypeScript
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>
|
|
)
|
|
}
|