Move file filter creation from frontend to editor (#4351)

This commit is contained in:
Timon
2026-08-28 11:19:44 +02:00
committed by GitHub
parent c8f38059f8
commit c2afc07a04
11 changed files with 98 additions and 50 deletions

View File

@@ -3,7 +3,7 @@ import { SvelteMap } from "svelte/reactivity";
import { writable } from "svelte/store";
import type { Writable } from "svelte/store";
import type { SubscriptionsRouter } from "/src/subscriptions-router";
import { downloadFile, downloadFileBlob, upload } from "/src/utility-functions/files";
import { acceptStringFromFilters, downloadFile, downloadFileBlob, upload } from "/src/utility-functions/files";
import { rasterizeSVG } from "/src/utility-functions/rasterization";
import { patchLayout } from "/src/utility-functions/widgets";
import type { EditorWrapper, DocumentInfo, LayerPanelEntry, LayerStructureEntry, Layout, WorkspacePanelLayout } from "/wrapper/pkg/graphite_wasm_wrapper";
@@ -93,14 +93,13 @@ export function createPortfolioStore(subscriptions: SubscriptionsRouter, editor:
}
});
subscriptions.subscribeFrontendMessage("TriggerOpen", async () => {
const files = await upload(`image/*,.${editor.fileExtension()},.${editor.gddFileExtension()}`, "data", true);
subscriptions.subscribeFrontendMessage("TriggerOpen", async ({ filters }) => {
const files = await upload(acceptStringFromFilters(filters), "data", true);
files.forEach((file) => editor.openFile(file.filename, file.content));
});
subscriptions.subscribeFrontendMessage("TriggerImport", async () => {
// TODO: Use the same `accept` string as in the `TriggerOpen` handler once importing Graphite documents as nodes is supported
const data = await upload("image/*", "data");
subscriptions.subscribeFrontendMessage("TriggerImport", async ({ filters }) => {
const data = await upload(acceptStringFromFilters(filters), "data");
editor.importFile(data.filename, data.content);
});

View File

@@ -1,5 +1,5 @@
import { extractPixelData } from "/src/utility-functions/rasterization";
import type { EditorWrapper } from "/wrapper/pkg/graphite_wasm_wrapper";
import type { EditorWrapper, FileFilter } from "/wrapper/pkg/graphite_wasm_wrapper";
export function downloadFileURL(filename: string, url: string) {
const element = document.createElement("a");
@@ -91,8 +91,14 @@ export async function pasteFile(item: DataTransferItem, editor: EditorWrapper, m
} else if (file.type.startsWith("image/")) {
const imageData = await extractPixelData(file);
editor.pasteImage(file.name, new Uint8Array(imageData.data), imageData.width, imageData.height, mouse?.[0], mouse?.[1], insertParentId, insertIndex);
} else if (file.name.endsWith("." + editor.fileExtension())) {
} else {
// TODO: When we eventually have sub-documents, this should be changed to import the document as a node instead of opening it in a separate tab
editor.openFile(file.name, await file.bytes());
}
}
export function acceptStringFromFilters(filters: FileFilter[]): string {
const extensions = filters.flatMap((filter) => filter.extensions);
const imageMime = extensions.some((extension) => ["svg", "png", "jpg", "jpeg", "bmp", "gif", "webp", "avif", "tif", "tiff"].includes(extension)) ? ["image/*"] : [];
return [...imageMime, ...extensions.map((extension) => `.${extension}`)].join(",");
}

View File

@@ -40,11 +40,11 @@ export async function loadDemoArtwork(editor: EditorWrapper) {
if (!demoArtwork) return;
try {
const url = new URL(`/demo-artwork/${demoArtwork}.${editor.fileExtension()}`, document.location.href);
const url = new URL(`/demo-artwork/${demoArtwork}.graphite`, document.location.href);
const response = await fetch(url);
if (!response.ok) throw new Error();
const filename = url.pathname.split("/").pop() || `Untitled.${editor.fileExtension()}`;
const filename = url.pathname.split("/").pop() || "Untitled.graphite";
const content = await response.bytes();
editor.openFile(filename, content);

View File

@@ -240,16 +240,6 @@ impl EditorWrapper {
cfg!(debug_assertions)
}
#[wasm_bindgen(js_name = fileExtension)]
pub fn file_extension(&self) -> String {
"graphite".into()
}
#[wasm_bindgen(js_name = gddFileExtension)]
pub fn gdd_file_extension(&self) -> String {
"gdd".into()
}
/// Load persisted browser storage state (web only; on desktop, persistence is handled natively and this is never triggered)
#[cfg(all(feature = "web", not(feature = "native")))]
#[wasm_bindgen(js_name = loadPersistedState)]