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>;
}
}
|