Skip to content

Commit

Permalink
feat: implemented dialogs via Zenity. Close #159
Browse files Browse the repository at this point in the history
  • Loading branch information
ChugunovRoman committed Jan 15, 2021
1 parent 1f33c6a commit adb52eb
Show file tree
Hide file tree
Showing 16 changed files with 469 additions and 124 deletions.
1 change: 1 addition & 0 deletions @types/Common/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ interface SettingsInterface {
logLevel: number;
enableColorSpaceSrgb: boolean;
visibleNewProjectBtn: boolean;
useZenity: boolean;
panelHeight: number;
saveLastOpenedTabs: boolean;
exportDir: string;
Expand Down
45 changes: 45 additions & 0 deletions @types/Main/dialogs.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
declare namespace Dialogs {
type Providers = "Native" | "Zenity";
type Type = "error" | "warning" | "info" | "question";

interface SaveOptions {
title?: string;
defaultPath?: string;
showsTagField?: boolean;
}
interface OpenOptions {
buttonLabel?: string;
defaultPath?: string;
properties?: string[];
}

type MessageBoxOptions = ErrorBoxOptions | QuestionBoxOptions | WarningBoxOptions;
interface BaseBoxOptions {
textOkButton?: string;
title?: string;
message: string;
detail?: string;
}
interface ErrorBoxOptions extends BaseBoxOptions {
type: "error";
}
interface WarningBoxOptions extends BaseBoxOptions {
type: "warning";
}
interface QuestionBoxOptions extends BaseBoxOptions {
type: "question";
textCancelButton?: string;
defaultFocusedButton: "Ok" | "Cancel";
}
}

declare interface ProviderDialog {
showMessageBox(params: Dialogs.MessageBoxOptions): Promise<number>;
showMessageBoxSync(params: Dialogs.MessageBoxOptions): number;

showOpenDialog(params: Dialogs.OpenOptions): Promise<string[] | null>;
showOpenDialogSync(params: Dialogs.OpenOptions): string[] | null;

showSaveDialog(params: Dialogs.SaveOptions): Promise<string | null>;
showSaveDialogSync(params: Dialogs.SaveOptions): string | null;
}
6 changes: 6 additions & 0 deletions @types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ declare namespace Electron {
channel: "set-clipboard-data",
listener: (event: IpcMainInvokeEvent, data: WebApi.SetClipboardData) => void,
): this;
on(channel: "set-use-zenity", listener: (event: IpcMainInvokeEvent, value: boolean) => void): this;
on(channel: "set-settings", listener: (event: IpcMainInvokeEvent, settings: SettingsInterface) => void): this;

handle(
Expand Down Expand Up @@ -127,6 +128,8 @@ declare namespace Electron {
channel: "get-font-file",
listener: (event: IpcMainInvokeEvent, data: WebApi.GetFontFile) => Promise<void> | Buffer,
): void;
handle(channel: "add-font-directories", listener: (event: IpcMainInvokeEvent) => Promise<string[] | null>): void;
handle(channel: "select-export-directory", listener: (event: IpcMainInvokeEvent) => Promise<string | null>): void;
}

interface IpcRenderer extends NodeJS.EventEmitter {
Expand Down Expand Up @@ -184,6 +187,7 @@ declare namespace Electron {
send(channel: "saveCreatorTheme", theme: Themes.Theme): this;
send(channel: "sync-themes"): this;
send(channel: "set-clipboard-data", data: WebApi.SetClipboardData): this;
send(channel: "set-use-zenity", value: boolean): this;
send(channel: "set-settings", settings: SettingsInterface): this;

invoke(channel: "writeNewExtensionToDisk", data: WebApi.WriteNewExtensionToDiskArgs): Promise<number>;
Expand All @@ -198,6 +202,8 @@ declare namespace Electron {
invoke(channel: "writeFiles", data: WebApi.WriteFiles): Promise<void>;
invoke(channel: "get-fonts"): Promise<FontsMap>;
invoke(channel: "get-font-file", data: WebApi.GetFontFile): Promise<Buffer>;
invoke(channel: "add-font-directories"): Promise<string[] | null>;
invoke(channel: "select-export-directory"): Promise<string | null>;
}

interface WebContents extends NodeJS.EventEmitter {
Expand Down
1 change: 1 addition & 0 deletions src/constants/_defaultSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const DEFAULT_SETTINGS: SettingsInterface = {
logLevel: LogLevel.INFO,
enableColorSpaceSrgb: false,
visibleNewProjectBtn: true,
useZenity: false,
panelHeight: 40,
saveLastOpenedTabs: true,
exportDir: `${process.env.HOME}/Pictures/Figma`,
Expand Down
88 changes: 88 additions & 0 deletions src/main/Dialogs/Native.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import * as E from "electron";

export class NativeDialogs implements ProviderDialog {
constructor() {}

public showMessageBox = async (options: Dialogs.MessageBoxOptions) => {
const ops: E.MessageBoxOptions = {
type: options.type,
title: options.title,
message: options.message,
detail: options.detail,
defaultId: 0,
};

if (options.type === "question") {
const buttons = ["Ok", "Cancel"];

if (options.textCancelButton) {
buttons[1] = options.textCancelButton;
}
if (options.textOkButton) {
buttons[0] = options.textOkButton;
}
ops.buttons = buttons;
} else {
if (options.textOkButton) {
const buttons = ["Ok"];

buttons[0] = options.textOkButton;

ops.buttons = buttons;
}
}

const result = await E.dialog.showMessageBox(null, ops);
return result.response;
};
public showMessageBoxSync = (options: Dialogs.MessageBoxOptions) => {
const ops: E.MessageBoxOptions = {
type: options.type,
title: options.title,
message: options.message,
detail: options.detail,
defaultId: 0,
};

if (options.type === "question") {
const buttons = ["Ok", "Cancel"];

if (options.textCancelButton) {
buttons[1] = options.textCancelButton;
}
if (options.textOkButton) {
buttons[0] = options.textOkButton;
}
ops.buttons = buttons;
} else {
if (options.textOkButton) {
const buttons = ["Ok"];

buttons[0] = options.textOkButton;

ops.buttons = buttons;
}
}

const result = E.dialog.showMessageBoxSync(null, ops);
return result;
};

public showOpenDialog = async (options: Dialogs.OpenOptions) => {
const result = await E.dialog.showOpenDialog(null, options as E.OpenDialogOptions);
return !result.canceled ? result.filePaths : null;
};
public showOpenDialogSync = (options: Dialogs.OpenOptions) => {
const result = E.dialog.showOpenDialogSync(null, options as E.OpenDialogOptions);
return result || [];
};

public showSaveDialog = async (options: Dialogs.SaveOptions) => {
const result = await E.dialog.showSaveDialog(null, options);
return !result.canceled && result.filePath ? result.filePath : null;
};
public showSaveDialogSync = (options: Dialogs.SaveOptions) => {
const result = E.dialog.showSaveDialogSync(null, options);
return result;
};
}
160 changes: 160 additions & 0 deletions src/main/Dialogs/Zenity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { process } from "../Process";

export class ZenityDialogs implements ProviderDialog {
constructor() {}

public showMessageBox = async (options: Dialogs.MessageBoxOptions) => {
const cmd = [`zenity --${options.type} --ellipsize`];

if (options.title) {
cmd.push(`--title="${options.title}"`);
}
if (options.detail) {
cmd.push(`--text="${options.message}\n${options.detail}"`);
}
if (options.textOkButton) {
cmd.push(`--ok-label="${options.textOkButton}"`);
}
if (options.type === "question") {
if (options.textCancelButton) {
cmd.push(`--cancel-label="${options.textCancelButton}"`);
}
if (options.defaultFocusedButton === "Cancel") {
cmd.push(`--default-cancel`);
}
}

try {
await process.exec(cmd.join(" "));
return 0;
} catch (error) {
return 1;
}
};
public showMessageBoxSync = (options: Dialogs.MessageBoxOptions) => {
const cmd = [`zenity --${options.type} --ellipsize`];

if (options.title) {
cmd.push(`--title="${options.title}"`);
}
if (options.detail) {
cmd.push(`--text="${options.message}\n${options.detail}"`);
}
if (options.textOkButton) {
cmd.push(`--ok-label="${options.textOkButton}"`);
}
if (options.type === "question") {
if (options.textCancelButton) {
cmd.push(`--cancel-label="${options.textCancelButton}"`);
}
if (options.defaultFocusedButton === "Cancel") {
cmd.push(`--default-cancel`);
}
}

try {
process.execSync(cmd.join(" "));
return 0;
} catch (error) {
return 1;
}
};

public showOpenDialog = async (options: Dialogs.OpenOptions) => {
const cmd = ["zenity --file-selection"];

if (options.defaultPath) {
cmd.push(`--filename="${options.defaultPath}"`);
}
if (Array.isArray(options.properties) && options.properties.length > 0) {
for (const prop of options.properties) {
switch (prop) {
case "openDirectory": {
cmd.push(`--directory`);
break;
}
case "multiSelections": {
cmd.push(`--multiple`);
break;
}
}
}
}

let result: string[] | undefined;
try {
const stdout = await process.exec(cmd.join(" "));
result = stdout.replace(/\n/, "").split("|");
} catch (error) {
return null;
}

return result;
};
public showOpenDialogSync = (options: Dialogs.OpenOptions) => {
const cmd = ["zenity --file-selection"];

if (options.defaultPath) {
cmd.push(`--filename="${options.defaultPath}"`);
}
if (Array.isArray(options.properties) && options.properties.length > 0) {
for (const prop of options.properties) {
switch (prop) {
case "openDirectory": {
cmd.push(`--directory`);
break;
}
case "multiSelections": {
cmd.push(`--multiple`);
break;
}
}
}
}

let result: string[] | undefined;
try {
const stdout = process.execSync(cmd.join(" "));
result = stdout.replace(/\n/, "").split("|");
} catch (error) {
return null;
}

return result;
};

public showSaveDialog = async (options: Dialogs.SaveOptions) => {
const cmd = ["zenity --file-selection --save --confirm-overwrite"];

if (options.defaultPath) {
cmd.push(`--filename="${options.defaultPath}"`);
}

let result: string | undefined;
try {
result = await process.exec(cmd.join(" "));
result = result.replace(/\n/, "");
} catch (error) {
return null;
}

return result;
};
public showSaveDialogSync = (options: Dialogs.SaveOptions) => {
const cmd = ["zenity --file-selection --save --confirm-overwrite"];

if (options.defaultPath) {
cmd.push(`--filename="${options.defaultPath}"`);
}

let result: string | undefined;
try {
result = process.execSync(cmd.join(" "));
result = result.replace(/\n/, "");
} catch (error) {
return null;
}

return result;
};
}
Loading

0 comments on commit adb52eb

Please sign in to comment.