mirror of
https://github.com/stonith404/pingvin-share.git
synced 2025-02-19 01:55:48 -05:00
feat: show upload modal on file drop
This commit is contained in:
parent
955af04e32
commit
13e7a30bb9
3 changed files with 60 additions and 56 deletions
|
@ -1,6 +1,6 @@
|
||||||
import { Button, Center, createStyles, Group, Text } from "@mantine/core";
|
import { Button, Center, createStyles, Group, Text } from "@mantine/core";
|
||||||
import { Dropzone as MantineDropzone } from "@mantine/dropzone";
|
import { Dropzone as MantineDropzone } from "@mantine/dropzone";
|
||||||
import { Dispatch, ForwardedRef, SetStateAction, useRef } from "react";
|
import { ForwardedRef, useRef } from "react";
|
||||||
import { TbCloudUpload, TbUpload } from "react-icons/tb";
|
import { TbCloudUpload, TbUpload } from "react-icons/tb";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import useTranslate from "../../hooks/useTranslate.hook";
|
import useTranslate from "../../hooks/useTranslate.hook";
|
||||||
|
@ -35,13 +35,11 @@ const useStyles = createStyles((theme) => ({
|
||||||
const Dropzone = ({
|
const Dropzone = ({
|
||||||
isUploading,
|
isUploading,
|
||||||
maxShareSize,
|
maxShareSize,
|
||||||
files,
|
showCreateUploadModalCallback,
|
||||||
setFiles,
|
|
||||||
}: {
|
}: {
|
||||||
isUploading: boolean;
|
isUploading: boolean;
|
||||||
maxShareSize: number;
|
maxShareSize: number;
|
||||||
files: FileUpload[];
|
showCreateUploadModalCallback: (files: FileUpload[]) => void;
|
||||||
setFiles: Dispatch<SetStateAction<FileUpload[]>>;
|
|
||||||
}) => {
|
}) => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
|
|
||||||
|
@ -55,24 +53,21 @@ const Dropzone = ({
|
||||||
}}
|
}}
|
||||||
disabled={isUploading}
|
disabled={isUploading}
|
||||||
openRef={openRef as ForwardedRef<() => void>}
|
openRef={openRef as ForwardedRef<() => void>}
|
||||||
onDrop={(newFiles: FileUpload[]) => {
|
onDrop={(files: FileUpload[]) => {
|
||||||
const fileSizeSum = [...newFiles, ...files].reduce(
|
const fileSizeSum = files.reduce((n, { size }) => n + size, 0);
|
||||||
(n, { size }) => n + size,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (fileSizeSum > maxShareSize) {
|
if (fileSizeSum > maxShareSize) {
|
||||||
toast.error(
|
toast.error(
|
||||||
t("upload.dropzone.notify.file-too-big", {
|
t("upload.dropzone.notify.file-too-big", {
|
||||||
maxSize: byteToHumanSizeString(maxShareSize),
|
maxSize: byteToHumanSizeString(maxShareSize),
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
newFiles = newFiles.map((newFile) => {
|
files = files.map((newFile) => {
|
||||||
newFile.uploadingProgress = 0;
|
newFile.uploadingProgress = 0;
|
||||||
return newFile;
|
return newFile;
|
||||||
});
|
});
|
||||||
setFiles([...newFiles, ...files]);
|
showCreateUploadModalCallback(files);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className={classes.dropzone}
|
className={classes.dropzone}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import useTranslate, {
|
||||||
translateOutsideContext,
|
translateOutsideContext,
|
||||||
} from "../../../hooks/useTranslate.hook";
|
} from "../../../hooks/useTranslate.hook";
|
||||||
import shareService from "../../../services/share.service";
|
import shareService from "../../../services/share.service";
|
||||||
|
import { FileUpload } from "../../../types/File.type";
|
||||||
import { CreateShare } from "../../../types/share.type";
|
import { CreateShare } from "../../../types/share.type";
|
||||||
import { getExpirationPreview } from "../../../utils/date.util";
|
import { getExpirationPreview } from "../../../utils/date.util";
|
||||||
|
|
||||||
|
@ -38,7 +39,8 @@ const showCreateUploadModal = (
|
||||||
allowUnauthenticatedShares: boolean;
|
allowUnauthenticatedShares: boolean;
|
||||||
enableEmailRecepients: boolean;
|
enableEmailRecepients: boolean;
|
||||||
},
|
},
|
||||||
uploadCallback: (createShare: CreateShare) => void,
|
files: FileUpload[],
|
||||||
|
uploadCallback: (createShare: CreateShare, files: FileUpload[]) => void
|
||||||
) => {
|
) => {
|
||||||
const t = translateOutsideContext();
|
const t = translateOutsideContext();
|
||||||
|
|
||||||
|
@ -47,6 +49,7 @@ const showCreateUploadModal = (
|
||||||
children: (
|
children: (
|
||||||
<CreateUploadModalBody
|
<CreateUploadModalBody
|
||||||
options={options}
|
options={options}
|
||||||
|
files={files}
|
||||||
uploadCallback={uploadCallback}
|
uploadCallback={uploadCallback}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
@ -55,9 +58,11 @@ const showCreateUploadModal = (
|
||||||
|
|
||||||
const CreateUploadModalBody = ({
|
const CreateUploadModalBody = ({
|
||||||
uploadCallback,
|
uploadCallback,
|
||||||
|
files,
|
||||||
options,
|
options,
|
||||||
}: {
|
}: {
|
||||||
uploadCallback: (createShare: CreateShare) => void;
|
files: FileUpload[];
|
||||||
|
uploadCallback: (createShare: CreateShare, files: FileUpload[]) => void;
|
||||||
options: {
|
options: {
|
||||||
isUserSignedIn: boolean;
|
isUserSignedIn: boolean;
|
||||||
isReverseShare: boolean;
|
isReverseShare: boolean;
|
||||||
|
@ -121,7 +126,8 @@ const CreateUploadModalBody = ({
|
||||||
const expiration = form.values.never_expires
|
const expiration = form.values.never_expires
|
||||||
? "never"
|
? "never"
|
||||||
: form.values.expiration_num + form.values.expiration_unit;
|
: form.values.expiration_num + form.values.expiration_unit;
|
||||||
uploadCallback({
|
uploadCallback(
|
||||||
|
{
|
||||||
id: values.link,
|
id: values.link,
|
||||||
expiration: expiration,
|
expiration: expiration,
|
||||||
recipients: values.recipients,
|
recipients: values.recipients,
|
||||||
|
@ -130,7 +136,9 @@ const CreateUploadModalBody = ({
|
||||||
password: values.password,
|
password: values.password,
|
||||||
maxViews: values.maxViews,
|
maxViews: values.maxViews,
|
||||||
},
|
},
|
||||||
});
|
},
|
||||||
|
files
|
||||||
|
);
|
||||||
modals.closeAll();
|
modals.closeAll();
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
|
@ -152,7 +160,7 @@ const CreateUploadModalBody = ({
|
||||||
"link",
|
"link",
|
||||||
Buffer.from(Math.random().toString(), "utf8")
|
Buffer.from(Math.random().toString(), "utf8")
|
||||||
.toString("base64")
|
.toString("base64")
|
||||||
.substr(10, 7),
|
.substr(10, 7)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -251,7 +259,7 @@ const CreateUploadModalBody = ({
|
||||||
neverExpires: t("upload.modal.completed.never-expires"),
|
neverExpires: t("upload.modal.completed.never-expires"),
|
||||||
expiresOn: t("upload.modal.completed.expires-on"),
|
expiresOn: t("upload.modal.completed.expires-on"),
|
||||||
},
|
},
|
||||||
form,
|
form
|
||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
</>
|
</>
|
||||||
|
@ -266,7 +274,7 @@ const CreateUploadModalBody = ({
|
||||||
<Textarea
|
<Textarea
|
||||||
variant="filled"
|
variant="filled"
|
||||||
placeholder={t(
|
placeholder={t(
|
||||||
"upload.modal.accordion.description.placeholder",
|
"upload.modal.accordion.description.placeholder"
|
||||||
)}
|
)}
|
||||||
{...form.getInputProps("description")}
|
{...form.getInputProps("description")}
|
||||||
/>
|
/>
|
||||||
|
@ -290,7 +298,7 @@ const CreateUploadModalBody = ({
|
||||||
if (!query.match(/^\S+@\S+\.\S+$/)) {
|
if (!query.match(/^\S+@\S+\.\S+$/)) {
|
||||||
form.setFieldError(
|
form.setFieldError(
|
||||||
"recipients",
|
"recipients",
|
||||||
t("upload.modal.accordion.email.invalid-email"),
|
t("upload.modal.accordion.email.invalid-email")
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
form.setFieldError("recipients", null);
|
form.setFieldError("recipients", null);
|
||||||
|
@ -316,7 +324,7 @@ const CreateUploadModalBody = ({
|
||||||
<PasswordInput
|
<PasswordInput
|
||||||
variant="filled"
|
variant="filled"
|
||||||
placeholder={t(
|
placeholder={t(
|
||||||
"upload.modal.accordion.security.password.placeholder",
|
"upload.modal.accordion.security.password.placeholder"
|
||||||
)}
|
)}
|
||||||
label={t("upload.modal.accordion.security.password.label")}
|
label={t("upload.modal.accordion.security.password.label")}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
|
@ -327,7 +335,7 @@ const CreateUploadModalBody = ({
|
||||||
type="number"
|
type="number"
|
||||||
variant="filled"
|
variant="filled"
|
||||||
placeholder={t(
|
placeholder={t(
|
||||||
"upload.modal.accordion.security.max-views.placeholder",
|
"upload.modal.accordion.security.max-views.placeholder"
|
||||||
)}
|
)}
|
||||||
label={t("upload.modal.accordion.security.max-views.label")}
|
label={t("upload.modal.accordion.security.max-views.label")}
|
||||||
{...form.getInputProps("maxViews")}
|
{...form.getInputProps("maxViews")}
|
||||||
|
@ -336,7 +344,7 @@ const CreateUploadModalBody = ({
|
||||||
</Accordion.Panel>
|
</Accordion.Panel>
|
||||||
</Accordion.Item>
|
</Accordion.Item>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
<Button type="submit">
|
<Button type="submit" data-autofocus>
|
||||||
<FormattedMessage id="common.button.share" />
|
<FormattedMessage id="common.button.share" />
|
||||||
</Button>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
|
@ -40,7 +40,7 @@ const Upload = ({
|
||||||
|
|
||||||
maxShareSize ??= parseInt(config.get("share.maxSize"));
|
maxShareSize ??= parseInt(config.get("share.maxSize"));
|
||||||
|
|
||||||
const uploadFiles = async (share: CreateShare) => {
|
const uploadFiles = async (share: CreateShare, files: FileUpload[]) => {
|
||||||
setisUploading(true);
|
setisUploading(true);
|
||||||
createdShare = await shareService.create(share);
|
createdShare = await shareService.create(share);
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ const Upload = ({
|
||||||
file.uploadingProgress = progress;
|
file.uploadingProgress = progress;
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ const Upload = ({
|
||||||
name: file.name,
|
name: file.name,
|
||||||
},
|
},
|
||||||
chunkIndex,
|
chunkIndex,
|
||||||
chunks,
|
chunks
|
||||||
)
|
)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
fileId = response.id;
|
fileId = response.id;
|
||||||
|
@ -114,16 +114,34 @@ const Upload = ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
Promise.all(fileUploadPromises);
|
Promise.all(fileUploadPromises);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showCreateUploadModalCallback = (files: FileUpload[]) => {
|
||||||
|
setFiles(files);
|
||||||
|
showCreateUploadModal(
|
||||||
|
modals,
|
||||||
|
{
|
||||||
|
isUserSignedIn: user ? true : false,
|
||||||
|
isReverseShare,
|
||||||
|
appUrl: config.get("general.appUrl"),
|
||||||
|
allowUnauthenticatedShares: config.get(
|
||||||
|
"share.allowUnauthenticatedShares"
|
||||||
|
),
|
||||||
|
enableEmailRecepients: config.get("email.enableShareEmailRecipients"),
|
||||||
|
},
|
||||||
|
files,
|
||||||
|
uploadFiles
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Check if there are any files that failed to upload
|
// Check if there are any files that failed to upload
|
||||||
const fileErrorCount = files.filter(
|
const fileErrorCount = files.filter(
|
||||||
(file) => file.uploadingProgress == -1,
|
(file) => file.uploadingProgress == -1
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
if (fileErrorCount > 0) {
|
if (fileErrorCount > 0) {
|
||||||
|
@ -133,7 +151,7 @@ const Upload = ({
|
||||||
{
|
{
|
||||||
withCloseButton: false,
|
withCloseButton: false,
|
||||||
autoClose: false,
|
autoClose: false,
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
errorToastShown = true;
|
errorToastShown = true;
|
||||||
|
@ -166,31 +184,14 @@ const Upload = ({
|
||||||
<Button
|
<Button
|
||||||
loading={isUploading}
|
loading={isUploading}
|
||||||
disabled={files.length <= 0}
|
disabled={files.length <= 0}
|
||||||
onClick={() => {
|
onClick={() => showCreateUploadModalCallback(files)}
|
||||||
showCreateUploadModal(
|
|
||||||
modals,
|
|
||||||
{
|
|
||||||
isUserSignedIn: user ? true : false,
|
|
||||||
isReverseShare,
|
|
||||||
appUrl: config.get("general.appUrl"),
|
|
||||||
allowUnauthenticatedShares: config.get(
|
|
||||||
"share.allowUnauthenticatedShares",
|
|
||||||
),
|
|
||||||
enableEmailRecepients: config.get(
|
|
||||||
"email.enableShareEmailRecipients",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
uploadFiles,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<FormattedMessage id="common.button.share" />
|
<FormattedMessage id="common.button.share" />
|
||||||
</Button>
|
</Button>
|
||||||
</Group>
|
</Group>
|
||||||
<Dropzone
|
<Dropzone
|
||||||
maxShareSize={maxShareSize}
|
maxShareSize={maxShareSize}
|
||||||
files={files}
|
showCreateUploadModalCallback={showCreateUploadModalCallback}
|
||||||
setFiles={setFiles}
|
|
||||||
isUploading={isUploading}
|
isUploading={isUploading}
|
||||||
/>
|
/>
|
||||||
{files.length > 0 && <FileList files={files} setFiles={setFiles} />}
|
{files.length > 0 && <FileList files={files} setFiles={setFiles} />}
|
||||||
|
|
Loading…
Add table
Reference in a new issue