mirror of
https://github.com/Kong/insomnia
synced 2024-11-08 23:00:30 +00:00
221 lines
5.6 KiB
TypeScript
221 lines
5.6 KiB
TypeScript
import * as electron from 'electron';
|
|
import React from 'react';
|
|
|
|
import * as analytics from '../../../app/common/analytics';
|
|
import { axiosRequest as axios } from '../../../app/network/axios-request';
|
|
import { getAppPlatform, getAppVersion } from '../../common/constants';
|
|
import type { RenderPurpose } from '../../common/render';
|
|
import {
|
|
RENDER_PURPOSE_GENERAL,
|
|
RENDER_PURPOSE_NO_RENDER,
|
|
RENDER_PURPOSE_SEND,
|
|
} from '../../common/render';
|
|
import { HtmlElementWrapper } from '../../ui/components/html-element-wrapper';
|
|
import { showAlert, showModal, showPrompt } from '../../ui/components/modals';
|
|
import { PromptModalOptions } from '../../ui/components/modals/prompt-modal';
|
|
import { WrapperModal } from '../../ui/components/modals/wrapper-modal';
|
|
|
|
interface DialogOptions {
|
|
onHide?: () => void;
|
|
tall?: boolean;
|
|
skinny?: boolean;
|
|
wide?: boolean;
|
|
}
|
|
|
|
interface AppInfo {
|
|
version: string;
|
|
platform: NodeJS.Platform;
|
|
}
|
|
|
|
interface ShowDialogOptions {
|
|
defaultPath?: string;
|
|
}
|
|
|
|
interface AppClipboard {
|
|
readText(): string;
|
|
writeText(text: string): void;
|
|
clear(): void;
|
|
}
|
|
|
|
interface ShowGenericModalDialogOptions {
|
|
html?: string;
|
|
}
|
|
|
|
export interface AppContext {
|
|
alert: (
|
|
title: string,
|
|
message?: string
|
|
) => Promise<undefined> | ReturnType<typeof showAlert>;
|
|
dialog: (title: string, body: HTMLElement, options?: DialogOptions) => void;
|
|
prompt: (title: string, options?: Pick<PromptModalOptions, 'label' | 'defaultValue' | 'submitName' | 'cancelable'>) => Promise<string>;
|
|
getPath: (name: string) => string;
|
|
getInfo: () => AppInfo;
|
|
showSaveDialog: (options?: ShowDialogOptions) => Promise<string | null>;
|
|
clipboard: AppClipboard;
|
|
/**
|
|
* @deprecated as it was never officially supported
|
|
*/
|
|
showGenericModalDialog: (
|
|
title: string,
|
|
options?: ShowGenericModalDialogOptions
|
|
) => void;
|
|
}
|
|
|
|
export interface PrivateProperties {
|
|
axios: typeof axios;
|
|
analytics: typeof analytics;
|
|
}
|
|
|
|
export function init(renderPurpose: RenderPurpose = RENDER_PURPOSE_GENERAL): {
|
|
app: AppContext;
|
|
__private: PrivateProperties;
|
|
} {
|
|
const canShowDialogs =
|
|
renderPurpose === RENDER_PURPOSE_SEND ||
|
|
renderPurpose === RENDER_PURPOSE_NO_RENDER;
|
|
return {
|
|
app: {
|
|
alert(title: string, message?: string) {
|
|
if (!canShowDialogs) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
return showAlert({
|
|
title,
|
|
message,
|
|
});
|
|
},
|
|
|
|
dialog(
|
|
title,
|
|
body,
|
|
options = {},
|
|
) {
|
|
if (
|
|
renderPurpose !== RENDER_PURPOSE_SEND &&
|
|
renderPurpose !== RENDER_PURPOSE_NO_RENDER
|
|
) {
|
|
return;
|
|
}
|
|
|
|
showModal(WrapperModal, {
|
|
title,
|
|
body: <HtmlElementWrapper el={body} onUnmount={options.onHide} />,
|
|
tall: options.tall,
|
|
skinny: options.skinny,
|
|
wide: options.wide,
|
|
});
|
|
},
|
|
|
|
prompt(
|
|
title,
|
|
options = {},
|
|
) {
|
|
if (!canShowDialogs) {
|
|
return Promise.resolve(options.defaultValue || '');
|
|
}
|
|
|
|
// This custom promise converts the prompt modal from being callback-based to reject when the modal is cancelled and resolve when the modal is submitted and hidden
|
|
return new Promise<string>((resolve, reject) => {
|
|
let shouldResolve = false;
|
|
let resolveWith: string | null = null;
|
|
|
|
showPrompt({
|
|
title,
|
|
...(options || ({} as Record<string, any>)),
|
|
|
|
onCancel() {
|
|
reject(new Error(`Prompt ${title} cancelled`));
|
|
},
|
|
|
|
onComplete(value: string) {
|
|
shouldResolve = true;
|
|
resolveWith = value;
|
|
},
|
|
|
|
// don't resolve the overall promise until the modal has hidden after clicking submit
|
|
onHide() {
|
|
if (shouldResolve && resolveWith !== null) {
|
|
resolve(resolveWith);
|
|
}
|
|
},
|
|
});
|
|
});
|
|
},
|
|
|
|
getPath(name: string) {
|
|
switch (name.toLowerCase()) {
|
|
case 'desktop':
|
|
return electron.remote.app.getPath('desktop');
|
|
|
|
default:
|
|
throw new Error(`Unknown path name ${name}`);
|
|
}
|
|
},
|
|
|
|
getInfo() {
|
|
return {
|
|
version: getAppVersion(),
|
|
platform: getAppPlatform(),
|
|
};
|
|
},
|
|
|
|
async showSaveDialog(
|
|
options = {},
|
|
): Promise<string | null> {
|
|
if (!canShowDialogs) {
|
|
return Promise.resolve(null);
|
|
}
|
|
|
|
const saveOptions = {
|
|
title: 'Save File',
|
|
buttonLabel: 'Save',
|
|
defaultPath: options.defaultPath,
|
|
};
|
|
const { filePath } = await electron.remote.dialog.showSaveDialog(
|
|
saveOptions
|
|
);
|
|
return filePath || null;
|
|
},
|
|
|
|
clipboard: {
|
|
readText() {
|
|
return electron.clipboard.readText();
|
|
},
|
|
|
|
writeText(text) {
|
|
electron.clipboard.writeText(text);
|
|
},
|
|
|
|
clear() {
|
|
electron.clipboard.clear();
|
|
},
|
|
},
|
|
|
|
// ~~~~~~~~~~~~~~~~~~ //
|
|
// Deprecated Methods //
|
|
// ~~~~~~~~~~~~~~~~~~ //
|
|
showGenericModalDialog(
|
|
title,
|
|
options = {},
|
|
) {
|
|
console.warn(
|
|
'app.showGenericModalDialog() is deprecated. Use app.dialog() instead.'
|
|
);
|
|
// Create DOM node so we can adapt to the new dialog() method
|
|
const body = document.createElement('div');
|
|
|
|
if (options.html) {
|
|
body.innerHTML = options.html;
|
|
}
|
|
|
|
return this.dialog(title, body);
|
|
},
|
|
},
|
|
__private: {
|
|
axios,
|
|
analytics,
|
|
},
|
|
};
|
|
}
|