Skip to content

Commit

Permalink
Merge pull request #124 from raid-guild/minor/96-reduce-size-of-ipfs-…
Browse files Browse the repository at this point in the history
…images

Handle IPFS images better
  • Loading branch information
ECWireless authored Jan 5, 2024
2 parents f9b1a07 + 1c52b4d commit 8a9c84a
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 56 deletions.
2 changes: 1 addition & 1 deletion hooks/useUploadFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const useUploadFile = ({
try {
setIsUploading(true);
const formData = new FormData();
formData.set(file.name, file);
formData.set(fileName, file);

const response = await fetch(`/api/uploadFile?name=${fileName}`, {
method: 'POST',
Expand Down
68 changes: 20 additions & 48 deletions pages/api/uploadFile.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import formidable from 'formidable';
import Jimp from 'jimp';
import type { NextApiRequest, NextApiResponse, PageConfig } from 'next';
import { Writable } from 'stream';
import { File } from 'web3.storage';

import { uploadToWeb3Storage } from '@/lib/fileStorage';
Expand All @@ -11,40 +11,10 @@ export const config: PageConfig = {
},
};

const formidableConfig = {
keepExtensions: true,
maxFileSize: 1_000_000,
maxFieldsSize: 1_000_000,
maxFields: 2,
allowEmptyFiles: false,
multiples: false,
};

const formidablePromise = (
req: NextApiRequest,
opts?: Parameters<typeof formidable>[0],
): Promise<{ fields: formidable.Fields; files: formidable.Files }> => {
return new Promise((accept, reject) => {
const form = formidable(opts);

form.parse(req, (err, fields, files) => {
if (err) {
return reject(err);
}
return accept({ fields, files });
});
});
};

const fileConsumer = <T = unknown>(acc: T[]) => {
const writable = new Writable({
write: (chunk, _enc, next) => {
acc.push(chunk);
next();
},
});

return writable;
type FormFile = {
_writeStream: {
path: string;
};
};

type ResponseData = {
Expand All @@ -57,24 +27,26 @@ export default async function uploadFile(
res: NextApiResponse<ResponseData>,
) {
const fileName = req.query.name as string;
const chunks: never[] = [];
const form = formidable({});

try {
const { files } = await formidablePromise(req, {
...formidableConfig,
// consume this, otherwise formidable tries to save the file to disk
fileWriteStreamHandler: () => fileConsumer(chunks),
});

const fileExtension = Object.keys(files)[0].split('.').pop();
const fileContents = Buffer.concat(chunks);
const file = new File([fileContents], `${fileName}.${fileExtension}`);

const [, files] = await form.parse(req);
const formFile = files[fileName] as [FormFile] | undefined;

if (!formFile) {
return res.status(400).json({ error: 'No file provided' });
}

const image = await Jimp.read(formFile[0]._writeStream.path);
const fileContents = await image
.resize(700, Jimp.AUTO)
.getBufferAsync(Jimp.MIME_PNG);
const file = new File([fileContents], `${fileName}.png`);
const cid = await uploadToWeb3Storage(file);

res.status(200).json({ cid });
return res.status(200).json({ cid });
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Something went wrong' });
return res.status(500).json({ error: 'Something went wrong' });
}
}
7 changes: 5 additions & 2 deletions pages/api/uploadTraits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,12 @@ export default async function uploadTraits(
return acc.composite(image, 0, 0);
});

const fileContents = await imageComposite.getBufferAsync(Jimp.MIME_PNG);
const fileContents = await imageComposite
.quality(85)
.resize(700, Jimp.AUTO)
.getBufferAsync(Jimp.MIME_JPEG);

const file = new File([fileContents], 'characterAvater.png');
const file = new File([fileContents], 'characterAvater.jpg');

const attributes = getAttributesFromTraitsObject(traits);
const cid = await uploadToWeb3Storage(file);
Expand Down
11 changes: 6 additions & 5 deletions utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ItemInfoFragment,
ItemRequirementInfoFragment,
} from '@/graphql/autogen/types';
import { ENVIRONMENT } from '@/utils/constants';

import {
Character,
Expand All @@ -18,11 +19,11 @@ import {
Metadata,
} from './types';

const IPFS_GATEWAYS = [
'https://character-sheets.infura-ipfs.io',
'https://cloudflare-ipfs.com',
'https://ipfs.io',
];
const IPFS_GATEWAYS = ['https://cloudflare-ipfs.com', 'https://ipfs.io'];

if (ENVIRONMENT === 'main') {
IPFS_GATEWAYS.unshift('https://character-sheets.infura-ipfs.io');
}

/**
* Given a URI that may be ipfs, ipns, http, https, ar, or data protocol, return the fetch-able http(s) URLs for the same content
Expand Down

0 comments on commit 8a9c84a

Please sign in to comment.