chore: cleanup multiple uses of FileReader (#3110)

from
https://discord.com/channels/859816885297741824/1006133967642177556/1213038401465618433

### Change Type

- [x] `patch` — Bug fix
This commit is contained in:
Mime Čuvalo 2024-03-12 09:10:18 +00:00 committed by GitHub
parent 60cc0dcce3
commit dba6d4c414
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 14 additions and 52 deletions

View file

@ -1,6 +1,7 @@
/* eslint-disable react-hooks/rules-of-hooks */
import {
BaseBoxShapeUtil,
FileHelpers,
HTMLContainer,
TLImageShape,
TLOnDoubleClickHandler,
@ -19,12 +20,7 @@ import { usePrefersReducedMotion } from '../shared/usePrefersReducedMotion'
async function getDataURIFromURL(url: string): Promise<string> {
const response = await fetch(url)
const blob = await response.blob()
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onloadend = () => resolve(reader.result as string)
reader.onerror = reject
reader.readAsDataURL(blob)
})
return FileHelpers.fileToBase64(blob)
}
/** @public */

View file

@ -2,6 +2,7 @@ import {
DefaultColorThemePalette,
DefaultFontFamilies,
DefaultFontStyle,
FileHelpers,
HASH_PATTERN_ZOOM_NAMES,
MAX_ZOOM,
SvgExportDef,
@ -27,12 +28,7 @@ export function getFontDefForExport(fontStyle: TLDefaultFontStyle): SvgExportDef
if (!url || !fontFaceRule) return null
const fontFile = await (await fetch(url)).blob()
const base64FontFile = await new Promise<string>((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => resolve(reader.result as string)
reader.onerror = reject
reader.readAsDataURL(fontFile)
})
const base64FontFile = FileHelpers.fileToBase64(fontFile)
const newFontFaceRule = fontFaceRule.replace(url, base64FontFile)
const style = document.createElementNS('http://www.w3.org/2000/svg', 'style')

View file

@ -1,5 +1,6 @@
import {
Editor,
FileHelpers,
TLArrowShape,
TLBookmarkShape,
TLEmbedShape,
@ -81,26 +82,6 @@ function disallowClipboardEvents(editor: Editor) {
)
}
/**
* Get a blob as a string.
*
* @param blob - The blob to get as a string.
* @internal
*/
async function blobAsString(blob: Blob) {
return new Promise<string>((resolve, reject) => {
const reader = new FileReader()
reader.addEventListener('loadend', () => {
const text = reader.result
resolve(text as string)
})
reader.addEventListener('error', () => {
reject(reader.error)
})
reader.readAsText(blob)
})
}
/**
* Whether a ClipboardItem is a file.
* @param item - The ClipboardItem to check.
@ -270,7 +251,7 @@ const handlePasteFromClipboardApi = async (
things.push({
type: 'html',
source: new Promise<string>((r) =>
item.getType('text/html').then((blob) => blobAsString(blob).then(r))
item.getType('text/html').then((blob) => FileHelpers.fileToBase64(blob).then(r))
),
})
}
@ -279,7 +260,7 @@ const handlePasteFromClipboardApi = async (
things.push({
type: 'url',
source: new Promise<string>((r) =>
item.getType('text/uri-list').then((blob) => blobAsString(blob).then(r))
item.getType('text/uri-list').then((blob) => FileHelpers.fileToBase64(blob).then(r))
),
})
}
@ -288,7 +269,7 @@ const handlePasteFromClipboardApi = async (
things.push({
type: 'text',
source: new Promise<string>((r) =>
item.getType('text/plain').then((blob) => blobAsString(blob).then(r))
item.getType('text/plain').then((blob) => FileHelpers.fileToBase64(blob).then(r))
),
})
}

View file

@ -1,5 +1,6 @@
import {
Editor,
FileHelpers,
PngHelpers,
TLShapeId,
TLSvgOptions,
@ -98,7 +99,6 @@ export async function getSvgAsString(svg: SVGElement) {
svg.setAttribute('width', +svg.getAttribute('width')! + '')
svg.setAttribute('height', +svg.getAttribute('height')! + '')
const fileReader = new FileReader()
const imgs = Array.from(clone.querySelectorAll('image')) as SVGImageElement[]
for (const img of imgs) {
@ -106,11 +106,7 @@ export async function getSvgAsString(svg: SVGElement) {
if (src) {
if (!src.startsWith('data:')) {
const blob = await (await fetch(src)).blob()
const base64 = await new Promise<string>((resolve, reject) => {
fileReader.onload = () => resolve(fileReader.result as string)
fileReader.onerror = () => reject(fileReader.error)
fileReader.readAsDataURL(blob)
})
const base64 = await FileHelpers.fileToBase64(blob)
img.setAttribute('xlink:href', base64)
}
}

View file

@ -32,10 +32,10 @@ export class FileHelpers {
return await new Promise((resolve, reject) => {
if (file) {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result as string)
reader.onerror = (error) => reject(error)
reader.onabort = (error) => reject(error)
reader.readAsDataURL(file)
}
})
}

View file

@ -1,3 +1,4 @@
import { FileHelpers } from './file'
import { PngHelpers } from './png'
/**
@ -44,16 +45,8 @@ export class MediaHelpers {
* Read a blob into a data url
* @public
*/
static blobToDataUrl(blob: Blob): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => resolve(reader.result as string)
reader.onerror = (e) => {
console.error(e)
reject(new Error('Could not read blob'))
}
reader.readAsDataURL(blob)
})
static blobToDataUrl(blob: Blob) {
return FileHelpers.fileToBase64(blob)
}
/**