Desktop: Unify save file handling and add file dialog for export (#3008)

* Prepare save file unification

* Desktop add save file dialog
This commit is contained in:
Timon
2025-08-06 16:07:53 +00:00
committed by GitHub
parent 5f2432cacf
commit 96a1b12a05
8 changed files with 47 additions and 30 deletions
+7 -7
View File
@@ -798,10 +798,10 @@ export class TriggerSaveDocument extends JsMessage {
readonly path!: string | undefined;
readonly document!: string;
readonly content!: Uint8Array;
}
export class TriggerDownloadImage extends JsMessage {
export class TriggerExportImage extends JsMessage {
readonly svg!: string;
readonly name!: string;
@@ -812,10 +812,10 @@ export class TriggerDownloadImage extends JsMessage {
readonly size!: XY;
}
export class TriggerDownloadTextFile extends JsMessage {
readonly document!: string;
export class TriggerSaveFile extends JsMessage {
readonly name!: string;
readonly content!: Uint8Array;
}
export class TriggerSavePreferences extends JsMessage {
@@ -1658,8 +1658,8 @@ export const messageMakers: Record<string, MessageMaker> = {
SendUIMetadata,
TriggerAboutGraphiteLocalizedCommitDate,
TriggerSaveDocument,
TriggerDownloadImage,
TriggerDownloadTextFile,
TriggerSaveFile,
TriggerExportImage,
TriggerFetchAndOpenDocument,
TriggerFontLoad,
TriggerImport,
+8 -8
View File
@@ -7,8 +7,8 @@ import {
type FrontendDocumentDetails,
TriggerFetchAndOpenDocument,
TriggerSaveDocument,
TriggerDownloadImage,
TriggerDownloadTextFile,
TriggerExportImage,
TriggerSaveFile,
TriggerImport,
TriggerOpenDocument,
UpdateActiveDocument,
@@ -18,7 +18,7 @@ import {
patchWidgetLayout,
UpdateSpreadsheetLayout,
} from "@graphite/messages";
import { downloadFileText, downloadFileBlob, upload } from "@graphite/utility-functions/files";
import { downloadFile, downloadFileBlob, upload } from "@graphite/utility-functions/files";
import { extractPixelData, rasterizeSVG } from "@graphite/utility-functions/rasterization";
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
@@ -86,13 +86,13 @@ export function createPortfolioState(editor: Editor) {
editor.handle.pasteImage(data.filename, new Uint8Array(imageData.data), imageData.width, imageData.height);
});
editor.subscriptions.subscribeJsMessage(TriggerSaveDocument, (triggerSaveDocument) => {
downloadFileText(triggerSaveDocument.name, triggerSaveDocument.document);
downloadFile(triggerSaveDocument.name, triggerSaveDocument.content);
});
editor.subscriptions.subscribeJsMessage(TriggerDownloadTextFile, (triggerFileDownload) => {
downloadFileText(triggerFileDownload.name, triggerFileDownload.document);
editor.subscriptions.subscribeJsMessage(TriggerSaveFile, (triggerFileDownload) => {
downloadFile(triggerFileDownload.name, triggerFileDownload.content);
});
editor.subscriptions.subscribeJsMessage(TriggerDownloadImage, async (triggerDownloadImage) => {
const { svg, name, mime, size } = triggerDownloadImage;
editor.subscriptions.subscribeJsMessage(TriggerExportImage, async (TriggerExportImage) => {
const { svg, name, mime, size } = TriggerExportImage;
// Fill the canvas with white if it'll be a JPEG (which does not support transparency and defaults to black)
const backgroundColor = mime.endsWith("jpeg") ? "white" : undefined;
+3 -3
View File
@@ -15,10 +15,10 @@ export function downloadFileBlob(filename: string, blob: Blob) {
URL.revokeObjectURL(url);
}
export function downloadFileText(filename: string, text: string) {
const type = filename.endsWith(".svg") ? "image/svg+xml;charset=utf-8" : "text/plain;charset=utf-8";
export function downloadFile(filename: string, content: Uint8Array) {
const type = filename.endsWith(".svg") ? "image/svg+xml;charset=utf-8" : "application/octet-stream";
const blob = new Blob([text], { type });
const blob = new Blob([content], { type });
downloadFileBlob(filename, blob);
}