aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx
blob: 89d2bf2c33324ba0096fb9f2dab9f219c4d413a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
import { makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, FieldResult, FieldType } from '../../../../fields/Doc';
import { InkTool } from '../../../../fields/InkField';
import { StrCast } from '../../../../fields/Types';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { DocButtonState, DocumentLinksButton } from '../../nodes/DocumentLinksButton';
import { TopBar } from '../../topbar/TopBar';
import { CollectionFreeFormInfoState, InfoState, StateEntryFunc, infoState } from './CollectionFreeFormInfoState';
import { CollectionFreeFormView } from './CollectionFreeFormView';
import './CollectionFreeFormView.scss';

export interface CollectionFreeFormInfoUIProps {
    Doc: Doc;
    layoutDoc: Doc;
    childDocs: () => Doc[];
    close: () => void;
}

@observer
export class CollectionFreeFormInfoUI extends ObservableReactComponent<CollectionFreeFormInfoUIProps> {
    public static Init() {
        CollectionFreeFormView.SetInfoUICreator((doc: Doc, layout: Doc, childDocs: () => Doc[], close: () => void) => (
            //
            <CollectionFreeFormInfoUI Doc={doc} layoutDoc={layout} childDocs={childDocs} close={close} />
        ));
    }
    _firstDocPos = { x: 0, y: 0 };

    constructor(props: CollectionFreeFormInfoUIProps) {
        super(props);
        makeObservable(this);
        this._currState = this.setupStates();
    }
    _originalbackground: string | undefined;

    @observable _currState: infoState | undefined = undefined;
    get currState() { return this._currState; } // prettier-ignore
    set currState(val) { runInAction(() => {this._currState = val;}); } // prettier-ignore

    componentWillUnmount(): void {
        this._props.Doc.$backgroundColor = this._originalbackground;
    }

    setCurrState = (state: infoState) => {
        if (state) {
            this.currState = state;
            this.currState[StateEntryFunc]?.();
        }
    };

