import * as React from 'react'; import { RefObject, useMemo, useRef } from 'react'; import { DialogState } from '../types'; import { PrintCallback } from './usePrintToCallback'; import { _ } from '@joplin/lib/locale'; import announceForAccessibility from '../../utils/announceForAccessibility'; interface PromptSuggestion { key: string; value: T; label: string; indentDepth?: number; } interface PromptOptions { label: string; value: string; suggestions: PromptSuggestion[]; } export interface WindowControl { setState: (update: Partial)=> void; showPrompt: (options: PromptOptions)=> Promise; printTo: PrintCallback; announcePanelVisibility(panelName: string, visible: boolean): void; getFocusedDocument(): Document; } export type OnSetDialogState = React.Dispatch>; const useWindowControl = (setDialogState: OnSetDialogState, onPrint: PrintCallback, windowDomRef: RefObject) => { // Use refs to avoid reloading the output where possible -- reloading the window control // may mean reloading all main window commands. const onPrintRef = useRef(onPrint); onPrintRef.current = onPrint; return useMemo((): WindowControl => { const control: WindowControl = { setState: (newPartialState: Partial) => { setDialogState(oldState => ({ ...oldState, ...newPartialState, })); }, printTo: (target, options) => onPrintRef.current(target, options), announcePanelVisibility: (panelName, visible) => { announceForAccessibility( visible ? _('Panel "%s" is visible', panelName) : _('Panel %s is hidden', panelName), ); }, showPrompt: (options: PromptOptions) => { return new Promise((resolve) => { control.setState({ promptOptions: { label: options.label, inputType: 'dropdown', value: options.value, autocomplete: options.suggestions, onClose: async (answer: unknown) => { if (answer) { resolve((answer as PromptSuggestion).value); } else { resolve(null); } control.setState({ promptOptions: null }); }, }, }); }); }, getFocusedDocument: () => { return windowDomRef.current; }, }; return control; }, [setDialogState, windowDomRef]); }; export default useWindowControl;