aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/DragManager.ts3
-rw-r--r--src/client/views/DocumentDecorations.tsx2
-rw-r--r--src/client/views/MainOverlayTextBox.tsx5
-rw-r--r--src/client/views/MainView.tsx2
-rw-r--r--src/client/views/OverlayView.tsx31
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx1
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx90
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx1
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx12
-rw-r--r--src/client/views/nodes/ImageBox.scss1
-rw-r--r--src/new_fields/Doc.ts6
-rw-r--r--src/server/authentication/models/current_user_utils.ts6
13 files changed, 107 insertions, 55 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 748fb9d13..4c9c9c17c 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -252,7 +252,7 @@ export namespace DragManager {
});
}
- export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], downX: number, downY: number, options?: DragOptions) {
+ export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize?: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) {
let dragData = new DragManager.DocumentDragData([], [undefined]);
runInAction(() => StartDragFunctions.map(func => func()));
StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag :
@@ -268,6 +268,7 @@ export namespace DragManager {
bd.onClick = scriptField;
}
params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc)));
+ initialize && initialize(bd);
bd.buttonParams = new List<string>(params);
dropData.droppedDocuments = [bd];
});
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index bd510c3c5..579806a89 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -1,7 +1,7 @@
import { library, IconProp } from '@fortawesome/fontawesome-svg-core';
import { faLink, faTag, faTimes, faArrowAltCircleDown, faArrowAltCircleUp, faCheckCircle, faStopCircle, faCloudUploadAlt, faSyncAlt, faShare } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable, reaction, runInAction } from "mobx";
+import { action, computed, observable, reaction, runInAction, trace } from "mobx";
import { observer } from "mobx-react";
import { Doc } from "../../new_fields/Doc";
import { List } from "../../new_fields/List";
diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx
index 0839e1114..e95e5b777 100644
--- a/src/client/views/MainOverlayTextBox.tsx
+++ b/src/client/views/MainOverlayTextBox.tsx
@@ -59,7 +59,7 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
let sxf = Utils.GetScreenTransform(box ? box.CurrentDiv : undefined);
return new Transform(-sxf.translateX, -sxf.translateY, 1 / sxf.scale);
};
- this.setTextDoc(box.props.fieldKey, box.CurrentDiv, xf, BoolCast(box.props.Document.autoHeight, false) || box.props.height === "min-content");
+ this.setTextDoc(box.props.fieldKey, box.CurrentDiv, xf, BoolCast(box.props.Document.autoHeight) || box.props.height === "min-content");
}
else {
this.TextDoc = undefined;
@@ -131,10 +131,11 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
this.TextDoc; this.TextDataDoc;
if (FormattedTextBox.InputBoxOverlay && this._textTargetDiv) {
let wid = FormattedTextBox.InputBoxOverlay.props.Document.width; // need to force overlay to render when underlying text box is resized (eg, w/ DocDecorations)
+ let hgtx = FormattedTextBox.InputBoxOverlay.props.Document.height; // need to force overlay to render when underlying text box is resized (eg, w/ DocDecorations)
let textRect = this._textTargetDiv.getBoundingClientRect();
let s = this._textXf().Scale;
let location = this._textBottom ? textRect.bottom : textRect.top;
- let hgt = this._textAutoHeight || this._textBottom ? "auto" : this._textTargetDiv.clientHeight;
+ let hgt = (this._textBox && this._textBox.props.Document.autoHeight) || this._textBottom ? "auto" : this._textTargetDiv.clientHeight;
return <div ref={this._setouterdiv} className="mainOverlayTextBox-unscaled_div" style={{ transform: `translate(${textRect.left}px, ${location}px)` }} >
<div className="mainOverlayTextBox-textInput" style={{ transform: `scale(${1 / s})`, width: "auto", height: "0px" }} >
<div className="mainOverlayTextBox-textInput" onPointerDown={this.textBoxDown} ref={this._textProxyDiv} onScroll={this.textScroll}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index f28844009..a02214deb 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -404,7 +404,7 @@ export class MainView extends React.Component {
get mainContent() {
let sidebar = CurrentUserUtils.UserDocument.sidebar;
if (!(sidebar instanceof Doc)) return (null);
- return <div>
+ return <div className="mainContent" style={{ width: "100%", height: "100%", position: "absolute" }}>
<div className="mainView-libraryHandle"
style={{ cursor: "ew-resize", left: `${this.flyoutWidth - 10}px`, backgroundColor: `${StrCast(sidebar.backgroundColor, "lightGray")}` }}
onPointerDown={this.onPointerDown}>
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index 2f2579057..a60dc591c 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -1,9 +1,15 @@
import * as React from "react";
import { observer } from "mobx-react";
import { observable, action } from "mobx";
-import { Utils } from "../../Utils";
+import { Utils, emptyFunction, returnOne, returnTrue, returnEmptyString } from "../../Utils";
import './OverlayView.scss';
+import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
+import { DocListCast, Doc } from "../../new_fields/Doc";
+import { Id } from "../../new_fields/FieldSymbols";
+import { DocumentView } from "./nodes/DocumentView";
+import { Transform } from "../util/Transform";
+import { CollectionFreeFormDocumentView } from "./nodes/CollectionFreeFormDocumentView";
export type OverlayDisposer = () => void;
@@ -134,8 +140,29 @@ export class OverlayView extends React.Component {
render() {
return (
- <div>
+ <div className="overlayView">
{this._elements}
+ {CurrentUserUtils.UserDocument.overlays instanceof Doc && DocListCast(CurrentUserUtils.UserDocument.overlays.data).map(d => (
+ <CollectionFreeFormDocumentView key={d[Id]}
+ Document={d}
+ bringToFront={emptyFunction}
+ addDocument={undefined}
+ removeDocument={undefined}
+ ContentScaling={returnOne}
+ PanelWidth={returnOne}
+ PanelHeight={returnOne}
+ ScreenToLocalTransform={Transform.Identity}
+ renderDepth={1}
+ selectOnLoad={false}
+ parentActive={returnTrue}
+ whenActiveChanged={emptyFunction}
+ focus={emptyFunction}
+ backgroundColor={returnEmptyString}
+ addDocTab={emptyFunction}
+ pinToPres={emptyFunction}
+ ContainingCollectionView={undefined}
+ zoomToScale={emptyFunction}
+ getScale={returnOne} />))}
</div>
);
}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 7e1aacd5d..6e284a76f 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -373,6 +373,7 @@ class TreeView extends React.Component<TreeViewProps> {
return <>
<div className="docContainer" id={`docContainer-${this.props.parentKey}`} ref={reference} onPointerDown={onItemDown}
style={{
+ color: this.props.document.isMinimized ? "red" : "black",
background: Doc.IsBrushed(this.props.document) ? "#06121212" : "0",
outline: BoolCast(this.props.document.workspaceBrush) ? "dashed 1px #06123232" : undefined,
pointerEvents: this.props.active() || SelectionManager.GetIsDragging() ? "all" : "none"
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 15bef39b3..1156d8fa7 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -41,16 +41,31 @@ let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
export class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> {
//(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\)
+ private _buttonizableCommands = [{
+ // title: "set content", script: "getProto(this.target).data = aliasDocs(this.source.map(async p => await p));", params: ["target", "source"], // bcz: doesn't look like we can do async stuff in scripting...
+ title: "set content", script: "getProto(this.target).data = aliasDocs(this.source);", params: ["target", "source"],
+ immediate: (draggedDocs: Doc[]) => Doc.GetProto(this.props.CollectionView.props.Document).data = new List<Doc>(draggedDocs.map((d: any) => Doc.MakeAlias(d)))
+ },
+ {
+ title: "set template", script: "this.target.childLayout = this.source ? this.source[0] : undefined", params: ["target", "source"],
+ immediate: (draggedDocs: Doc[]) => this.props.CollectionView.props.Document.childLayout = draggedDocs.length ? draggedDocs[0] : undefined
+ },
+ {
+ title: "restore view", script: "this.target.panX = this.restoredPanX; this.target.panY = this.restoredPanY; this.target.scale = this.restoredScale;", params: ["target"],
+ immediate: (draggedDocs: Doc[]) => { this.props.CollectionView.props.Document.panX = 0; this.props.CollectionView.props.Document.panY = 0; this.props.CollectionView.props.Document.scale = 1 },
+ initialize: (button: Doc) => { button.restoredPanX = this.props.CollectionView.props.Document.panX; button.restoredPanY = this.props.CollectionView.props.Document.panY; button.restoredScale = this.props.CollectionView.props.Document.scale; }
+ }];
+ private _picker: any;
+ private _commandRef = React.createRef<HTMLInputElement>();
+ private _autosuggestRef = React.createRef<Autosuggest>();
+ @observable private _currentKey: string = "";
@observable private _viewSpecsOpen: boolean = false;
@observable private _dateWithinValue: string = "";
@observable private _dateValue: Date | string = "";
@observable private _keyRestrictions: [JSX.Element, string][] = [];
@observable private suggestions: string[] = [];
- _commandRef = React.createRef<HTMLInputElement>();
@computed private get filterValue() { return Cast(this.props.CollectionView.props.Document.viewSpecScript, ScriptField); }
- private _picker: any;
-
getFilters = (script: string) => {
let re: any = /(!)?\(\(\(doc\.(\w+)\s+&&\s+\(doc\.\w+\s+as\s+\w+\)\.includes\(\"(\w+)\"\)/g;
let arr: any[] = re.exec(script);
@@ -215,25 +230,10 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
subChrome = () => {
switch (this.props.type) {
- case CollectionViewType.Stacking: return (
- <CollectionStackingViewChrome
- key="collchrome"
- CollectionView={this.props.CollectionView}
- type={this.props.type} />);
- case CollectionViewType.Schema: return (
- <CollectionSchemaViewChrome
- key="collchrome"
- CollectionView={this.props.CollectionView}
- type={this.props.type}
- />);
- case CollectionViewType.Tree: return (
- <CollectionTreeViewChrome
- key="collchrome"
- CollectionView={this.props.CollectionView}
- type={this.props.type}
- />);
- default:
- return null;
+ case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
+ case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
+ case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />);
+ default: return null;
}
}
@@ -286,21 +286,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
}
}
-
- commands = [{
- // title: "set content", script: "getProto(this.target).data = aliasDocs(this.source.map(async p => await p));", params: ["target", "source"], // bcz: doesn't look like we can do async stuff in scripting...
- title: "set content", script: "getProto(this.target).data = aliasDocs(this.source);", params: ["target", "source"],
- immediate: (draggedDocs: Doc[]) => Doc.GetProto(this.props.CollectionView.props.Document).data = new List<Doc>(draggedDocs)
- },
- {
- title: "set template", script: "this.target.childLayout = this.source ? this.source[0] : undefined", params: ["target", "source"],
- immediate: (draggedDocs: Doc[]) => this.props.CollectionView.props.Document.childLayout = draggedDocs.length ? draggedDocs[0] : undefined
- }];
@undoBatch
@action
protected drop(e: Event, de: DragManager.DropEvent): boolean {
if (de.data instanceof DragManager.DocumentDragData && de.data.draggedDocuments.length) {
- this.commands.filter(c => c.title === this._currentKey).map(c => c.immediate(de.data.draggedDocuments));
+ this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate(de.data.draggedDocuments));
e.stopPropagation();
}
return true;
@@ -319,8 +309,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
}
}
}
- @observable private _currentKey: string = "";
- private autosuggestRef = React.createRef<Autosuggest>();
renderSuggestion = (suggestion: string) => {
return <p>{suggestion}</p>;
@@ -340,21 +328,43 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
this.suggestions = [];
}
getKeySuggestions = async (value: string): Promise<string[]> => {
- return this.commands.filter(c => c.title.indexOf(value) !== -1).map(c => c.title);
+ return this._buttonizableCommands.filter(c => c.title.indexOf(value) !== -1).map(c => c.title);
}
autoSuggestDown = (e: React.PointerEvent) => {
e.stopPropagation();
}
+ private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 };
+ private _sensitivity: number = 16;
+
dragCommandDown = (e: React.PointerEvent) => {
- this.commands.filter(c => c.title === this._currentKey).map(c =>
- DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title,
- { target: this.props.CollectionView.props.Document }, c.params, e.clientX, e.clientY));
+
+ this._startDragPosition = { x: e.clientX, y: e.clientY };
+ document.addEventListener("pointermove", this.dragPointerMove);
+ document.addEventListener("pointerup", this.dragPointerUp);
e.stopPropagation();
e.preventDefault();
}
+ dragPointerMove = (e: PointerEvent) => {
+ e.stopPropagation();
+ e.preventDefault();
+ let [dx, dy] = [e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y];
+ if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
+ this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c =>
+ DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title,
+ { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY));
+ document.removeEventListener("pointermove", this.dragPointerMove);
+ document.removeEventListener("pointerup", this.dragPointerUp);
+ }
+ }
+ dragPointerUp = (e: PointerEvent) => {
+ document.removeEventListener("pointermove", this.dragPointerMove);
+ document.removeEventListener("pointerup", this.dragPointerUp);
+
+ }
+
render() {
let collapsed = this.props.CollectionView.props.Document.chromeStatus !== "enabled";
return (
@@ -439,7 +449,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
renderSuggestion={this.renderSuggestion}
onSuggestionsFetchRequested={this.onSuggestionFetch}
onSuggestionsClearRequested={this.onSuggestionClear}
- ref={this.autosuggestRef} />
+ ref={this._autosuggestRef} />
</div>
</div>
</div>
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 0a2dcbe3b..f185222ce 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -760,7 +760,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
ele: <CollectionFreeFormDocumentView key={doc[Id]}
x={script ? pos.x : undefined} y={script ? pos.y : undefined}
width={script ? pos.width : undefined} height={script ? pos.height : undefined} {...this.getChildDocumentViewProps(pair.layout, pair.data)} />,
- bounds: (pos.x !== undefined && pos.y !== undefined) ? { x: pos.x, y: pos.y, z: pos.z, width: NumCast(pos.width), height: NumCast(pos.height) } : undefined
+ bounds: { x: pos.x || 0, y: pos.y || 0, z: pos.z, width: NumCast(pos.width), height: NumCast(pos.height) }
});
}
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6c944c6b2..3cf86b6f9 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -628,6 +628,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
!existingAnalyze && cm.addItem({ description: "Analyzers...", subitems: analyzers, icon: "hand-point-right" });
cm.addItem({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.Document), icon: "map-pin" }); //I think this should work... and it does! A miracle!
cm.addItem({ description: "Add Repl", icon: "laptop-code", event: () => OverlayView.Instance.addWindow(<ScriptingRepl />, { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" }) });
+ cm.addItem({ description: "Move To Overlay", icon: "laptop-code", event: () => ((o: Doc) => o && Doc.AddDocToList(o, "data", this.props.Document))(Cast(CurrentUserUtils.UserDocument.overlays, Doc) as Doc) });
cm.addItem({
description: "Download document", icon: "download", event: () => {
const a = document.createElement("a");
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 0e04bacf7..876d4c428 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -36,6 +36,7 @@ import { GoogleApiClientUtils, Pulls, Pushes } from '../../apis/google_docs/Goog
import { DocumentDecorations } from '../DocumentDecorations';
import { DictationManager } from '../../util/DictationManager';
import { ReplaceStep } from 'prosemirror-transform';
+import { DocumentType } from '../../documents/DocumentTypes';
library.add(faEdit);
library.add(faSmile, faTextHeight, faUpload);
@@ -256,10 +257,11 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
let model: NodeType = (url.includes(".mov") || url.includes(".mp4")) ? schema.nodes.video : schema.nodes.image;
this._editorView!.dispatch(this._editorView!.state.tr.insert(0, model.create({ src: url })));
e.stopPropagation();
- } else {
- if (de.data instanceof DragManager.DocumentDragData) {
- this.props.Document.layout = de.data.draggedDocuments[0];
- de.data.draggedDocuments[0].isTemplate = true;
+ } else if (de.data instanceof DragManager.DocumentDragData) {
+ const draggedDoc = de.data.draggedDocuments.length && de.data.draggedDocuments[0];
+ if (draggedDoc && draggedDoc.type === DocumentType.TEXT && StrCast(draggedDoc.layout) != "") {
+ this.props.Document.layout = draggedDoc;
+ draggedDoc.isTemplate = true;
e.stopPropagation();
}
}
@@ -796,7 +798,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
tryUpdateHeight() {
const ChromeHeight = this.props.ChromeHeight;
let sh = this._ref.current ? this._ref.current.scrollHeight : 0;
- if (this.props.Document.autoHeight && sh !== 0) {
+ if (!this.props.isOverlay && this.props.Document.autoHeight && sh !== 0) {
let nh = this.props.Document.isTemplate ? 0 : NumCast(this.dataDoc.nativeHeight, 0);
let dh = NumCast(this.props.Document.height, 0);
this.props.Document.height = Math.max(10, (nh ? dh / nh * sh : sh) + (ChromeHeight ? ChromeHeight() : 0));
diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss
index b1afa3f7d..00c069e1f 100644
--- a/src/client/views/nodes/ImageBox.scss
+++ b/src/client/views/nodes/ImageBox.scss
@@ -65,6 +65,7 @@
display:flex;
align-items: center;
height:100%;
+ overflow:hidden;
.imageBox-fadeBlocker {
width:100%;
height:100%;
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 4833ad259..6f1ef38d1 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -530,6 +530,7 @@ export namespace Doc {
target.nativeWidth = undefined;
target.nativeHeight = undefined;
target.onClick = undefined;
+ target.type = undefined;
return;
}
let temp = Doc.MakeDelegate(templateDoc);
@@ -540,7 +541,7 @@ export namespace Doc {
target.width = templateDoc.width;
target.height = templateDoc.height;
target.onClick = templateDoc.onClick instanceof ObjectField && templateDoc.onClick[Copy]();
- Doc.GetProto(target).type = DocumentType.TEMPLATE;
+ target.type = DocumentType.TEMPLATE;
if (targetData && targetData.layout === target) {
targetData.layout = temp;
targetData.miniLayout = StrCast(templateDoc.miniLayout);
@@ -588,7 +589,8 @@ export namespace Doc {
let miniLayout = await PromiseValue(d.miniLayout);
let detailLayout = await PromiseValue(d.detailedLayout);
d.layout !== miniLayout ? miniLayout && (d.layout = d.miniLayout) : detailLayout && (d.layout = detailLayout);
- if (d.layout === detailLayout) Doc.GetProto(d).nativeWidth = Doc.GetProto(d).nativeHeight = undefined;
+ if (d.layout === detailLayout) d.nativeWidth = d.nativeHeight = 0;
+ if (StrCast(d.layout) !== "") d.nativeWidth = d.nativeHeight = undefined;
});
}
export function UseDetailLayout(d: Doc) {
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index f7ce24967..83e45d3ce 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -73,6 +73,12 @@ export class CurrentUserUtils {
sidebar.boxShadow = "1 1 3";
doc.sidebar = sidebar;
}
+ if (doc.overlays === undefined) {
+ const overlays = Docs.Create.FreeformDocument([], { title: "Overlays" });
+ overlays.excludeFromLibrary = true;
+ Doc.GetProto(overlays).backgroundColor = "#aca3a6";
+ doc.overlays = overlays;
+ }
StrCast(doc.title).indexOf("@") !== -1 && (doc.title = StrCast(doc.title).split("@")[0] + "'s Library");
doc.width = 100;
doc.preventTreeViewOpen = true;