Skip to content

Instantly share code, notes, and snippets.

@PBillingsby
Created February 24, 2023 00:40
Show Gist options
  • Select an option

  • Save PBillingsby/c042d4db7d4e6967c5b13d20f9350c00 to your computer and use it in GitHub Desktop.

Select an option

Save PBillingsby/c042d4db7d4e6967c5b13d20f9350c00 to your computer and use it in GitHub Desktop.
import { Async, AsyncReader } from "./utils.js";
const { of, ask, lift } = AsyncReader;
/**
* @param {File} file
* @param {string} mimeType
* @returns { AsyncReader }
*/
export function uploadAvatar(file, mimeType) {
const compressedFile = compressAndResizeImage(file);
// convert file to Uint8Array
return of(compressedFile)
.chain((f) =>
ask(({ toArrayBuffer, dispatch }) =>
toArrayBuffer(f)
// check if file is < 100kb
.chain((data) =>
data.byteLength > 100000
? Async.Rejected({ message: "File too big!" })
: Async.Resolved(data)
)
// dispatch
.chain((data) =>
dispatch({
data,
tags: [{ name: "Content-Type", value: mimeType }]
})
)
)
)
.chain(lift);
}
function compressAndResizeImage(file) {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (event) => {
const img = new Image();
img.src = event.target.result.toString();
img.onload = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
// @ts-ignore
ctx.webkitImageSmoothingEnabled = false;
// @ts-ignore
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
const width = 300;
const height = 300;
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob(
(blob) => {
const compressedFile = new File([blob], file.name, {
type: file.type,
lastModified: Date.now(),
});
const sizeKB = Math.round(blob.size / 1024);
console.log(`Image size: ${sizeKB} KB`);
const compressedImg = new Image();
compressedImg.src = URL.createObjectURL(compressedFile);
return compressedImg;
},
file.type,
0.6
);
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment