Files
Graphite/frontend/src/state/dialog.ts
T
0HyperCubeandKeavon Chambers 4b7d8b7ab0 Migrate dialogs to Rust and add a New File dialog (#623)
* Migrate coming soon and about dialog to Rust

* Migrate confirm close and close all

* Migrate dialog error

* Improve keyboard navigation throughout UI

* Cleanup and fix panic dialog

* Reduce css spacing to better match old dialogs

* Add new document modal

* Fix crash when generating default name

* Populate rust about graphite data on startup

* Code review changes

* Move one more :focus CSS rule into App.vue

* Add a dialog message and move dialogs

* Split out keyboard input navigation from this branch

* Improvements including simplifying panic dialog code

Co-authored-by: Keavon Chambers <keavon@keavon.com>
2022-05-07 09:59:52 +01:00

59 lines
2.0 KiB
TypeScript

import { reactive, readonly } from "vue";
import { defaultWidgetLayout, DisplayDialog, DisplayDialogDismiss, UpdateDialogDetails, WidgetLayout } from "@/dispatcher/js-messages";
import { EditorState } from "@/state/wasm-loader";
import { IconName } from "@/utilities/icons";
import { TextButtonWidget } from "@/utilities/widgets";
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export function createDialogState(editor: EditorState) {
const state = reactive({
visible: false,
icon: "" as IconName,
widgets: defaultWidgetLayout(),
// Special case for the crash dialog because we cannot handle button widget callbacks from Rust once the editor instance has panicked
jsCallbackBasedButtons: undefined as undefined | TextButtonWidget[],
});
// Creates a panic dialog from JS.
// Normal dialogs are created in the Rust backend, however for the crash dialog, the editor instance has panicked so it cannot respond to widget callbacks.
const createPanicDialog = (widgets: WidgetLayout, jsCallbackBasedButtons: TextButtonWidget[]): void => {
state.visible = true;
state.icon = "Warning";
state.widgets = widgets;
state.jsCallbackBasedButtons = jsCallbackBasedButtons;
};
const dismissDialog = (): void => {
state.visible = false;
};
const dialogIsVisible = (): boolean => state.visible;
const comingSoon = (issueNumber?: number): void => {
editor.instance.request_coming_soon_dialog(issueNumber);
};
// Run on creation
editor.dispatcher.subscribeJsMessage(DisplayDialog, (displayDialog) => {
state.visible = true;
state.icon = displayDialog.icon;
});
editor.dispatcher.subscribeJsMessage(DisplayDialogDismiss, dismissDialog);
editor.dispatcher.subscribeJsMessage(UpdateDialogDetails, (updateDialogDetails) => {
state.widgets = updateDialogDetails;
state.jsCallbackBasedButtons = undefined;
});
return {
state: readonly(state),
createPanicDialog,
dismissDialog,
dialogIsVisible,
comingSoon,
};
}
export type DialogState = ReturnType<typeof createDialogState>;