Handle inline images and attachments via data urls
This commit is contained in:
parent
0365673c41
commit
8dac58f38a
@ -185,6 +185,12 @@ export class Space extends EventEmitter<SpaceEvents> {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an attachment
|
||||
* @param name path of the attachment
|
||||
* @param encoding how the return value is expected to be encoded
|
||||
* @returns
|
||||
*/
|
||||
readAttachment(
|
||||
name: string,
|
||||
encoding: FileEncoding,
|
||||
|
@ -78,10 +78,10 @@ export class CapacitorSpacePrimitives implements SpacePrimitives {
|
||||
}
|
||||
}
|
||||
return {
|
||||
data,
|
||||
data: data!,
|
||||
meta: await this.getFileMeta(name),
|
||||
};
|
||||
} catch (e: any) {
|
||||
} catch {
|
||||
throw new Error(`Page not found`);
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,11 @@ export function openUrl(url: string): Promise<void> {
|
||||
return syscall("editor.openUrl", url);
|
||||
}
|
||||
|
||||
// Force the client to download the file in dataUrl with filename as file name
|
||||
export function downloadFile(filename: string, dataUrl: string): Promise<void> {
|
||||
return syscall("editor.downloadFile", filename, dataUrl);
|
||||
}
|
||||
|
||||
export function flashNotification(
|
||||
message: string,
|
||||
type: "info" | "error" = "info",
|
||||
|
@ -35,12 +35,24 @@ export function getAttachmentMeta(name: string): Promise<AttachmentMeta> {
|
||||
return syscall("space.getAttachmentMeta", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an attachment from the space
|
||||
* @param name path of the attachment to read
|
||||
* @returns the attachment data encoded as a data URL
|
||||
*/
|
||||
export function readAttachment(
|
||||
name: string,
|
||||
): Promise<string> {
|
||||
return syscall("space.readAttachment", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an attachment to the space
|
||||
* @param name path of the attachment to write
|
||||
* @param encoding encoding of the data ("string" or "dataurl)
|
||||
* @param data data itself
|
||||
* @returns
|
||||
*/
|
||||
export function writeAttachment(
|
||||
name: string,
|
||||
encoding: "string" | "dataurl",
|
||||
@ -49,6 +61,10 @@ export function writeAttachment(
|
||||
return syscall("space.writeAttachment", name, encoding, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an attachment from the space
|
||||
* @param name path of the attachment to delete
|
||||
*/
|
||||
export function deleteAttachment(name: string): Promise<void> {
|
||||
return syscall("space.deleteAttachment", name);
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
import type { ClickEvent } from "$sb/app_event.ts";
|
||||
import { editor, markdown, system } from "$sb/silverbullet-syscall/mod.ts";
|
||||
import {
|
||||
editor,
|
||||
markdown,
|
||||
space,
|
||||
system,
|
||||
} from "$sb/silverbullet-syscall/mod.ts";
|
||||
import {
|
||||
addParentPointers,
|
||||
findNodeOfType,
|
||||
@ -8,14 +13,6 @@ import {
|
||||
ParseTree,
|
||||
} from "$sb/lib/tree.ts";
|
||||
|
||||
// Checks if the URL contains a protocol, if so keeps it, otherwise assumes an attachment
|
||||
function patchUrl(url: string): string {
|
||||
if (url.indexOf("://") === -1) {
|
||||
return `fs/${url}`;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
async function actionClickOrActionEnter(
|
||||
mdTree: ParseTree | null,
|
||||
inNewWindow = false,
|
||||
@ -71,7 +68,7 @@ async function actionClickOrActionEnter(
|
||||
break;
|
||||
}
|
||||
case "NakedURL":
|
||||
await editor.openUrl(patchUrl(mdTree.children![0].text!));
|
||||
await editor.openUrl(mdTree.children![0].text!);
|
||||
break;
|
||||
case "Image":
|
||||
case "Link": {
|
||||
@ -79,11 +76,18 @@ async function actionClickOrActionEnter(
|
||||
if (!urlNode) {
|
||||
return;
|
||||
}
|
||||
const url = patchUrl(urlNode.children![0].text!);
|
||||
let url = urlNode.children![0].text!;
|
||||
if (url.length <= 1) {
|
||||
return editor.flashNotification("Empty link, ignoring", "error");
|
||||
}
|
||||
await editor.openUrl(url);
|
||||
if (url.indexOf("://") === -1) {
|
||||
url = decodeURIComponent(url);
|
||||
// attachment URL, let's fetch as a data url
|
||||
const dataUrl = await space.readAttachment(url);
|
||||
return editor.downloadFile(url, dataUrl);
|
||||
} else {
|
||||
await editor.openUrl(url);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CommandLink": {
|
||||
|
@ -27,8 +27,8 @@ class InlineImageWidget extends WidgetType {
|
||||
if (this.url.startsWith("http")) {
|
||||
img.src = this.url;
|
||||
} else {
|
||||
// Specific to mobile
|
||||
this.space.readAttachment(decodeURI(this.url), "dataurl").then(
|
||||
// Load the image as a dataURL and inject it into the img's src attribute
|
||||
this.space.readAttachment(decodeURIComponent(this.url), "dataurl").then(
|
||||
({ data }) => {
|
||||
img.src = data as string;
|
||||
},
|
||||
|
@ -38,6 +38,12 @@ export function editorSyscalls(editor: Editor): SysCallMapping {
|
||||
win.focus();
|
||||
}
|
||||
},
|
||||
"editor.downloadFile": (_ctx, filename: string, dataUrl: string) => {
|
||||
const link = document.createElement("a");
|
||||
link.href = dataUrl;
|
||||
link.download = filename;
|
||||
link.click();
|
||||
},
|
||||
"editor.flashNotification": (
|
||||
_ctx,
|
||||
message: string,
|
||||
|
Loading…
Reference in New Issue
Block a user