Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix time interval #1463

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 38 additions & 19 deletions components/document-upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,28 @@ import { toast } from "sonner";

import { SUPPORTED_DOCUMENT_MIME_TYPES } from "@/lib/constants";
import { usePlan } from "@/lib/swr/use-billing";
import useLimits from "@/lib/swr/use-limits";
import { bytesToSize } from "@/lib/utils";
import { fileIcon } from "@/lib/utils/get-file-icon";
import {
getFileSizeLimit,
getFileSizeLimits,
} from "@/lib/utils/get-file-size-limits";
import { getPagesCount } from "@/lib/utils/get-page-number-count";

const fileSizeLimits: { [key: string]: number } = {
"application/vnd.ms-excel": 40, // 40 MB
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": 40, // 40 MB
"application/vnd.oasis.opendocument.spreadsheet": 40, // 40 MB
"image/png": 100, // 100 MB
"image/jpeg": 100, // 100 MB
"image/jpg": 100, // 100 MB
"video/mp4": 500, // 500 MB
"video/quicktime": 500, // 500 MB
"video/x-msvideo": 500, // 500 MB
"video/webm": 500, // 500 MB
"video/ogg": 500, // 500 MB
};
// const fileSizeLimits: { [key: string]: number } = {
// "application/vnd.ms-excel": 40, // 40 MB
// "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": 40, // 40 MB
// "application/vnd.oasis.opendocument.spreadsheet": 40, // 40 MB
// "image/png": 100, // 100 MB
// "image/jpeg": 100, // 100 MB
// "image/jpg": 100, // 100 MB
// "video/mp4": 500, // 500 MB
// "video/quicktime": 500, // 500 MB
// "video/x-msvideo": 500, // 500 MB
// "video/webm": 500, // 500 MB
// "video/ogg": 500, // 500 MB
// };