    setupStates = () => {
        this._originalbackground = StrCast(this._props.Doc.$backgroundColor);
        //  state entry functions
        // const setBackground = (colour: string) => () => {this._props.Doc.$backgroundColor = colour;} // prettier-ignore
        // const setOpacity = (opacity: number) => () => {this._props.layoutDoc.opacity = opacity;} // prettier-ignore
        //  arc transition trigger conditions
        const firstDoc = () => (this._props.childDocs().length ? this._props.childDocs()[0] : undefined);
        const numDocs = () => this._props.childDocs().length;

        let docX: FieldResult<FieldType>;
        let docY: FieldResult<FieldType>;

        const docNewX = () => firstDoc()?.x;
        const docNewY = () => firstDoc()?.y;

        const linkStart = () => DocumentLinksButton.StartLink;
        const linkUnstart = () => !DocumentLinksButton.StartLink;

        const numDocLinks = () => Doc.Links(firstDoc())?.length;
        const linkMenuOpen = () => DocButtonState.Instance.LinkEditorDocView;

        const activeTool = () => Doc.ActiveTool;

        const pin = () => DocListCast(Doc.ActivePresentation?.data);

        let trail: number;

        const presentationMode = () => Doc.ActivePresentation?.presentation_status;

        // set of states
        const start = InfoState(
            'Click anywhere and begin typing to create your first text document.',
            {
                docCreated: [() => numDocs(), () => {
                    docX = firstDoc()?.x;
                    docY = firstDoc()?.y;
                    // eslint-disable-next-line no-use-before-define
                    return oneDoc;
                }],
            }
        ); // prettier-ignore

        const oneDoc = InfoState(
            'Hello world! You can drag and drop to move your document around.',
            {
                // docCreated: [() => numDocs() > 1, () => multipleDocs],
                docDeleted: [() => numDocs() < 1, () => start],
                docMoved: [() => (docX && docX !== docNewX()) || (docY && docY !== docNewY()), () => {
                    docX = firstDoc()?.x;
                    docY = firstDoc()?.y;
                    // eslint-disable-next-line no-use-before-define
                    return movedDoc;
                }],
            }
        ); // prettier-ignore

        const movedDoc = InfoState(
            'Great moves. Try creating a second document. You can see the list of supported document types by typing a colon (":")',
            {
                // eslint-disable-next-line no-use-before-define
                docCreated: [() => numDocs() === 2, () => multipleDocs],
                docDeleted: [() => numDocs() < 1, () => start],
            },
            'dash-colon-menu.gif',
            () => TopBar.Instance.FlipDocumentationIcon()
        ); // prettier-ignore

        const multipleDocs = InfoState(
            'Let\'s create a new link. Click the link icon on one of your documents.',
            {
                // eslint-disable-next-line no-use-before-define
                linkStarted: [() => linkStart(), () => startedLink],
                docRemoved: [() => numDocs() < 2, () => oneDoc],
            },
            'dash-create-link-board.gif'
        ); // prettier-ignore

        const startedLink = InfoState(
            'Now click the highlighted link icon on your other document.',
            {
                linkUnstart: [() => linkUnstart(), () => multipleDocs],
                // eslint-disable-next-line no-use-before-define
                linkCreated: [() => numDocLinks(), () => madeLink],
                docRemoved: [() => numDocs() < 2, () => oneDoc],
            },
            'dash-create-link-board.gif'
        ); // prettier-ignore

        const madeLink = InfoState(
            'You made your first link! You can view your links by selecting the blue dot.',
            {
                linkCreated: [() => !numDocLinks(), () => multipleDocs],
                linkViewed: [() => linkMenuOpen(), () => {
                    alert(numDocLinks() + " cheer for " + numDocLinks() + " link!");
                    // eslint-disable-next-line no-use-before-define
                    return viewedLink;
                }],
            },
            'dash-following-link.gif'
        ); // prettier-ignore

        const viewedLink = InfoState(
            'Great work. You are now ready to create your own hypermedia world. Click the ? icon in the top right corner to learn more.',
            {
                linkDeleted: [() => !numDocLinks(), () => multipleDocs],
                docRemoved: [() => numDocs() < 2, () => oneDoc],
                docCreated: [() => numDocs() === 3, () => {
                    trail = pin().length;
                    // eslint-disable-next-line no-use-before-define
                    return presentDocs;
                }],
                // eslint-disable-next-line no-use-before-define
                activePen: [() => activeTool() === InkTool.Ink, () => penMode],
            },
            'documentation.png',
            () => TopBar.Instance.FlipDocumentationIcon()
        ); // prettier-ignore

        const presentDocs = InfoState(
            'Another document! You could make a presentation. Click the pin icon in the top left corner.',
            {
                docPinned: [
                    () => pin().length > trail,
                    () => {
                        trail = pin().length;
                        // eslint-disable-next-line no-use-before-define
                        return pinnedDoc1;
                    },
                ],
                docRemoved: [() => numDocs() < 3, () => viewedLink],
            },
            '/assets/dash-pin-with-view.gif'
        );

        const penMode = InfoState('You\'re in pen mode. Click and drag to draw your first masterpiece.', {
            // activePen: [() => activeTool() === InkTool.Eraser, () => eraserMode],
            activePen: [() => activeTool() !== InkTool.Ink, () => viewedLink],
        }); // prettier-ignore

        // const eraserMode = InfoState('You\'re in eraser mode. Say goodbye to your first masterpiece.', {
        //     docsRemoved: [() => numDocs() == 3, () => demos],
        // }); // prettier-ignore

        const pinnedDoc1 = InfoState('You just pinned your doc.', {
            docPinned: [
                () => pin().length > trail,
                () => {
                    trail = pin().length;
                    // eslint-disable-next-line no-use-before-define
                    return pinnedDoc2;
                },
            ],
            // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            // manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
            // eslint-disable-next-line no-use-before-define
            autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
            docRemoved: [() => numDocs() < 3, () => viewedLink],
        });

        const pinnedDoc2 = InfoState(`You pinned another doc.`, {
            docPinned: [
                () => pin().length > trail,
                () => {
                    trail = pin().length;
                    // eslint-disable-next-line no-use-before-define
                    return pinnedDoc3;
                },
            ],
            // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            // manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
            // eslint-disable-next-line no-use-before-define
            autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
            docRemoved: [() => numDocs() < 3, () => viewedLink],
        });

        const pinnedDoc3 = InfoState(`You pinned yet another doc.`, {
            docPinned: [
                () => pin().length > trail,
                () => {
                    trail = pin().length;
                    return pinnedDoc2;
                },
            ],
            // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            // manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
            // eslint-disable-next-line no-use-before-define
            autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
            docRemoved: [() => numDocs() < 3, () => viewedLink],
        });

        // const openedTrail = InfoState('This is your trails tab.', {
        //     trailView: [() => presentationMode() === 'edit', () => editPresentationMode],
        // });

        // const editPresentationMode = InfoState('You are editing your presentation.', {
        //     manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
        //     autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
        //     docRemoved: [() => numDocs() < 3, () => demos],
        //     docCreated: [() => numDocs() == 4, () => completed],
        // });

        const manualPresentationMode = InfoState("You're in manual presentation mode.", {
            // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            // eslint-disable-next-line no-use-before-define
            autoPresentation: [() => presentationMode() === 'auto', () => autoPresentationMode],
            docRemoved: [() => numDocs() < 3, () => viewedLink],
            // eslint-disable-next-line no-use-before-define
            docCreated: [() => numDocs() === 4, () => completed],
        });

        const autoPresentationMode = InfoState("You're in auto presentation mode.", {
            // editPresentation: [() => presentationMode() === 'edit', () => editPresentationMode],
            manualPresentation: [() => presentationMode() === 'manual', () => manualPresentationMode],
            docRemoved: [() => numDocs() < 3, () => viewedLink],
            // eslint-disable-next-line no-use-before-define
            docCreated: [() => numDocs() === 4, () => completed],
        });

        const completed = InfoState(
            'Eager to learn more? Click the ? icon in the top right corner to read our full documentation.',
            { docRemoved: [() => numDocs() === 1, () => oneDoc] },
            'documentation.png',
            () => TopBar.Instance.FlipDocumentationIcon()
        ); // prettier-ignore

        return start;
    };

    render() {
        return !this.currState ? null : <CollectionFreeFormInfoState next={this.setCurrState} close={this._props.close} infoState={this.currState} />;
    }
}