import { NodeViewWrapper } from '@tiptap/react' import React, { useEffect } from 'react' import { Resizable } from 're-resizable' import { AlertTriangle, Image, Download, AlignLeft, AlignCenter, AlignRight, Expand } from 'lucide-react' import { uploadNewImageFile } from '../../../../../services/blocks/Image/images' import { getActivityBlockMediaDirectory } from '@services/media/media' import { useOrg } from '@components/Contexts/OrgContext' import { useCourse } from '@components/Contexts/CourseContext' import { useEditorProvider } from '@components/Contexts/Editor/EditorContext' import { useLHSession } from '@components/Contexts/LHSessionContext' import { FileUploadBlock, FileUploadBlockButton, FileUploadBlockInput } from '../../FileUploadBlock' import { constructAcceptValue } from '@/lib/constants'; import Modal from '@components/Objects/StyledElements/Modal/Modal' const SUPPORTED_FILES = constructAcceptValue(['image']) function ImageBlockComponent(props: any) { const org = useOrg() as any const course = useCourse() as any const editorState = useEditorProvider() as any const session = useLHSession() as any const access_token = session?.data?.tokens?.access_token; const isEditable = editorState.isEditable const [image, setImage] = React.useState(null) const [isLoading, setIsLoading] = React.useState(false) const [blockObject, setblockObject] = React.useState( props.node.attrs.blockObject ) const [imageSize, setImageSize] = React.useState({ width: props.node.attrs.size ? props.node.attrs.size.width : 300, }) const [alignment, setAlignment] = React.useState(props.node.attrs.alignment || 'center') const [isModalOpen, setIsModalOpen] = React.useState(false) const fileId = blockObject ? `${blockObject.content.file_id}.${blockObject.content.file_format}` : null const handleImageChange = (event: React.ChangeEvent) => { setImage(event.target.files[0]) } const handleSubmit = async (e: any) => { e.preventDefault() setIsLoading(true) let object = await uploadNewImageFile( image, props.extension.options.activity.activity_uuid,access_token ) setIsLoading(false) setblockObject(object) props.updateAttributes({ blockObject: object, size: imageSize, alignment: alignment, }) } const handleDownload = () => { if (!fileId) return; const imageUrl = getActivityBlockMediaDirectory( org?.org_uuid, course?.courseStructure.course_uuid, props.extension.options.activity.activity_uuid, blockObject.block_uuid, fileId, 'imageBlock' ); const link = document.createElement('a'); link.href = imageUrl || ''; link.download = `image-${blockObject?.block_uuid || 'download'}.${blockObject?.content.file_format || 'jpg'}`; link.setAttribute('download', ''); link.setAttribute('target', '_blank'); link.setAttribute('rel', 'noopener noreferrer'); document.body.appendChild(link); link.click(); document.body.removeChild(link); }; const handleExpand = () => { setIsModalOpen(true); }; const handleAlignmentChange = (newAlignment: string) => { setAlignment(newAlignment); props.updateAttributes({ alignment: newAlignment, }); }; const imageUrl = blockObject ? getActivityBlockMediaDirectory( org?.org_uuid, course?.courseStructure.course_uuid, props.extension.options.activity.activity_uuid, blockObject.block_uuid, fileId || '', 'imageBlock' ) : null; useEffect(() => {}, [course, org]) const getAlignmentClass = () => { switch (alignment) { case 'left': return 'justify-start'; case 'right': return 'justify-end'; default: return 'justify-center'; } }; return ( <> {blockObject && isEditable && (
{ const newWidth = Math.min(imageSize.width + d.width, ref.parentElement?.clientWidth || 1000); props.updateAttributes({ size: { width: newWidth, }, }) setImageSize({ width: newWidth, }) }} >
)} {blockObject && !isEditable && (
)} {isLoading && (
)}
{blockObject && imageUrl && ( } /> )} ) } export default ImageBlockComponent