Skip to content

Commit

Permalink
Replace any data URL images with uploaded IDs on sync DL
Browse files Browse the repository at this point in the history
- see in line comments
  • Loading branch information
poltak committed Apr 4, 2024
1 parent 3acbcf5 commit d76320c
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
8 changes: 3 additions & 5 deletions src/image-support/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export class ImageSupportBackground {
throw new Error(`Failed to initialize image support storage`)
}
this.remoteFunctions = {
generateImageId: remoteFunctionWithoutExtraArgs(
this.generateImageId,
generateImageId: remoteFunctionWithoutExtraArgs(async () =>
this.generateImageId(),
),
uploadImage: remoteFunctionWithoutExtraArgs(this.uploadImage),
getImageUrl: remoteFunctionWithoutExtraArgs(this.getImageUrl),
Expand All @@ -40,9 +40,7 @@ export class ImageSupportBackground {
registerRemoteFunctions(this.remoteFunctions)
}

generateImageId: ImageSupportInterface<
'provider'
>['generateImageId']['function'] = async () => {
generateImageId = () => {
return this.options.generateImageId()
}

Expand Down
57 changes: 57 additions & 0 deletions src/personal-cloud/background/handle-incoming-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { normalizeUrl } from '@worldbrain/memex-common/lib/url-utils/normalize'
import type { ImageSupportBackground } from 'src/image-support/background'
import type { Browser } from 'webextension-polyfill'
import type { Annotation } from '@worldbrain/memex-common/lib/types/core-data-types/client'

interface IncomingDataInfo {
storageType: PersonalCloudClientStorageType
Expand Down Expand Up @@ -42,6 +43,14 @@ export const handleIncomingData = (deps: {
? deps.persistentStorageManager
: deps.storageManager

if (collection === 'annotations') {
// TODO: do something with these promises, but don't hold up sync
const uploadPromises = maybeReplaceAnnotCommentImages(
updates as Annotation,
deps.imageSupportBG,
)
}

// Add any newly created lists to the list suggestion cache
if (collection === 'customLists' && updates.id != null) {
const existingList = await deps.storageManager.backend.operation(
Expand Down Expand Up @@ -351,3 +360,51 @@ async function handleSyncedDataForPKMSync(
console.error(e)
}
}

// We had a bug where annotation comments contained data URLs for big images, which blows up the extension on storage ops.
// This makes sure they get uploaded and replaced with links.
function maybeReplaceAnnotCommentImages(
annotation: Pick<Annotation, 'comment' | 'url' | 'pageUrl'>,
imageSupportBG: ImageSupportBackground,
): Promise<void>[] {
// Should match the data URL part of a markdown string containing something like this: "![alt text](data:image/png;base64,asdafasf)"
const dataUrlExtractRegexp = /!\[[\w|\s|\.|\!|\-|\?|=]*\]\((data:image\/(png|jpeg);base64,[\w|\+|\/|=]+)\)/g
// Most comments should exit here
if (!dataUrlExtractRegexp.test(annotation.comment)) {
return []
}

const matches = annotation.comment.matchAll(dataUrlExtractRegexp)
const dataUrlToImageId = new Map<string, string>()
const imageUploadPromises: Promise<void>[] = []
// For each found data URL, upload it and generate an ID
for (const matchRes of matches) {
const dataUrl = matchRes?.[1]
if (!dataUrl) {
continue
}
const imageId = imageSupportBG.generateImageId()
imageUploadPromises.push(
imageSupportBG.uploadImage({
id: imageId,
image: dataUrl,
annotationUrl: annotation.url,
normalizedPageUrl: annotation.pageUrl,
}),
)
dataUrlToImageId.set(dataUrl, imageId)
}
// Replace all markdown data URL image links with HTML ones using the generated ID
annotation.comment = annotation.comment.replace(
dataUrlExtractRegexp,
(_, dataUrl) => {
if (!dataUrl) {
return '' // Wipe it out if this match fails
}
const imageId = dataUrlToImageId.get(dataUrl)
return `<img src="${imageId}" remoteid="${imageId}"/>`
},
)

return imageUploadPromises
}

0 comments on commit d76320c

Please sign in to comment.