aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/BranchingTrailManager.tsx112
-rw-r--r--src/client/util/CurrentUserUtils.ts12
-rw-r--r--src/client/util/RTFMarkup.tsx3
-rw-r--r--src/client/util/SettingsManager.tsx30
-rw-r--r--src/client/views/Main.tsx2
-rw-r--r--src/client/views/PropertiesView.scss7
-rw-r--r--src/client/views/PropertiesView.tsx30
-rw-r--r--src/client/views/StyleProvider.tsx4
-rw-r--r--src/client/views/collections/TreeView.scss19
-rw-r--r--src/client/views/collections/TreeView.tsx65
-rw-r--r--src/client/views/newlightbox/components/Recommendation/Recommendation.tsx4
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx2
-rw-r--r--src/client/views/nodes/ImageBox.tsx1
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx23
-rw-r--r--src/client/views/nodes/trails/PresElementBox.scss4
-rw-r--r--src/client/views/nodes/trails/PresElementBox.tsx45
-rw-r--r--src/server/server_Initialization.ts4
17 files changed, 332 insertions, 35 deletions
diff --git a/src/client/util/BranchingTrailManager.tsx b/src/client/util/BranchingTrailManager.tsx
new file mode 100644
index 000000000..44cec6922
--- /dev/null
+++ b/src/client/util/BranchingTrailManager.tsx
@@ -0,0 +1,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>;
+ }
+}
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 54828867e..2e83a1655 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -294,7 +294,7 @@ export class CurrentUserUtils {
{ toolTip: "Tap or drag to create a note", title: "Note", icon: "sticky-note", dragFactory: doc.emptyNote as Doc, clickFactory: DocCast(doc.emptyNote)},
{ toolTip: "Tap or drag to create a flashcard", title: "Flashcard", icon: "id-card", dragFactory: doc.emptyFlashcard as Doc, clickFactory: DocCast(doc.emptyFlashcard)},
{ toolTip: "Tap or drag to create an equation", title: "Math", icon: "calculator", dragFactory: doc.emptyEquation as Doc, clickFactory: DocCast(doc.emptyEquation)},
- { toolTip: "Tap or drag to create a physics simulation",title: "Simulation", icon: "rocket",dragFactory: doc.emptySimulation as Doc, clickFactory: DocCast(doc.emptySimulation)},
+ { toolTip: "Tap or drag to create a physics simulation",title: "Simulation", icon: "rocket",dragFactory: doc.emptySimulation as Doc, clickFactory: DocCast(doc.emptySimulation), funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a note board", title: "Notes", icon: "folder", dragFactory: doc.emptyNoteboard as Doc, clickFactory: DocCast(doc.emptyNoteboard)},
{ toolTip: "Tap or drag to create a collection", title: "Col", icon: "folder", dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab)},
{ toolTip: "Tap or drag to create a webpage", title: "Web", icon: "globe-asia", dragFactory: doc.emptyWebpage as Doc, clickFactory: DocCast(doc.emptyWebpage)},
@@ -304,12 +304,12 @@ export class CurrentUserUtils {
{ toolTip: "Tap or drag to create a screen grabber", title: "Grab", icon: "photo-video", dragFactory: doc.emptyScreengrab as Doc, clickFactory: DocCast(doc.emptyScreengrab), openFactoryLocation: OpenWhere.overlay},
{ toolTip: "Tap or drag to create a WebCam recorder", title: "WebCam", icon: "photo-video", dragFactory: doc.emptyWebCam as Doc, clickFactory: DocCast(doc.emptyWebCam), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
{ toolTip: "Tap or drag to create a button", title: "Button", icon: "bolt", dragFactory: doc.emptyButton as Doc, clickFactory: DocCast(doc.emptyButton)},
- { toolTip: "Tap or drag to create a scripting box", title: "Script", icon: "terminal", dragFactory: doc.emptyScript as Doc, clickFactory: DocCast(doc.emptyScript)},
- { toolTip: "Tap or drag to create a data viz node", title: "DataViz", icon: "chart-bar", dragFactory: doc.emptyDataViz as Doc, clickFactory: DocCast(doc.emptyDataViz)},
- { toolTip: "Tap or drag to create a bullet slide", title: "PPT Slide", icon: "file", dragFactory: doc.emptySlide as Doc, clickFactory: DocCast(doc.emptySlide), openFactoryLocation: OpenWhere.overlay},
- { toolTip: "Tap or drag to create a data note", title: "DataNote", icon: "window-maximize",dragFactory: doc.emptyHeader as Doc,clickFactory: DocCast(doc.emptyHeader), openFactoryAsDelegate: true },
+ { toolTip: "Tap or drag to create a scripting box", title: "Script", icon: "terminal", dragFactory: doc.emptyScript as Doc, clickFactory: DocCast(doc.emptyScript), funcs: { hidden: "IsNoviceMode()"}},
+ { toolTip: "Tap or drag to create a data viz node", title: "DataViz", icon: "chart-bar", dragFactory: doc.emptyDataViz as Doc, clickFactory: DocCast(doc.emptyDataViz)},
+ { toolTip: "Tap or drag to create a bullet slide", title: "PPT Slide", icon: "file", dragFactory: doc.emptySlide as Doc, clickFactory: DocCast(doc.emptySlide), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
+ { toolTip: "Tap or drag to create a data note", title: "DataNote", icon: "window-maximize",dragFactory: doc.emptyHeader as Doc,clickFactory: DocCast(doc.emptyHeader), openFactoryAsDelegate: true, funcs: { hidden: "IsNoviceMode()"} },
{ toolTip: "Toggle a Calculator REPL", title: "replviewer", icon: "calculator", clickFactory: '<ScriptingRepl />' as any, openFactoryLocation: OpenWhere.overlay}, // hack: clickFactory is not a Doc but will get interpreted as a custom UI by the openDoc() onClick script
- { toolTip: "Toggle an UndoStack", title: "undostacker", icon: "calculator", clickFactory: "<UndoStack>" as any, openFactoryLocation: OpenWhere.overlay},
+ // { toolTip: "Toggle an UndoStack", title: "undostacker", icon: "calculator", clickFactory: "<UndoStack>" as any, openFactoryLocation: OpenWhere.overlay},
].map(tuple => (
{ openFactoryLocation: OpenWhere.addRight,
scripts: { onClick: 'openDoc(copyDragFactory(this.clickFactory,this.openFactoryAsDelegate), this.openFactoryLocation)',
diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx
index c2f121e1f..afc880a7b 100644
--- a/src/client/util/RTFMarkup.tsx
+++ b/src/client/util/RTFMarkup.tsx
@@ -2,6 +2,7 @@ import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { MainViewModal } from '../views/MainViewModal';
+import { SettingsManager } from './SettingsManager';
@observer
export class RTFMarkup extends React.Component<{}> {
@@ -30,7 +31,7 @@ export class RTFMarkup extends React.Component<{}> {
*/
@computed get cheatSheet() {
return (
- <div style={{ background: 'white', textAlign: 'initial', height: '100%' }}>
+ <div style={{ background: SettingsManager.Instance.userBackgroundColor, color: SettingsManager.Instance.userColor, textAlign: 'initial', height: '100%' }}>
<p>
<b style={{ fontSize: 'larger' }}>{`wiki:phrase`}</b>
{` display wikipedia page for entered text (terminate with carriage return)`}
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 6acba8af4..a2e5e54fe 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -169,9 +169,33 @@ export class SettingsManager extends React.Component<{}> {
/>
{userTheme === ColorScheme.Custom && (
<Group formLabel="Custom Theme">
- <ColorPicker tooltip={'User Color'} color={this.userColor} type={Type.SEC} icon={<FaFillDrip />} selectedColor={this.userColor} setSelectedColor={this.switchUserColor} />
- <ColorPicker tooltip={'User Background Color'} color={this.userColor} type={Type.SEC} icon={<FaPalette />} selectedColor={this.userBackgroundColor} setSelectedColor={this.switchUserBackgroundColor} />
- <ColorPicker tooltip={'User Variant Color'} color={this.userColor} type={Type.SEC} icon={<FaPalette />} selectedColor={this.userVariantColor} setSelectedColor={this.switchUserVariantColor} />
+ <ColorPicker
+ tooltip={'User Color'} //
+ color={this.userColor}
+ type={Type.SEC}
+ icon={<FaFillDrip />}
+ selectedColor={this.userColor}
+ setSelectedColor={this.switchUserColor}
+ setFinalColor={this.switchUserColor}
+ />
+ <ColorPicker
+ tooltip={'User Background Color'}
+ color={this.userColor}
+ type={Type.SEC}
+ icon={<FaPalette />}
+ selectedColor={this.userBackgroundColor}
+ setSelectedColor={this.switchUserBackgroundColor}
+ setFinalColor={this.switchUserBackgroundColor}
+ />
+ <ColorPicker
+ tooltip={'User Variant Color'}
+ color={this.userColor}
+ type={Type.SEC}
+ icon={<FaPalette />}
+ selectedColor={this.userVariantColor}
+ setSelectedColor={this.switchUserVariantColor}
+ setFinalColor={this.switchUserVariantColor}
+ />
</Group>
)}
</div>
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 6dd1d53ee..730a926a2 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -12,6 +12,7 @@ import { TrackMovements } from '../util/TrackMovements';
import { CollectionView } from './collections/CollectionView';
import { MainView } from './MainView';
import * as dotenv from 'dotenv'; // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import
+import { BranchingTrailManager } from '../util/BranchingTrailManager';
import { PingManager } from '../util/PingManager';
import './global/globalScripts';
dotenv.config();
@@ -50,6 +51,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' };
document.cookie = `loadtime=${loading};${expires};path=/`;
new TrackMovements();
new ReplayMovements();
+ new BranchingTrailManager();
new PingManager();
root.render(<MainView />);
}, 0);
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
index 1a7c9eb64..a0b054851 100644
--- a/src/client/views/PropertiesView.scss
+++ b/src/client/views/PropertiesView.scss
@@ -1,5 +1,12 @@
@import './global/globalCssVariables.scss';
+.propertiesView-presentationTrails-title {
+ display: flex;
+}
+.propertiesView-presentationTrails-title-icon {
+ position: absolute;
+ right: 4;
+}
.propertiesView {
height: 100%;
width: 250;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 1b6037ed9..82ab54787 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -39,6 +39,7 @@ import { DefaultStyleProvider } from './StyleProvider';
import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView';
import { KeyValueBox } from './nodes/KeyValueBox';
import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails';
+import { SettingsManager } from '../util/SettingsManager';
const higflyout = require('@hig/flyout');
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -1701,7 +1702,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</div>
{!selectedItem ? null : (
<div className="propertiesView-presentationTrails">
- <div className="propertiesView-presentationTrails-title" onPointerDown={action(() => (this.openPresTransitions = !this.openPresTransitions))} style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
+ <div
+ className="propertiesView-presentationTrails-title"
+ onPointerDown={action(() => (this.openPresTransitions = !this.openPresTransitions))}
+ style={{
+ color: SettingsManager.Instance.userColor,
+ backgroundColor: this.openPresTransitions ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor,
+ }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Transitions
<div className="propertiesView-presentationTrails-title-icon">
<FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg" />
@@ -1715,7 +1722,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<div
className="propertiesView-presentationTrails-title"
onPointerDown={action(() => (this.openPresVisibilityAndDuration = !this.openPresVisibilityAndDuration))}
- style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
+ style={{
+ color: SettingsManager.Instance.userColor,
+ backgroundColor: this.openPresVisibilityAndDuration ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor,
+ }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Visibilty
<div className="propertiesView-presentationTrails-title-icon">
<FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" />
@@ -1726,7 +1736,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
)}
{!selectedItem ? null : (
<div className="propertiesView-presentationTrails">
- <div className="propertiesView-presentationTrails-title" onPointerDown={action(() => (this.openPresProgressivize = !this.openPresProgressivize))} style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
+ <div
+ className="propertiesView-presentationTrails-title"
+ onPointerDown={action(() => (this.openPresProgressivize = !this.openPresProgressivize))}
+ style={{
+ color: SettingsManager.Instance.userColor,
+ backgroundColor: this.openPresProgressivize ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor,
+ }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Progressivize
<div className="propertiesView-presentationTrails-title-icon">
<FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg" />
@@ -1737,7 +1753,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
)}
{!selectedItem || (type !== DocumentType.VID && type !== DocumentType.AUDIO) ? null : (
<div className="propertiesView-presentationTrails">
- <div className="propertiesView-presentationTrails-title" onPointerDown={action(() => (this.openSlideOptions = !this.openSlideOptions))} style={{ backgroundColor: this.openSlideOptions ? 'black' : '' }}>
+ <div
+ className="propertiesView-presentationTrails-title"
+ onPointerDown={action(() => (this.openSlideOptions = !this.openSlideOptions))}
+ style={{
+ color: SettingsManager.Instance.userColor,
+ backgroundColor: this.openSlideOptions ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor,
+ }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={type === DocumentType.AUDIO ? 'file-audio' : 'file-video'} /> &nbsp; {type === DocumentType.AUDIO ? 'Audio Options' : 'Video Options'}
<div className="propertiesView-presentationTrails-title-icon">
<FontAwesomeIcon icon={this.openSlideOptions ? 'caret-down' : 'caret-right'} size="lg" />
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index c2dcf071d..46243d50a 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -239,12 +239,12 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
switch (doc?.type) {
case DocumentType.COL:
return StrCast(
- doc?.layout_borderRounding,
+ doc?.layout_boxShadow,
doc?._type_collection === CollectionViewType.Pile
? '4px 4px 10px 2px'
: lockedPosition() || doc?._isGroup || docProps?.LayoutTemplateString
? undefined // groups have no drop shadow -- they're supposed to be "invisible". LayoutString's imply collection is being rendered as something else (e.g., title of a Slide)
- : `${darkScheme() ? Colors.DARK_GRAY : Colors.MEDIUM_GRAY} ${StrCast(doc.layout_borderRounding, '0.2vw 0.2vw 0.8vw')}`
+ : `${darkScheme() ? Colors.DARK_GRAY : Colors.MEDIUM_GRAY} ${StrCast(doc.layout_boxShadow, '0.2vw 0.2vw 0.8vw')}`
);
case DocumentType.LABEL:
diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss
index d22e85880..d3ba23b4e 100644
--- a/src/client/views/collections/TreeView.scss
+++ b/src/client/views/collections/TreeView.scss
@@ -23,6 +23,25 @@
.treeView-bulletIcons {
width: 100%;
height: 100%;
+ // position: absolute;
+
+ .treeView-expandIcon {
+ display: none;
+ left: -8px;
+ position: absolute;
+ }
+
+ .treeView-checkIcon {
+ left: 3.5px;
+ top: 2px;
+ position: absolute;
+ }
+
+ &:hover {
+ .treeView-expandIcon {
+ display: unset;
+ }
+ }
position: relative;
display: flex;
flex-direction: row;
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 27f9ebc49..a3725be75 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -2,7 +2,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
-import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc';
+import { Doc, DocListCast, Field, FieldResult, Opt, StrListCast } from '../../../fields/Doc';
import { DocData, Height, Width } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
@@ -227,6 +227,39 @@ export class TreeView extends React.Component<TreeViewProps> {
}
};
+ @undoBatch
+ @action
+ recurToggle = (childList: Doc[]) => {
+ if (childList.length > 0) {
+ childList.forEach(child => {
+ console.log(child);
+ child.runProcess = !!!child.runProcess;
+ TreeView.ToggleChildrenRun.get(child)?.();
+ });
+ }
+ };
+
+ @undoBatch
+ @action
+ getRunningChildren = (childList: Doc[]) => {
+ if (childList.length === 0) {
+ return [];
+ }
+
+ const runningChildren: FieldResult[] = [];
+ childList.forEach(child => {
+ if (child.runProcess && TreeView.GetRunningChildren.get(child)) {
+ if (child.runProcess) {
+ runningChildren.push(child);
+ }
+ runningChildren.push(...(TreeView.GetRunningChildren.get(child)?.() ?? []));
+ }
+ });
+ return runningChildren;
+ };
+
+ static GetRunningChildren = new Map<Doc, any>();
+ static ToggleChildrenRun = new Map<Doc, () => void>();
constructor(props: any) {
super(props);
if (!TreeView._openLevelScript) {
@@ -235,6 +268,19 @@ export class TreeView extends React.Component<TreeViewProps> {
}
this._openScript = Doc.IsSystem(this.props.document) ? undefined : () => TreeView._openLevelScript!;
this._editTitleScript = Doc.IsSystem(this.props.document) ? () => TreeView._openLevelScript! : () => TreeView._openTitleScript!;
+
+ // set for child processing highligting
+ // this.dataDoc.testing = 'testing';
+ console.log(this.doc, this.dataDoc, this.childDocs);
+ this.dataDoc.hasChildren = this.childDocs.length > 0;
+ // this.dataDoc.children = this.childDocs;
+ TreeView.ToggleChildrenRun.set(this.doc, () => {
+ this.recurToggle(this.childDocs);
+ });
+
+ TreeView.GetRunningChildren.set(this.doc, () => {
+ return this.getRunningChildren(this.childDocs);
+ });
}
_treeEle: any;
@@ -722,15 +768,14 @@ export class TreeView extends React.Component<TreeViewProps> {
)
) : (
<div className="treeView-bulletIcons" style={{ color: Doc.IsSystem(DocCast(this.doc.proto)) ? 'red' : undefined }}>
- {this.onCheckedClick ? (
- <IconButton
- color={color}
- icon={<FontAwesomeIcon size="sm" icon={checked === 'check' ? 'check' : checked === 'x' ? 'times' : checked === 'unchecked' ? 'square' : !this.treeViewOpen ? 'caret-right' : 'caret-down'} />}
- size={Size.XSMALL}
+ <div className={`treeView-${this.onCheckedClick ? 'checkIcon' : 'expandIcon'}`}>
+ <FontAwesomeIcon
+ size="sm"
+ style={{ display: this.childDocs?.length >= 1 ? 'block' : 'none' }}
+ icon={checked === 'check' ? 'check' : checked === 'x' ? 'times' : checked === 'unchecked' ? 'square' : !this.treeViewOpen ? 'caret-right' : 'caret-down'}
/>
- ) : (
- <IconButton color={color} icon={<FontAwesomeIcon icon={iconType as IconProp} />} size={Size.XSMALL} />
- )}
+ </div>
+ {this.onCheckedClick ? null : typeof iconType === 'string' ? <FontAwesomeIcon icon={iconType as IconProp} /> : iconType}
</div>
)}
</div>
@@ -928,8 +973,8 @@ export class TreeView extends React.Component<TreeViewProps> {
}
})}
Document={this.doc}
+ DataDoc={undefined} // or this.dataDoc?
layout_fitWidth={returnTrue}
- DataDoc={undefined}
scriptContext={this}
hideDecorationTitle={this.props.treeView.outlineMode}
hideResizeHandles={this.props.treeView.outlineMode}
diff --git a/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx b/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx
index 2c2f04b9f..96846673b 100644
--- a/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx
+++ b/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx
@@ -25,11 +25,11 @@ export const Recommendation = (props: IRecommendation) => {
switch (type) {
case 'YouTube':
console.log('create ', type, 'document');
- doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript: transcript });
+ doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript });
break;
case 'Video':
console.log('create ', type, 'document');
- doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript: transcript });
+ doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript });
break;
case 'Webpage':
console.log('create ', type, 'document');
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index ca5ec9389..a334e75f1 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -96,7 +96,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
const anchor = Docs.Create.ConfigDocument({
title: 'CompareAnchor:' + this.rootDoc.title,
// set presentation timing properties for restoring view
- presTransition: 1000,
+ presentation_transition: 1000,
annotationOn: this.rootDoc,
});
if (anchor) {
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index c7ccd1ea0..44da98f75 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -82,7 +82,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
config_panX: NumCast(this.layoutDoc._freeform_panX),
config_panY: NumCast(this.layoutDoc._freeform_panY),
config_viewScale: Cast(this.layoutDoc._freeform_scale, 'number', null),
- presentation_transition: 1000,
annotationOn: this.rootDoc,
});
if (anchor) {
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 05f59d8fe..b02e7ecbd 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -36,6 +36,8 @@ import { FieldView, FieldViewProps } from '../FieldView';
import { ScriptingBox } from '../ScriptingBox';
import './PresBox.scss';
import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums';
+import { BranchingTrailManager } from '../../../util/BranchingTrailManager';
+import { TreeView } from '../../collections/TreeView';
const { Howl } = require('howler');
export interface pinDataTypes {
@@ -256,7 +258,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const serial = nextSelected + 1 < this.childDocs.length && NumCast(this.childDocs[nextSelected + 1].presentation_groupWithUp) > 1;
if (serial) {
this.gotoDocument(nextSelected, this.activeItem, true, async () => {
- const waitTime = NumCast(this.activeItem.presentation_duration) - NumCast(this.activeItem.presentation_transition);
+ const waitTime = NumCast(this.activeItem.presentation_duration);
await new Promise<void>(res => setTimeout(() => res(), Math.max(0, waitTime)));
doGroupWithUp(nextSelected + 1)();
});
@@ -279,6 +281,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return listItems.filter(doc => !doc.layout_unrendered);
}
};
+
+ // go to documents chain
+ runSubroutines = (childrenToRun: Doc[], normallyNextSlide: Doc) => {
+ console.log(childrenToRun, normallyNextSlide, 'runSUBFUNC');
+ if (childrenToRun[0] === normallyNextSlide) {
+ return;
+ }
+
+ childrenToRun.forEach(child => {
+ DocumentManager.Instance.showDocument(child, {});
+ });
+ };
+
// Called when the user activates 'next' - to move to the next part of the pres. trail
@action
next = () => {
@@ -319,6 +334,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// Case 1: No more frames in current doc and next slide is defined, therefore move to next slide
const slides = DocListCast(this.rootDoc[StrCast(this.presFieldKey, 'data')]);
const curLast = this.selectedArray.size ? Math.max(...Array.from(this.selectedArray).map(d => slides.indexOf(DocCast(d)))) : this.itemIndex;
+
+ // before moving onto next slide, run the subroutines :)
+ const currentDoc = this.childDocs[this.itemIndex];
+ this.runSubroutines(TreeView.GetRunningChildren.get(currentDoc)?.(), this.childDocs[this.itemIndex + 1]);
+
this.nextSlide(curLast + 1 === this.childDocs.length ? (this.layoutDoc.presLoop ? 0 : curLast) : curLast + 1);
progressiveReveal(true); // shows first progressive document, but without a transition effect
} else {
@@ -691,6 +711,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
navigateToActiveItem = (afterNav?: () => void) => {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
+ BranchingTrailManager.Instance.observeDocumentChange(targetDoc, this);
const finished = () => {
afterNav?.();
console.log('Finish Slide Nav: ' + targetDoc.title);
diff --git a/src/client/views/nodes/trails/PresElementBox.scss b/src/client/views/nodes/trails/PresElementBox.scss
index 4f95f0c1f..9ac2b5a94 100644
--- a/src/client/views/nodes/trails/PresElementBox.scss
+++ b/src/client/views/nodes/trails/PresElementBox.scss
@@ -4,6 +4,10 @@ $light-background: #ececec;
$slide-background: #d5dce2;
$slide-active: #5b9fdd;
+.testingv2 {
+ background-color: red;
+}
+
.presItem-container {
cursor: grab;
display: flex;
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 5de51dbe9..6bc1e95ac 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -25,6 +25,7 @@ import { PresBox } from './PresBox';
import './PresElementBox.scss';
import { PresMovement } from './PresEnums';
import React = require('react');
+import { TreeView } from '../../collections/TreeView';
/**
* This class models the view a document added to presentation will have in the presentation.
* It involves some functionality for its buttons and options.
@@ -399,6 +400,19 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
};
+ @undoBatch
+ @action
+ lfg = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ console.log('lfg called');
+ // TODO: fix this bug
+ const { toggleChildrenRun } = this.rootDoc;
+ TreeView.ToggleChildrenRun.get(this.rootDoc)?.();
+
+ // call this.rootDoc.recurChildren() to get all the children
+ // if (iconClick) PresElementBox.showVideo = false;
+ };
+
@computed
get toolbarWidth(): number {
const presBoxDocView = DocumentManager.Instance.getDocumentView(this.presBox);
@@ -414,6 +428,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
const presColorBool: boolean = presBoxColor ? presBoxColor !== Colors.WHITE && presBoxColor !== 'transparent' : false;
const targetDoc: Doc = this.targetDoc;
const activeItem: Doc = this.rootDoc;
+ const hasChildren: boolean = Cast(this.rootDoc?.hasChildren, 'boolean') || false;
const items: JSX.Element[] = [];
items.push(
@@ -445,7 +460,17 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
);
if (this.indexInPres !== 0) {
items.push(
- <Tooltip key="arrow" title={<div className="dash-tooltip">{activeItem.presentation_groupWithUp ? 'Ungroup' : 'Group with up'}</div>}>
+ <Tooltip
+ key="arrow"
+ title={
+ <div className="dash-tooltip">
+ {!activeItem.presentation_groupWithUp
+ ? 'Not grouped with previous slide (click to group)'
+ : activeItem.presentation_groupWithUp === 1
+ ? 'Run simultaneously with previous slide (click again to run after)'
+ : 'Run after previous slide (click to ungroup from previous)'}
+ </div>
+ }>
<div
className="slideButton"
onClick={() => (activeItem.presentation_groupWithUp = (NumCast(activeItem.presentation_groupWithUp) + 1) % 3)}
@@ -476,6 +501,22 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
</Tooltip>
);
+ if (!Doc.noviceMode && hasChildren) {
+ // TODO: replace with if treeveiw, has childrenDocs
+ items.push(
+ <Tooltip key="children" title={<div className="dash-tooltip">Run child processes (tree only)</div>}>
+ <div
+ className="slideButton"
+ onClick={e => {
+ e.stopPropagation();
+ this.lfg(e);
+ }}
+ style={{ fontWeight: 700 }}>
+ <FontAwesomeIcon icon={'circle-play'} onPointerDown={e => e.stopPropagation()} />
+ </div>
+ </Tooltip>
+ );
+ }
items.push(
<Tooltip key="trash" title={<div className="dash-tooltip">Remove from presentation</div>}>
<div className={'slideButton'} onClick={this.removePresentationItem}>
@@ -522,7 +563,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
) : (
<div
ref={this._dragRef}
- className={`presItem-slide ${isCurrent ? 'active' : ''}`}
+ className={`presItem-slide ${isCurrent ? 'active' : ''}${this.rootDoc.runProcess ? ' testingv2' : ''}`}
style={{
display: 'infline-block',
backgroundColor: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor),
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index 354f809e0..ee32de152 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -176,8 +176,8 @@ function proxyServe(req: any, requrl: string, response: any) {
const htmlText = htmlInputText
.toString('utf8')
.replace('<head>', '<head> <style>[id ^= "google"] { display: none; } </style>')
- .replace('<script', '<noscript')
- .replace('</script', '</noscript')
+ // .replace('<script', '<noscript')
+ // .replace('</script', '</noscript')
// .replace(/href="https?([^"]*)"/g, httpsToCors)
.replace(/data-srcset="[^"]*"/g, '')
.replace(/srcset="[^"]*"/g, '')