export default function DocumentUpload({
currentFile,
Expand All @@ -36,11 +41,23 @@ export default function DocumentUpload({
const isLight =
theme === "light" || (theme === "system" && systemTheme === "light");
const { plan, trial } = usePlan();
const { limits } = useLimits();
const isFreePlan = plan === "free";
const isTrial = !!trial;
const maxSize = isFreePlan && !isTrial ? 30 : 100;
// const maxSize = isFreePlan && !isTrial ? 30 : 100;
const maxNumPages = isFreePlan && !isTrial ? 100 : 500;

// Get file size limits
const fileSizeLimits = useMemo(
() =>
getFileSizeLimits({
limits,
isFreePlan,
isTrial,
}),
[limits, isFreePlan, isTrial],
);

const { getRootProps, getInputProps } = useDropzone({
accept:
isFreePlan && !isTrial
Expand Down Expand Up @@ -90,11 +107,12 @@ export default function DocumentUpload({
onDropAccepted: (acceptedFiles) => {
const file = acceptedFiles[0];
const fileType = file.type;
const fileSizeLimit = (fileSizeLimits[fileType] || maxSize) * 1024 * 1024;
const fileSizeLimitMB = getFileSizeLimit(fileType, fileSizeLimits); // in MB
const fileSizeLimit = fileSizeLimitMB * 1024 * 1024; // in bytes

if (file.size > fileSizeLimit) {
toast.error(
`File size too big for ${fileType} (max. ${fileSizeLimits[fileType] || maxSize} MB)`,
`File size too big for ${fileType} (max. ${fileSizeLimitMB} MB)`,
);
return;
}
Expand Down Expand Up @@ -123,7 +141,8 @@ export default function DocumentUpload({
const { errors, file } = fileRejections[0];
let message;
if (errors[0].code === "file-too-large") {
message = `File size too big (max. ${maxSize} MB)${
const fileSizeLimitMB = getFileSizeLimit(file.type, fileSizeLimits);
message = `File size too big (max. ${fileSizeLimitMB} MB)${
isFreePlan && !isTrial
? `. Upgrade to a paid plan to increase the limit.`
: ""
Expand Down Expand Up @@ -192,8 +211,8 @@ export default function DocumentUpload({
{currentFile
? "Replace file?"
: isFreePlan && !isTrial
? `Only *.pdf, *.xls, *.xlsx, *.csv, *.ods, *.png, *.jpeg, *.jpg & ${maxSize} MB limit`
: `Only *.pdf, *.pptx, *.docx, *.xlsx, *.xls, *.xlsm, *.csv, *.ods, *.ppt, *.odp, *.doc, *.odt, *.dwg, *.dxf, *.png, *.jpg, *.jpeg & ${maxSize} MB limit`}
? `Only *.pdf, *.xls, *.xlsx, *.csv, *.ods, *.png, *.jpeg, *.jpg`
: `Only *.pdf, *.pptx, *.docx, *.xlsx, *.xls, *.xlsm, *.csv, *.ods, *.ppt, *.odp, *.doc, *.odt, *.dwg, *.dxf, *.png, *.jpg, *.jpeg, *.mp4, *.mov, *.avi, *.webm, *.ogg`}
</p>
</div>
</div>
Expand Down
128 changes: 88 additions & 40 deletions components/upload-zone.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useRouter } from "next/router";

import { useCallback, useRef, useState } from "react";
import { useCallback, useMemo, useRef, useState } from "react";

import { useTeam } from "@/context/team-context";
import { DocumentStorageType } from "@prisma/client";
Expand All @@ -18,6 +18,10 @@ import useLimits from "@/lib/swr/use-limits";
import { CustomUser } from "@/lib/types";
import { cn } from "@/lib/utils";
import { getSupportedContentType } from "@/lib/utils/get-content-type";
import {
getFileSizeLimit,
getFileSizeLimits,
} from "@/lib/utils/get-file-size-limits";
import { getPagesCount } from "@/lib/utils/get-page-number-count";

// Originally these mime values were directly used in the dropzone hook.
Expand Down Expand Up @@ -68,19 +72,19 @@ interface FileWithPaths extends File {
whereToUploadPath?: string;
}

const fileSizeLimits: { [key: string]: number } = {
"application/vnd.ms-excel": 40, // 40 MB
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": 40, // 40 MB
"application/vnd.oasis.opendocument.spreadsheet": 40, // 40 MB
"image/png": 100, // 100 MB
"image/jpeg": 100, // 100 MB
"image/jpg": 100, // 100 MB
"video/mp4": 500, // 500 MB
"video/quicktime": 500, // 500 MB
"video/x-msvideo": 500, // 500 MB
"video/webm": 500, // 500 MB
"video/ogg": 500, // 500 MB
};
// const fileSizeLimits: { [key: string]: number } = {
// "application/vnd.ms-excel": 40, // 40 MB
// "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": 40, // 40 MB
// "application/vnd.oasis.opendocument.spreadsheet": 40, // 40 MB
// "image/png": 100, // 100 MB
// "image/jpeg": 100, // 100 MB
// "image/jpg": 100, // 100 MB
// "video/mp4": 500, // 500 MB
// "video/quicktime": 500, // 500 MB
// "video/x-msvideo": 500, // 500 MB
// "video/webm": 500, // 500 MB
// "video/ogg": 500, // 500 MB
// };

export default function UploadZone({
children,
Expand Down Expand Up @@ -120,7 +124,7 @@ export default function UploadZone({
const { data: session } = useSession();
const isFreePlan = plan === "free";
const isTrial = !!trial;
const maxSize = isFreePlan && !isTrial ? 30 : 350;
// const maxSize = isFreePlan && !isTrial ? 30 : 350;
const maxNumPages = isFreePlan && !isTrial ? 100 : 500;
const { limits, canAddDocuments } = useLimits();
const remainingDocuments = limits?.documents
Expand All @@ -131,6 +135,16 @@ export default function UploadZone({
const [showProgress, setShowProgress] = useState(false);
const uploadProgress = useRef<number[]>([]);

const fileSizeLimits = useMemo(
() =>
getFileSizeLimits({
limits,
isFreePlan,
isTrial,
}),
[limits, isFreePlan, isTrial],
);

const acceptableDropZoneFileTypes =
isFreePlan && !isTrial
? acceptableDropZoneMimeTypesWhenIsFreePlanAndNotTrail
Expand All @@ -146,7 +160,8 @@ export default function UploadZone({
const rejected = rejectedFiles.map(({ file, errors }) => {
let message = "";
if (errors.find(({ code }) => code === "file-too-large")) {
message = `File size too big (max. ${maxSize} MB). Upgrade to a paid plan to increase the limit.`;
const fileSizeLimitMB = getFileSizeLimit(file.type, fileSizeLimits);
message = `File size too big (max. ${fileSizeLimitMB} MB). Upgrade to a paid plan to increase the limit.`;
} else if (errors.find(({ code }) => code === "file-invalid-type")) {
const isSupported = SUPPORTED_DOCUMENT_MIME_TYPES.includes(file.type);
message = `File type not supported ${
Expand All @@ -157,7 +172,7 @@ export default function UploadZone({
});
onUploadRejected(rejected);
},
[onUploadRejected, maxSize],
[onUploadRejected, fileSizeLimits, isFreePlan, isTrial],
);

const onDrop = useCallback(
Expand All @@ -166,13 +181,55 @@ export default function UploadZone({
toast.error("You have reached the maximum number of documents.");
return;
}
const newUploads = acceptedFiles.map((file) => ({

// Validate files and separate into valid and invalid
const validatedFiles = acceptedFiles.reduce<{
valid: FileWithPaths[];
invalid: { fileName: string; message: string }[];
}>(
(acc, file) => {
const fileSizeLimitMB = getFileSizeLimit(file.type, fileSizeLimits);
const fileSizeLimit = fileSizeLimitMB * 1024 * 1024; // Convert to bytes

if (file.size > fileSizeLimit) {
acc.invalid.push({
fileName: file.name,
message: `File size too big (max. ${fileSizeLimitMB} MB)${
isFreePlan && !isTrial
? ". Upgrade to a paid plan to increase the limit"
: ""
}`,
});
} else {
acc.valid.push(file);
}
return acc;
},
{ valid: [], invalid: [] },
);

// Handle rejected files first
if (validatedFiles.invalid.length > 0) {
setRejectedFiles((prev) => [...validatedFiles.invalid, ...prev]);

// If all files were rejected, show a summary toast
if (validatedFiles.valid.length === 0) {
toast.error(
`${validatedFiles.invalid.length} file(s) exceeded size limits`,
);
return;
}
}

// Continue with valid files
const newUploads = validatedFiles.valid.map((file) => ({
fileName: file.name,
progress: 0,
}));

onUploadStart(newUploads);

const uploadPromises = acceptedFiles.map(async (file, index) => {
const uploadPromises = validatedFiles.valid.map(async (file, index) => {
// Due to `getFilesFromEvent` file.path will always hold a valid value and represents the value of webkitRelativePath.
// We no longer need to use webkitRelativePath because everything is been handled in `getFilesFromEvent`
const path = file.path || file.name;
Expand All @@ -198,23 +255,6 @@ export default function UploadZone({
}
}

// check dynamic file size
const fileType = file.type;
const fileSizeLimit = fileSizeLimits[fileType] * 1024 * 1024;
if (file.size > fileSizeLimit) {
setUploads((prev) =>
prev.filter((upload) => upload.fileName !== file.name),
);

return setRejectedFiles((prev) => [
{
fileName: file.name,
message: `File size too big (max. ${fileSizeLimit} MB)`,
},
...prev,
]);
}

const { complete } = await resumableUpload({
file, // File
onProgress: (bytesUploaded, bytesTotal) => {
Expand Down Expand Up @@ -377,7 +417,14 @@ export default function UploadZone({
);
});
},
[onUploadStart, onUploadProgress, endpointTargetType],
[
onUploadStart,
onUploadProgress,
endpointTargetType,
fileSizeLimits,
isFreePlan,
isTrial,
],
);

const getFilesFromEvent = useCallback(
Expand Down Expand Up @@ -586,7 +633,8 @@ export default function UploadZone({
const { getRootProps, getInputProps, isDragActive } = useDropzone({
accept: acceptableDropZoneFileTypes,
multiple: true,
maxSize: maxSize * 1024 * 1024, // 30 MB
// maxSize: maxSize * 1024 * 1024, // 30 MB
maxFiles: 150,
onDrop,
onDropRejected,
getFilesFromEvent,
Expand Down Expand Up @@ -620,8 +668,8 @@ export default function UploadZone({
<span className="mx-auto">Drop your file(s) to upload here</span>
<p className="text-xs leading-5 text-gray-800">
{isFreePlan && !isTrial
? `Only *.pdf, *.xls, *.xlsx, *.csv, *.ods, *.png, *.jpeg, *.jpg & ${maxSize} MB limit`
: `Only *.pdf, *.pptx, *.docx, *.xlsx, *.xls, *.csv, *.ods, *.ppt, *.odp, *.doc, *.odt, *.dwg, *.dxf, *.png, *.jpg, *.jpeg & ${maxSize} MB limit`}
? `Only *.pdf, *.xls, *.xlsx, *.csv, *.ods, *.png, *.jpeg, *.jpg`
: `Only *.pdf, *.pptx, *.docx, *.xlsx, *.xls, *.csv, *.ods, *.ppt, *.odp, *.doc, *.odt, *.dwg, *.dxf, *.png, *.jpg, *.jpeg, *.mp4, *.mov, *.avi, *.webm, *.ogg`}
</p>
</div>
</div>
Expand Down
8 changes: 8 additions & 0 deletions ee/limits/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ const configSchema = z.object({
customDomainInDataroom: z.boolean(),
advancedLinkControlsOnPro: z.boolean().nullish(),
watermarkOnBusiness: z.boolean().nullish(),
fileSizeLimits: z
.object({
video: z.number().optional(), // in MB
document: z.number().optional(), // in MB
image: z.number().optional(), // in MB
excel: z.number().optional(), // in MB
})
.optional(),
});

export async function getLimits({
Expand Down
8 changes: 8 additions & 0 deletions ee/limits/swr-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ export type LimitProps = {
documents: number;
links: number;
};
fileSizeLimits:
| {
video: number | undefined;
document: number | undefined;
image: number | undefined;
excel: number | undefined;
}
| undefined;
};

export function useLimits() {
Expand Down
Loading