mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-13 06:36:49 -05:00
Add error message to user if trying to upload too big image
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import type { FileUpload } from "@remix-run/form-data-parser";
|
import type { FileUpload } from "@remix-run/form-data-parser";
|
||||||
import { parseFormData as parseMultipartFormData } from "@remix-run/form-data-parser";
|
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import type { ActionFunction } from "react-router";
|
import type { ActionFunction } from "react-router";
|
||||||
import { redirect } from "react-router";
|
import { redirect } from "react-router";
|
||||||
@@ -14,6 +13,7 @@ import {
|
|||||||
errorToastIfFalsy,
|
errorToastIfFalsy,
|
||||||
parseFormData,
|
parseFormData,
|
||||||
parseRequestPayload,
|
parseRequestPayload,
|
||||||
|
safeParseMultipartFormData,
|
||||||
} from "~/utils/remix.server";
|
} from "~/utils/remix.server";
|
||||||
import { userArtPage } from "~/utils/urls";
|
import { userArtPage } from "~/utils/urls";
|
||||||
import { NEW_ART_EXISTING_SEARCH_PARAM_KEY } from "../art-constants";
|
import { NEW_ART_EXISTING_SEARCH_PARAM_KEY } from "../art-constants";
|
||||||
@@ -86,7 +86,7 @@ export const action: ActionFunction = async ({ request }) => {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const formData = await parseMultipartFormData(
|
const formData = await safeParseMultipartFormData(
|
||||||
request,
|
request,
|
||||||
// 5MB
|
// 5MB
|
||||||
{ maxFileSize: 5 * 1024 * 1024 },
|
{ maxFileSize: 5 * 1024 * 1024 },
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import type { FileUpload } from "@remix-run/form-data-parser";
|
import type { FileUpload } from "@remix-run/form-data-parser";
|
||||||
import { parseFormData } from "@remix-run/form-data-parser";
|
|
||||||
import type { ActionFunctionArgs } from "react-router";
|
import type { ActionFunctionArgs } from "react-router";
|
||||||
import { redirect } from "react-router";
|
import { redirect } from "react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -14,6 +13,7 @@ import {
|
|||||||
badRequestIfFalsy,
|
badRequestIfFalsy,
|
||||||
errorToastIfFalsy,
|
errorToastIfFalsy,
|
||||||
parseSearchParams,
|
parseSearchParams,
|
||||||
|
safeParseMultipartFormData,
|
||||||
} from "~/utils/remix.server";
|
} from "~/utils/remix.server";
|
||||||
import { teamPage, tournamentOrganizationPage } from "~/utils/urls";
|
import { teamPage, tournamentOrganizationPage } from "~/utils/urls";
|
||||||
import * as ImageRepository from "../ImageRepository.server";
|
import * as ImageRepository from "../ImageRepository.server";
|
||||||
@@ -57,7 +57,7 @@ export const action = async ({ request }: ActionFunctionArgs) => {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const formData = await parseFormData(request, uploadHandler);
|
const formData = await safeParseMultipartFormData(request, uploadHandler);
|
||||||
const imgSrc = formData.get("img") as string | null;
|
const imgSrc = formData.get("img") as string | null;
|
||||||
invariant(imgSrc);
|
invariant(imgSrc);
|
||||||
|
|
||||||
|
|||||||
@@ -291,6 +291,50 @@ export function privatelyCachedJson<T>(dataValue: T) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024;
|
||||||
|
|
||||||
|
type FileUploadHandler = (
|
||||||
|
fileUpload: FileUpload,
|
||||||
|
) => Promise<string | null | undefined>;
|
||||||
|
type ParseFormDataOptions = { maxFileSize?: number };
|
||||||
|
|
||||||
|
export function safeParseMultipartFormData(
|
||||||
|
request: Request,
|
||||||
|
uploadHandler?: FileUploadHandler,
|
||||||
|
): Promise<FormData>;
|
||||||
|
export function safeParseMultipartFormData(
|
||||||
|
request: Request,
|
||||||
|
options?: ParseFormDataOptions,
|
||||||
|
uploadHandler?: FileUploadHandler,
|
||||||
|
): Promise<FormData>;
|
||||||
|
export async function safeParseMultipartFormData(
|
||||||
|
request: Request,
|
||||||
|
optionsOrHandler?: ParseFormDataOptions | FileUploadHandler,
|
||||||
|
uploadHandler?: FileUploadHandler,
|
||||||
|
): Promise<FormData> {
|
||||||
|
try {
|
||||||
|
if (typeof optionsOrHandler === "function") {
|
||||||
|
return await parseMultipartFormData(request, optionsOrHandler);
|
||||||
|
}
|
||||||
|
return await parseMultipartFormData(
|
||||||
|
request,
|
||||||
|
optionsOrHandler,
|
||||||
|
uploadHandler,
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
if (
|
||||||
|
err instanceof Error &&
|
||||||
|
err.cause instanceof Error &&
|
||||||
|
err.cause.name === "MaxFileSizeExceededError"
|
||||||
|
) {
|
||||||
|
throw errorToastRedirect(
|
||||||
|
`File size exceeds maximum allowed size of ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function uploadImageIfSubmitted({
|
export async function uploadImageIfSubmitted({
|
||||||
request,
|
request,
|
||||||
fileNamePrefix,
|
fileNamePrefix,
|
||||||
@@ -318,7 +362,7 @@ export async function uploadImageIfSubmitted({
|
|||||||
let formData: FormData;
|
let formData: FormData;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
formData = await parseMultipartFormData(request, uploadHandler);
|
formData = await safeParseMultipartFormData(request, uploadHandler);
|
||||||
const imgSrc = formData.get("img") as string | null;
|
const imgSrc = formData.get("img") as string | null;
|
||||||
if (!imgSrc) {
|
if (!imgSrc) {
|
||||||
throw new TypeError("No image submitted");
|
throw new TypeError("No image submitted");
|
||||||
|
|||||||
Reference in New Issue
Block a user