aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/BranchingTrailManager.tsx
blob: 44cec69223ebc05370625fa5366b08192d9c987b (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
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { PresBox } from '../views/nodes/trails';
import { OverlayView } from '../views/OverlayView';
import { DocumentManager } from './DocumentManager';

@observer
export class BranchingTrailManager extends React.Component {
    public static Instance: BranchingTrailManager;

    constructor(props: any) {
        super(props);
        if (!BranchingTrailManager.Instance) {
            BranchingTrailManager.Instance = this;
        }
    }

    setupUi = () => {
        OverlayView.Instance.addWindow(<BranchingTrailManager></BranchingTrailManager>, { x: 100, y: 150, width: 1000, title: 'Branching Trail' });
    };

    // stack of the history
    @observable private slideHistoryStack: String[] = [];
    @action setSlideHistoryStack = action((newArr: String[]) => {
        this.slideHistoryStack = newArr;
    });

    @observable private containsSet: Set<String> = new Set<String>();

    // prev pres to copmare with
    @observable private prevPresId: String | null = null;
    @action setPrevPres = action((newId: String | null) => {
        this.prevPresId = newId;
    });

    // docId to Doc map
    @observable private docIdToDocMap: Map<String, Doc> = new Map<String, Doc>();

    observeDocumentChange = (targetDoc: Doc, pres: PresBox) => {
        const presId = pres.props.Document[Id];
        if (this.prevPresId === presId) {
            return;
        }

        const targetDocId = targetDoc[Id];
        this.docIdToDocMap.set(targetDocId, targetDoc);

        if (this.prevPresId === null) {
            this.setupUi();
        }

        if (this.prevPresId === null || this.prevPresId !== presId) {
            this.setPrevPres(presId);
            // REVERT THE SET
            const stringified = [presId, targetDocId].toString();
            if (this.containsSet.has([presId, targetDocId].toString())) {
                // remove all the elements after the targetDocId
                const newStack = this.slideHistoryStack.slice(0, this.slideHistoryStack.indexOf(stringified));
                const removed = this.slideHistoryStack.slice(this.slideHistoryStack.indexOf(stringified));
                this.setSlideHistoryStack(newStack);

                removed.forEach(info => this.containsSet.delete(info.toString()));
            } else {
                this.setSlideHistoryStack([...this.slideHistoryStack, stringified]);
                this.containsSet.add(stringified);
            }
        }
    };

    clickHandler = (e: React.PointerEvent<HTMLButtonElement>, targetDocId: string, removeIndex: number) => {
        const targetDoc = this.docIdToDocMap.get(targetDocId);
        if (!targetDoc) {
            return;
        }
        const newStack = this.slideHistoryStack.slice(0, removeIndex);
        const removed = this.slideHistoryStack.slice(removeIndex);
        this.setSlideHistoryStack(newStack);

        removed.forEach(info => this.containsSet.delete(info.toString()));
        DocumentManager.Instance.showDocument(targetDoc, { willZoomCentered: true });
        //PresBox.NavigateToTarget(targetDoc, targetDoc);
    };

    @computed get trailBreadcrumbs() {
        return (
            <div style={{ border: '.5rem solid green', padding: '5px', backgroundColor: 'white', minHeight: '50px' }}>
                {this.slideHistoryStack.map((info, index) => {
                    const [presId, targetDocId] = info.split(',');
                    const doc = this.docIdToDocMap.get(targetDocId);
                    if (!doc) {
                        return <></>;
                    }
                    return (
                        <span key={targetDocId}>
                            <button key={index} onPointerDown={e => this.clickHandler(e, targetDocId, index)}>
                                {presId.slice(0, 3) + ':' + doc.title}
                            </button>
                            -{'>'}
                        </span>
                    );
                })}
            </div>
        );
    }

    render() {
        return <div>{BranchingTrailManager.Instance.trailBreadcrumbs}</div>;
    }
}