mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-12-23 10:11:54 +00:00
* Can only remove last document successfully * Correctly update the layer tree panel * Remove comments * Add support for randomly closing docs * Create new doc after closing last doc * Update layer panel when creating new docs * Fix bug that crashed the program when first doc was closed * Refactor to make code simpler and increase readability * Add shortcut to close active doc (Shift + C) * Add a confirmation dialog box before closing tabs * New docs get the correct title * Remove comments and fix typos * Disable 'eslint-no-alert' * Refactor and fix document title bug * Rename the FrontendMessage and ReponseType for showing close confirmation modal * Change the message displayed in the close confirmation modal Co-authored-by: Keavon Chambers <keavon@keavon.com>
234 lines
5.8 KiB
TypeScript
234 lines
5.8 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
|
|
type ResponseCallback = (responseData: Response) => void;
|
|
type ResponseMap = {
|
|
[response: string]: ResponseCallback | undefined;
|
|
};
|
|
declare global {
|
|
interface Window {
|
|
responseMap: ResponseMap;
|
|
}
|
|
}
|
|
|
|
export enum ResponseType {
|
|
UpdateCanvas = "UpdateCanvas",
|
|
ExportDocument = "ExportDocument",
|
|
ExpandFolder = "ExpandFolder",
|
|
CollapseFolder = "CollapseFolder",
|
|
SetActiveTool = "SetActiveTool",
|
|
SetActiveDocument = "SetActiveDocument",
|
|
NewDocument = "NewDocument",
|
|
CloseDocument = "CloseDocument",
|
|
UpdateWorkingColors = "UpdateWorkingColors",
|
|
PromptCloseConfirmationModal = "PromptCloseConfirmationModal",
|
|
}
|
|
|
|
export function attachResponseHandlerToPage() {
|
|
window.responseMap = {};
|
|
}
|
|
|
|
export function registerResponseHandler(responseType: ResponseType, callback: ResponseCallback) {
|
|
window.responseMap[responseType] = callback;
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
export function handleResponse(responseType: string, responseData: any) {
|
|
const callback = window.responseMap[responseType];
|
|
const data = parseResponse(responseType, responseData);
|
|
|
|
if (callback && data) {
|
|
callback(data);
|
|
} else if (data) {
|
|
console.error(`Received a Response of type "${responseType}" but no handler was registered for it from the client.`);
|
|
} else {
|
|
console.error(`Received a Response of type "${responseType}" but but was not able to parse the data.`);
|
|
}
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
function parseResponse(responseType: string, data: any): Response {
|
|
switch (responseType) {
|
|
case "DocumentChanged":
|
|
return newDocumentChanged(data.DocumentChanged);
|
|
case "CollapseFolder":
|
|
return newCollapseFolder(data.CollapseFolder);
|
|
case "ExpandFolder":
|
|
return newExpandFolder(data.ExpandFolder);
|
|
case "SetActiveTool":
|
|
return newSetActiveTool(data.SetActiveTool);
|
|
case "SetActiveDocument":
|
|
return newSetActiveDocument(data.SetActiveDocument);
|
|
case "NewDocument":
|
|
return newNewDocument(data.NewDocument);
|
|
case "CloseDocument":
|
|
return newCloseDocument(data.CloseDocument);
|
|
case "UpdateCanvas":
|
|
return newUpdateCanvas(data.UpdateCanvas);
|
|
case "ExportDocument":
|
|
return newExportDocument(data.ExportDocument);
|
|
case "UpdateWorkingColors":
|
|
return newUpdateWorkingColors(data.UpdateWorkingColors);
|
|
case "PromptCloseConfirmationModal":
|
|
return {};
|
|
default:
|
|
throw new Error(`Unrecognized origin/responseType pair: ${origin}, ${responseType}`);
|
|
}
|
|
}
|
|
|
|
export type Response = SetActiveTool | UpdateCanvas | DocumentChanged | CollapseFolder | ExpandFolder | UpdateWorkingColors;
|
|
|
|
export interface CloseDocument {
|
|
document_index: number;
|
|
}
|
|
function newCloseDocument(input: any): CloseDocument {
|
|
return { document_index: input.document_index };
|
|
}
|
|
|
|
export interface Color {
|
|
red: number;
|
|
green: number;
|
|
blue: number;
|
|
alpha: number;
|
|
}
|
|
function newColor(input: any): Color {
|
|
return { red: input.red * 255, green: input.green * 255, blue: input.blue * 255, alpha: input.alpha };
|
|
}
|
|
|
|
export interface UpdateWorkingColors {
|
|
primary: Color;
|
|
secondary: Color;
|
|
}
|
|
function newUpdateWorkingColors(input: any): UpdateWorkingColors {
|
|
return {
|
|
primary: newColor(input.primary),
|
|
secondary: newColor(input.secondary),
|
|
};
|
|
}
|
|
|
|
export interface SetActiveTool {
|
|
tool_name: string;
|
|
}
|
|
function newSetActiveTool(input: any): SetActiveTool {
|
|
return {
|
|
tool_name: input.tool_name,
|
|
};
|
|
}
|
|
|
|
export interface SetActiveDocument {
|
|
document_index: number;
|
|
}
|
|
function newSetActiveDocument(input: any): SetActiveDocument {
|
|
return {
|
|
document_index: input.document_index,
|
|
};
|
|
}
|
|
|
|
export interface NewDocument {
|
|
document_name: string;
|
|
}
|
|
function newNewDocument(input: any): NewDocument {
|
|
return {
|
|
document_name: input.document_name,
|
|
};
|
|
}
|
|
|
|
export interface UpdateCanvas {
|
|
document: string;
|
|
}
|
|
function newUpdateCanvas(input: any): UpdateCanvas {
|
|
return {
|
|
document: input.document,
|
|
};
|
|
}
|
|
|
|
export interface ExportDocument {
|
|
document: string;
|
|
}
|
|
function newExportDocument(input: any): UpdateCanvas {
|
|
return {
|
|
document: input.document,
|
|
};
|
|
}
|
|
|
|
export type DocumentChanged = {};
|
|
function newDocumentChanged(_: any): DocumentChanged {
|
|
return {};
|
|
}
|
|
|
|
export interface CollapseFolder {
|
|
path: BigUint64Array;
|
|
}
|
|
function newCollapseFolder(input: any): CollapseFolder {
|
|
return {
|
|
path: new BigUint64Array(input.path.map((n: number) => BigInt(n))),
|
|
};
|
|
}
|
|
|
|
export interface ExpandFolder {
|
|
path: BigUint64Array;
|
|
children: Array<LayerPanelEntry>;
|
|
}
|
|
function newExpandFolder(input: any): ExpandFolder {
|
|
return {
|
|
path: new BigUint64Array(input.path.map((n: number) => BigInt(n))),
|
|
children: input.children.map((child: any) => newLayerPanelEntry(child)),
|
|
};
|
|
}
|
|
|
|
export interface LayerPanelEntry {
|
|
name: string;
|
|
visible: boolean;
|
|
layer_type: LayerType;
|
|
path: BigUint64Array;
|
|
layer_data: LayerData;
|
|
}
|
|
function newLayerPanelEntry(input: any): LayerPanelEntry {
|
|
return {
|
|
name: input.name,
|
|
visible: input.visible,
|
|
layer_type: newLayerType(input.layer_type),
|
|
layer_data: newLayerData(input.layer_data),
|
|
path: new BigUint64Array(input.path.map((n: number) => BigInt(n))),
|
|
};
|
|
}
|
|
|
|
export interface LayerData {
|
|
expanded: boolean;
|
|
selected: boolean;
|
|
}
|
|
function newLayerData(input: any): LayerData {
|
|
return {
|
|
expanded: input.expanded,
|
|
selected: input.selected,
|
|
};
|
|
}
|
|
|
|
export enum LayerType {
|
|
Folder = "Folder",
|
|
Shape = "Shape",
|
|
Circle = "Circle",
|
|
Rect = "Rect",
|
|
Line = "Line",
|
|
PolyLine = "PolyLine",
|
|
Ellipse = "Ellipse",
|
|
}
|
|
function newLayerType(input: any): LayerType {
|
|
switch (input) {
|
|
case "Folder":
|
|
return LayerType.Folder;
|
|
case "Shape":
|
|
return LayerType.Shape;
|
|
case "Circle":
|
|
return LayerType.Circle;
|
|
case "Rect":
|
|
return LayerType.Rect;
|
|
case "Line":
|
|
return LayerType.Line;
|
|
case "PolyLine":
|
|
return LayerType.PolyLine;
|
|
case "Ellipse":
|
|
return LayerType.Ellipse;
|
|
default:
|
|
throw Error(`Received invalid input as an enum variant for LayerType: ${input}`);
|
|
}
|
|
}
|