import { IconButton, Size, Type } from '@dash/components'; import { IReactionDisposer, action, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { SettingsManager } from '../../../util/SettingsManager'; import { ButtonType } from '../../nodes/FontIconBox/FontIconBox'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import './CollectionFreeFormView.scss'; export interface InfoButton { targetState?: infoState; // DocumentOptions fields a button can set title?: string; toolTip?: string; btnType?: ButtonType; // fields that do not correspond to DocumentOption fields scripts?: { script?: string; onClick?: string; onDoubleClick?: string }; } /** * An Fsa Arc. The first array element is a test condition function that will be observed. * The second array element is a function that will be invoked when the first test function * returns a truthy value */ export type infoArc = [() => unknown, (res?: unknown) => infoState]; export const StateMessage = Symbol('StateMessage'); export const StateMessageGIF = Symbol('StateMessageGIF'); export const StateEntryFunc = Symbol('StateEntryFunc'); export const StateMessageButton = Symbol('StateMessageButton'); export class infoState { [StateMessage]: string = ''; [StateMessageGIF]?: string = ''; [StateMessageButton]?: InfoButton[]; [StateEntryFunc]?: () => unknown; [key: string]: infoArc; constructor(message: string, arcs?: { [key: string]: infoArc }, messageGif?: string, buttons?: InfoButton[], entryFunc?: () => unknown) { this[StateMessage] = message; Object.assign(this, arcs ?? {}); this[StateMessageGIF] = messageGif; this[StateEntryFunc] = entryFunc; this[StateMessageButton] = buttons; } } /** * Create an FSA state. * @param msg the message displayed when in this state * @param arcs an object with fields containing @infoArcs (an object with field names indicating the arc transition and * field values being a tuple of an arc transition trigger function (that returns a truthy value when the arc should fire), * and an arc transition action function (that sets the next state) * @param gif the gif displayed when in this state * @param entryFunc a function to call when entering the state * @returns an FSA state */ export function InfoState( msg: string, // arcs?: { [key: string]: infoArc }, gif?: string, button?: InfoButton[], entryFunc?: () => unknown ) { return new infoState(msg, arcs, gif, button, entryFunc); } export interface CollectionFreeFormInfoStateProps { infoState: infoState; next: (state: infoState) => unknown; // Ensure it's properly defined close: () => void; } @observer export class CollectionFreeFormInfoState extends ObservableReactComponent { _disposers: IReactionDisposer[] = []; @observable _expanded = false; constructor(props: CollectionFreeFormInfoStateProps) { super(props); makeObservable(this); } get State() { return this._props.infoState; } set State(value: infoState) { this._props.infoState = value; } get Arcs() { return Object.keys(this.State ?? []).map(key => this.State?.[key]); } clearState = () => this._disposers.map(disposer => disposer()); initState = () => { this._disposers = this.Arcs .map(arc => ({ test: arc[0], act: arc[1] })) .map(arc => reaction( arc.test, res => res && this._props.next(arc.act(res)), { fireImmediately: true } ) )}; // prettier-ignore componentDidMount() { this.initState(); } componentDidUpdate(prevProps: Readonly) { super.componentDidUpdate(prevProps); this.clearState(); this.initState(); } componentWillUnmount() { this.clearState(); } render() { const gif = this.State?.[StateMessageGIF]; const buttons = this.State?.[StateMessageButton]; console.log('Rendering CollectionFreeFormInfoState with state:', this.props.infoState); console.log(buttons); return (

{this.State?.[StateMessage]}

state message gif
{/* Render the buttons for skipping */}
{buttons?.map((button, index) => ( ))}
this.props.close())} />
); } }