mirror of
https://github.com/aljazceru/landscape-template.git
synced 2025-12-19 07:14:22 +01:00
142 lines
3.9 KiB
TypeScript
142 lines
3.9 KiB
TypeScript
import Uploady, { useRequestPreSend, UPLOADER_EVENTS, useAbortAll } from "@rpldy/uploady";
|
|
import { asUploadButton } from "@rpldy/upload-button";
|
|
// import { fetchUploadUrl } from "./fetch-upload-img-url";
|
|
import UploadDropZone from "@rpldy/upload-drop-zone";
|
|
import { forwardRef, ReactElement, useCallback, useState } from "react";
|
|
import styles from './styles.module.scss'
|
|
import { getMockSenderEnhancer } from "@rpldy/mock-sender";
|
|
import { NotificationsService } from "src/services";
|
|
import { useIsDraggingOnElement } from 'src/utils/hooks';
|
|
import { fetchUploadImageUrl } from "src/api/uploading";
|
|
|
|
|
|
|
|
const mockSenderEnhancer = getMockSenderEnhancer({
|
|
delay: 1500,
|
|
|
|
});
|
|
|
|
|
|
export interface ImageType {
|
|
id?: string | null,
|
|
name?: string | null,
|
|
url: string;
|
|
}
|
|
|
|
type RenderPropArgs = {
|
|
isUploading?: boolean;
|
|
img: ImageType | null,
|
|
onAbort: () => void,
|
|
isDraggingOnWindow?: boolean
|
|
}
|
|
|
|
interface Props {
|
|
value: ImageType | null | undefined,
|
|
onChange: (new_value: ImageType | null) => void;
|
|
wrapperClass?: string;
|
|
render: (args: RenderPropArgs) => ReactElement;
|
|
}
|
|
|
|
|
|
export default function SingleImageUploadInput(props: Props) {
|
|
|
|
const { value, onChange, render } = props;
|
|
|
|
|
|
const [currentlyUploadingItem, setCurrentlyUploadingItem] = useState<ImageType | null>(null)
|
|
|
|
|
|
return (
|
|
<Uploady
|
|
accept="image/*"
|
|
inputFieldName='file'
|
|
grouped={false}
|
|
listeners={{
|
|
[UPLOADER_EVENTS.ITEM_START]: (item) => {
|
|
onChange(null)
|
|
|
|
setCurrentlyUploadingItem({
|
|
id: item.id,
|
|
url: URL.createObjectURL(item.file),
|
|
name: item.file.name,
|
|
})
|
|
},
|
|
[UPLOADER_EVENTS.ITEM_ERROR]: (item) => {
|
|
NotificationsService.error("An error happened while uploading. Please try again.")
|
|
},
|
|
[UPLOADER_EVENTS.ITEM_FINALIZE]: () => setCurrentlyUploadingItem(null),
|
|
[UPLOADER_EVENTS.ITEM_FINISH]: (item) => {
|
|
|
|
const { id, filename, variants } = item?.uploadResponse?.data?.result;
|
|
const url = (variants as string[]).find(v => v.includes('public'));
|
|
|
|
if (id && url) {
|
|
onChange({ id, name: filename, url, })
|
|
}
|
|
}
|
|
}}
|
|
>
|
|
<DropZoneButton
|
|
extraProps={{
|
|
renderProps: {
|
|
isUploading: !!currentlyUploadingItem,
|
|
img: currentlyUploadingItem ?? value ?? null,
|
|
render,
|
|
wrapperClass: props.wrapperClass
|
|
}
|
|
}
|
|
}
|
|
/>
|
|
</Uploady>
|
|
)
|
|
}
|
|
|
|
|
|
const DropZone = forwardRef<any, any>((props, ref) => {
|
|
const { onClick, children, renderProps, ...buttonProps } = props;
|
|
|
|
const isDraggingOnWindow = useIsDraggingOnElement()
|
|
|
|
useRequestPreSend(async (data) => {
|
|
|
|
const filename = data.items?.[0].file.name ?? ''
|
|
|
|
const res = await fetchUploadImageUrl({ filename });
|
|
|
|
return {
|
|
options: {
|
|
destination: {
|
|
url: res.uploadURL
|
|
},
|
|
}
|
|
}
|
|
})
|
|
|
|
const onZoneClick = useCallback(
|
|
(e: any) => {
|
|
if (onClick) {
|
|
onClick(e);
|
|
}
|
|
},
|
|
[onClick]
|
|
);
|
|
|
|
return <UploadDropZone
|
|
{...buttonProps}
|
|
ref={ref}
|
|
type='button'
|
|
onDragOverClassName={'drag-active'}
|
|
extraProps={{ onClick: onZoneClick }}
|
|
className={renderProps.wrapperClass}
|
|
>
|
|
|
|
{renderProps.render({
|
|
img: renderProps.img,
|
|
isUploading: renderProps.isUploading,
|
|
isDraggingOnWindow,
|
|
})}
|
|
</UploadDropZone>
|
|
})
|
|
|
|
const DropZoneButton = asUploadButton(DropZone);
|