import {IpcRegistryDescription, Registry} from "tc-shared/events"; import {VideoViewerEvents} from "tc-shared/video-viewer/Definitions"; import {ChannelEditEvents} from "tc-shared/ui/modal/channel-edit/Definitions"; import {EchoTestEvents} from "tc-shared/ui/modal/echo-test/Definitions"; import {ModalGlobalSettingsEditorEvents} from "tc-shared/ui/modal/global-settings-editor/Definitions"; import {InviteUiEvents, InviteUiVariables} from "tc-shared/ui/modal/invite/Definitions"; import React, {ReactElement} from "react"; import {IpcVariableDescriptor} from "tc-shared/ui/utils/IpcVariable"; import {ModalBookmarkEvents, ModalBookmarkVariables} from "tc-shared/ui/modal/bookmarks/Definitions"; import { ModalBookmarksAddServerEvents, ModalBookmarksAddServerVariables } from "tc-shared/ui/modal/bookmarks-add-server/Definitions"; import {ModalPokeEvents, ModalPokeVariables} from "tc-shared/ui/modal/poke/Definitions"; export type ModalType = "error" | "warning" | "info" | "none"; export type ModalRenderType = "page" | "dialog"; export interface ModalOptions { /** * Unique modal id. */ uniqueId?: string, /** * Destroy the modal if it has been closed. * If the value is `false` it *might* destroy the modal anyways. * Default: `true`. */ destroyOnClose?: boolean, /** * Default size of the modal in pixel. * This value might or might not be respected. */ defaultSize?: { width: number, height: number }, /** * Determines if the modal is resizeable or now. * Some browsers might not support non resizeable modals. * Default: `both` */ resizeable?: "none" | "vertical" | "horizontal" | "both", /** * If the modal should be popoutable. * Default: `false` */ popoutable?: boolean, /** * The default popout state. * Default: `false` */ popedOut?: boolean } export interface ModalEvents { "open": {}, "close": {}, "destroy": {} } export enum ModalState { SHOWN, HIDDEN, DESTROYED } export interface ModalInstanceEvents { /* Actions which must be implemented by our modal owner */ action_close: {}, action_minimize: {}, action_popout: {}, /* State changes we encountered */ notify_open: {} notify_minimize: {}, notify_close: {}, notify_destroy: {}, } export interface ModalInstanceController { getState() : ModalState; getEvents() : Registry<ModalInstanceEvents>; show() : Promise<void>; hide() : Promise<void>; minimize() : Promise<void>; maximize() : Promise<void>; destroy(); } export interface ModalController { getOptions() : Readonly<ModalOptions>; getEvents() : Registry<ModalEvents>; getState() : ModalState; show() : Promise<void>; hide() : Promise<void>; destroy(); } export interface ModalInstanceProperties { windowed: boolean } let currentModalProperties: ModalInstanceProperties export abstract class AbstractModal { protected readonly properties: ModalInstanceProperties; protected constructor() { if(typeof currentModalProperties === "undefined") { throw "missing modal properties"; } this.properties = currentModalProperties; currentModalProperties = undefined; } abstract renderBody() : ReactElement; abstract renderTitle() : string | React.ReactElement; /* only valid for the "inline" modals */ type() : ModalType { return "none"; } color() : "none" | "blue" { return "none"; } verticalAlignment() : "top" | "center" | "bottom" { return "center"; } protected onInitialize() {} protected onDestroy() {} protected onClose() {} protected onOpen() {} } export abstract class InternalModal extends AbstractModal {} export function constructAbstractModalClass<T extends keyof ModalConstructorArguments>( klass: new (...args: ModalConstructorArguments[T]) => AbstractModal, properties: ModalInstanceProperties, args: ModalConstructorArguments[T]) : AbstractModal { currentModalProperties = properties; try { return new klass(...args); } finally { currentModalProperties = undefined; } } export interface ModalConstructorArguments { "__internal__modal__": any[], "video-viewer": [ /* events */ IpcRegistryDescription<VideoViewerEvents>, /* handlerId */ string, ], "channel-edit": [ /* events */ IpcRegistryDescription<ChannelEditEvents>, /* isChannelCreate */ boolean ], "echo-test": [ /* events */ IpcRegistryDescription<EchoTestEvents> ], "global-settings-editor": [ /* events */ IpcRegistryDescription<ModalGlobalSettingsEditorEvents> ], "conversation": any, "css-editor": any, "channel-tree": any, "modal-connect": any, "modal-invite": [ /* events */ IpcRegistryDescription<InviteUiEvents>, /* variables */ IpcVariableDescriptor<InviteUiVariables>, /* serverName */ string ], "modal-bookmarks": [ /* events */ IpcRegistryDescription<ModalBookmarkEvents>, /* variables */ IpcVariableDescriptor<ModalBookmarkVariables>, ], "modal-bookmark-add-server": [ /* events */ IpcRegistryDescription<ModalBookmarksAddServerEvents>, /* variables */ IpcVariableDescriptor<ModalBookmarksAddServerVariables>, ], "modal-poked": [ /* events */ IpcRegistryDescription<ModalPokeEvents>, /* variables */ IpcVariableDescriptor<ModalPokeVariables>, ], }