fix: Banner uploader fix error handling and reduce image size jump (#21903)
* improve uploader * better error handling * unnecessary check * more adjustments * remove logs
This commit is contained in:
@@ -3253,5 +3253,6 @@
|
||||
"booker_limit_exceeded_error_reschedule": "You already have a booking for this event on {{date}}. Would you like to reschedule to the new selected time?",
|
||||
"duration_min_error": "Duration must be at least {{min}} minute(s)",
|
||||
"duration_max_error": "Duration cannot exceed {{max}} minutes (24 hours)",
|
||||
"converted_image_size_limit_exceed": "Image size limit exceeded, please use a smaller image preferably in JPEG format",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -183,6 +183,11 @@ const OrgProfileForm = ({ defaultValues }: { defaultValues: FormValues }) => {
|
||||
|
||||
const mutation = trpc.viewer.organizations.update.useMutation({
|
||||
onError: (err) => {
|
||||
// Handle JSON parsing errors from body size limit exceeded
|
||||
if (err.message.includes("Unexpected token") && err.message.includes("Body excee")) {
|
||||
showToast(t("converted_image_size_limit_exceed"), "error");
|
||||
return;
|
||||
}
|
||||
showToast(err.message, "error");
|
||||
},
|
||||
onSuccess: async (res) => {
|
||||
|
||||
@@ -161,7 +161,12 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
|
||||
metadata: mergeMetadata({ ...input.metadata }),
|
||||
};
|
||||
|
||||
if (input.banner && input.banner.startsWith("data:image/png;base64,")) {
|
||||
if (
|
||||
input.banner &&
|
||||
(input.banner.startsWith("data:image/png;base64,") ||
|
||||
input.banner.startsWith("data:image/jpeg;base64,") ||
|
||||
input.banner.startsWith("data:image/jpg;base64,"))
|
||||
) {
|
||||
const banner = await resizeBase64Image(input.banner, { maxSize: 1500 });
|
||||
data.bannerUrl = await uploadLogo({
|
||||
logo: banner,
|
||||
@@ -172,7 +177,12 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
|
||||
data.bannerUrl = null;
|
||||
}
|
||||
|
||||
if (input.logoUrl && input.logoUrl.startsWith("data:image/png;base64,")) {
|
||||
if (
|
||||
input.logoUrl &&
|
||||
(input.logoUrl.startsWith("data:image/png;base64,") ||
|
||||
input.logoUrl.startsWith("data:image/jpeg;base64,") ||
|
||||
input.logoUrl.startsWith("data:image/jpg;base64,"))
|
||||
) {
|
||||
data.logoUrl = await uploadLogo({
|
||||
logo: await resizeBase64Image(input.logoUrl),
|
||||
teamId: currentOrgId,
|
||||
|
||||
@@ -209,6 +209,12 @@ async function getCroppedImg(
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (!ctx) throw new Error("Context is null, this should never happen.");
|
||||
|
||||
// Detect original image format from data URL
|
||||
const originalFormat =
|
||||
imageSrc.startsWith("data:image/jpeg") || imageSrc.startsWith("data:image/jpg")
|
||||
? "image/jpeg"
|
||||
: "image/png";
|
||||
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
@@ -224,5 +230,6 @@ async function getCroppedImg(
|
||||
canvas.height
|
||||
);
|
||||
|
||||
return canvas.toDataURL("image/png");
|
||||
// Use original format with quality setting for JPEG
|
||||
return canvas.toDataURL(originalFormat, originalFormat === "image/jpeg" ? 0.6 : undefined);
|
||||
}
|
||||
|
||||
@@ -192,6 +192,12 @@ async function getCroppedImg(imageSrc: string, pixelCrop: Area): Promise<string>
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (!ctx) throw new Error("Context is null, this should never happen.");
|
||||
|
||||
// Detect original image format from data URL
|
||||
const originalFormat =
|
||||
imageSrc.startsWith("data:image/jpeg") || imageSrc.startsWith("data:image/jpg")
|
||||
? "image/jpeg"
|
||||
: "image/png";
|
||||
|
||||
const maxSize = Math.max(image.naturalWidth, image.naturalHeight);
|
||||
const resizeRatio = MAX_IMAGE_SIZE / maxSize < 1 ? Math.max(MAX_IMAGE_SIZE / maxSize, 0.75) : 1;
|
||||
|
||||
@@ -216,7 +222,7 @@ async function getCroppedImg(imageSrc: string, pixelCrop: Area): Promise<string>
|
||||
// on very low ratios, the quality of the resize becomes awful. For this reason the resizeRatio is limited to 0.75
|
||||
if (resizeRatio <= 0.75) {
|
||||
// With a smaller image, thus improved ratio. Keep doing this until the resizeRatio > 0.75.
|
||||
return getCroppedImg(canvas.toDataURL("image/png"), {
|
||||
return getCroppedImg(canvas.toDataURL(originalFormat), {
|
||||
width: canvas.width,
|
||||
height: canvas.height,
|
||||
x: 0,
|
||||
@@ -224,5 +230,6 @@ async function getCroppedImg(imageSrc: string, pixelCrop: Area): Promise<string>
|
||||
});
|
||||
}
|
||||
|
||||
return canvas.toDataURL("image/png");
|
||||
// Use original format with quality setting for JPEG
|
||||
return canvas.toDataURL(originalFormat, originalFormat === "image/jpeg" ? 0.9 : undefined);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user