aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/Import & Export/DirectoryImportBox.tsx3
-rw-r--r--src/client/views/DocComponent.tsx2
-rw-r--r--src/client/views/DocumentButtonBar.tsx104
-rw-r--r--src/client/views/InkSelectDecorations.tsx16
-rw-r--r--src/client/views/InkingStroke.tsx22
-rw-r--r--src/client/views/Main.scss2
-rw-r--r--src/client/views/TemplateMenu.tsx49
-rw-r--r--src/client/views/collections/CollectionStaffView.tsx14
-rw-r--r--src/client/views/collections/CollectionView.tsx4
-rw-r--r--src/client/views/collections/ParentDocumentSelector.scss6
-rw-r--r--src/client/views/collections/ParentDocumentSelector.tsx29
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss1
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx34
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx5
-rw-r--r--src/client/views/nodes/FormattedTextBox.scss10
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx5
-rw-r--r--src/client/views/nodes/ImageBox.scss1
-rw-r--r--src/client/views/nodes/ImageBox.tsx2
-rw-r--r--src/client/views/nodes/VideoBox.tsx2
-rw-r--r--src/client/views/pdf/PDFViewer.scss7
-rw-r--r--src/client/views/pdf/PDFViewer.tsx8
-rw-r--r--src/server/ApiManagers/GooglePhotosManager.ts3
-rw-r--r--src/server/authentication/models/current_user_utils.ts5
-rw-r--r--src/server/index.ts2
25 files changed, 160 insertions, 180 deletions
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 63e74da5f..f0880f193 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -114,8 +114,7 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
runInAction(() => this.phase = `Internal: uploading ${this.quota - this.completed} files to Dash...`);
- const batched = BatchedArray.from(validated, { batchSize: 15 });
- const uploads = await batched.batchedMapAsync<ImageUploadResponse>(async (batch, collector) => {
+ const uploads = await BatchedArray.from(validated, { batchSize: 15 }).batchedMapAsync<ImageUploadResponse>(async (batch, collector) => {
const formData = new FormData();
batch.forEach(file => {
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 961a5a016..286a77f81 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -84,6 +84,8 @@ export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schema
whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive));
active = () => ((InkingControl.Instance.selectedTool === InkTool.None && !this.props.Document.isBackground) &&
(this.props.Document.forceActive || this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0) ? true : false)
+ annotationsActive = () => (InkingControl.Instance.selectedTool !== InkTool.None ||
+ (this.props.Document.forceActive || this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0) ? true : false)
}
return Component;
} \ No newline at end of file
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 1412316f9..c7ee413c9 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -8,13 +8,12 @@ import { RichTextField } from '../../new_fields/RichTextField';
import { NumCast, StrCast } from "../../new_fields/Types";
import { emptyFunction } from "../../Utils";
import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
-import { DragLinksAsDocuments, DragManager } from "../util/DragManager";
+import { DragManager } from "../util/DragManager";
import { LinkManager } from '../util/LinkManager';
import { UndoManager } from "../util/UndoManager";
import './DocumentButtonBar.scss';
import './collections/ParentDocumentSelector.scss';
import { LinkMenu } from "./linking/LinkMenu";
-import { MetadataEntryMenu } from './MetadataEntryMenu';
import { FormattedTextBox, GoogleRef } from "./nodes/FormattedTextBox";
import { TemplateMenu } from "./TemplateMenu";
import { Template, Templates } from "./Templates";
@@ -43,7 +42,6 @@ const fetch: IconProp = "sync-alt";
@observer
export class DocumentButtonBar extends React.Component<{ views: DocumentView[], stack?: any }, {}> {
private _linkButton = React.createRef<HTMLDivElement>();
- private _linkerButton = React.createRef<HTMLDivElement>();
private _aliasButton = React.createRef<HTMLDivElement>();
private _tooltipoff = React.createRef<HTMLDivElement>();
private _textDoc?: Doc;
@@ -109,14 +107,6 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
document.addEventListener("pointerup", this.onLinkerButtonUp);
}
- onAliasButtonDown = (e: React.PointerEvent): void => {
- e.stopPropagation();
- e.preventDefault();
- document.removeEventListener("pointermove", this.onAliasButtonMoved);
- document.addEventListener("pointermove", this.onAliasButtonMoved);
- document.removeEventListener("pointerup", this.onAliasButtonUp);
- document.addEventListener("pointerup", this.onAliasButtonUp);
- }
onLinkerButtonUp = (e: PointerEvent): void => {
document.removeEventListener("pointermove", this.onLinkerButtonMoved);
@@ -124,22 +114,17 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
e.stopPropagation();
}
- onAliasButtonUp = (e: PointerEvent): void => {
- document.removeEventListener("pointermove", this.onAliasButtonMoved);
- document.removeEventListener("pointerup", this.onAliasButtonUp);
- e.stopPropagation();
- }
@action
onLinkerButtonMoved = (e: PointerEvent): void => {
- if (this._linkerButton.current !== null) {
+ if (this._linkButton.current !== null) {
document.removeEventListener("pointermove", this.onLinkerButtonMoved);
- document.removeEventListener("pointerup", this.onLinkerButtonUp);
+ document.removeEventListener("pointerup", this.onLinkButtonUp);
let docView = this.props.views[0];
let container = docView.props.ContainingCollectionDoc ? docView.props.ContainingCollectionDoc.proto : undefined;
let dragData = new DragManager.LinkDragData(docView.props.Document, container ? [container] : []);
let linkDrag = UndoManager.StartBatch("Drag Link");
- DragManager.StartLinkDrag(this._linkerButton.current, dragData, e.pageX, e.pageY, {
+ DragManager.StartLinkDrag(this._linkButton.current, dragData, e.pageX, e.pageY, {
handlers: {
dragComplete: () => {
let tooltipmenu = FormattedTextBox.ToolTipTextMenu;
@@ -163,62 +148,22 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
e.stopPropagation();
}
- @action
- onAliasButtonMoved = (e: PointerEvent): void => {
- if (this._aliasButton.current !== null) {
- document.removeEventListener("pointermove", this.onAliasButtonMoved);
- document.removeEventListener("pointerup", this.onAliasButtonUp);
-
- let dragDocView = this.props.views[0];
- let dragData = new DragManager.DocumentDragData([dragDocView.props.Document]);
- const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).inverse().transformPoint(0, 0);
- dragData.offset = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).transformDirection(e.clientX - left, e.clientY - top);
- dragData.embedDoc = true;
- dragData.dropAction = "alias";
- DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, e.x, e.y, {
- offsetX: dragData.offset[0],
- offsetY: dragData.offset[1],
- handlers: {
- dragComplete: action(emptyFunction),
- },
- hideSource: false
- });
- }
- e.stopPropagation();
- }
onLinkButtonDown = (e: React.PointerEvent): void => {
e.stopPropagation();
e.preventDefault();
- document.removeEventListener("pointermove", this.onLinkButtonMoved);
- document.addEventListener("pointermove", this.onLinkButtonMoved);
+ document.removeEventListener("pointermove", this.onLinkerButtonMoved);
+ document.addEventListener("pointermove", this.onLinkerButtonMoved);
document.removeEventListener("pointerup", this.onLinkButtonUp);
document.addEventListener("pointerup", this.onLinkButtonUp);
}
onLinkButtonUp = (e: PointerEvent): void => {
- document.removeEventListener("pointermove", this.onLinkButtonMoved);
+ document.removeEventListener("pointermove", this.onLinkerButtonMoved);
document.removeEventListener("pointerup", this.onLinkButtonUp);
e.stopPropagation();
}
- onLinkButtonMoved = async (e: PointerEvent) => {
- if (this._linkButton.current !== null && (e.movementX > 1 || e.movementY > 1)) {
- document.removeEventListener("pointermove", this.onLinkButtonMoved);
- document.removeEventListener("pointerup", this.onLinkButtonUp);
- DragLinksAsDocuments(this._linkButton.current, e.x, e.y, this.props.views[0].props.Document);
- }
- e.stopPropagation();
- }
-
- aliasDragger = () => {
- return (<div className="linkButtonWrapper">
- <div title="Drag Alias" className="linkButton-linker" ref={this._aliasButton} onPointerDown={this.onAliasButtonDown}>
- <FontAwesomeIcon className="documentdecorations-icon" icon="image" size="sm" />
- </div>
- </div>);
- }
-
private get targetDoc() {
return this.props.views[0].props.Document;
}
@@ -317,30 +262,18 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
}
}
- get metadataMenu() {
- return (
- <div className="linkButtonWrapper">
- <Flyout anchorPoint={anchorPoints.TOP_LEFT}
- content={<MetadataEntryMenu docs={() => this.props.views.map(dv => dv.props.Document)} suggestWithFunction />}>{/* tfs: @bcz This might need to be the data document? */}
- <div className="docDecs-tagButton" title="Add fields"><FontAwesomeIcon className="documentdecorations-icon" icon="tag" size="sm" /></div>
- </Flyout>
- </div>
- );
- }
-
render() {
let linkButton = null;
if (this.props.views.length > 0) {
let selFirst = this.props.views[0];
let linkCount = LinkManager.Instance.getAllRelatedLinks(selFirst.props.Document).length;
- linkButton = (<Flyout
- anchorPoint={anchorPoints.RIGHT_TOP}
- content={<LinkMenu docView={selFirst}
- addDocTab={selFirst.props.addDocTab}
- changeFlyout={emptyFunction} />}>
- <div className={"linkButton-" + (linkCount ? "nonempty" : "empty")} onPointerDown={this.onLinkButtonDown} >{linkCount}</div>
- </Flyout >);
+ linkButton = <Flyout anchorPoint={anchorPoints.RIGHT_TOP}
+ content={<LinkMenu docView={selFirst} addDocTab={selFirst.props.addDocTab} changeFlyout={emptyFunction} />}>
+ <div className={"linkButton-" + (linkCount ? "nonempty" : "empty")} onPointerDown={this.onLinkButtonDown} >
+ {linkCount ? linkCount : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />}
+ </div>
+ </Flyout >;
}
let templates: Map<Template, boolean> = new Map();
@@ -349,21 +282,14 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
return (<div className="documentButtonBar">
<div className="linkButtonWrapper">
- <div title="View Links" className="linkFlyout" ref={this._linkButton}> {linkButton} </div>
- </div>
- <div className="linkButtonWrapper">
- <div title="Drag Link" className="linkButton-linker" ref={this._linkerButton} onPointerDown={this.onLinkerButtonDown}>
- <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />
- </div>
+ <div title="Drag(create link) Tap(view links)" className="linkFlyout" ref={this._linkButton}> {linkButton} </div>
</div>
<div className="linkButtonWrapper">
<TemplateMenu docs={this.props.views} templates={templates} />
</div>
- {this.metadataMenu}
- {this.aliasDragger()}
{this.considerGoogleDocsPush()}
{this.considerGoogleDocsPull()}
- <ParentDocSelector Document={this.props.views[0].props.Document} addDocTab={(doc, data, where) => {
+ <ParentDocSelector Views={this.props.views} Document={this.props.views[0].props.Document} addDocTab={(doc, data, where) => {
where === "onRight" ? CollectionDockingView.AddRightSplit(doc, data) : this.props.stack ? CollectionDockingView.Instance.AddTab(this.props.stack, doc, data) : this.props.views[0].props.addDocTab(doc, data, "onRight");
return true;
}} />
diff --git a/src/client/views/InkSelectDecorations.tsx b/src/client/views/InkSelectDecorations.tsx
index 95ccc1777..d40df9b75 100644
--- a/src/client/views/InkSelectDecorations.tsx
+++ b/src/client/views/InkSelectDecorations.tsx
@@ -3,7 +3,7 @@ import { Touchable } from "./Touchable";
import { PointData } from "../../new_fields/InkField";
import { observer } from "mobx-react";
import { computed, observable, action, runInAction } from "mobx";
-import "./InkSelectDecorations.scss"
+import "./InkSelectDecorations.scss";
@observer
export default class InkSelectDecorations extends Touchable {
@@ -46,14 +46,10 @@ export default class InkSelectDecorations extends Touchable {
render() {
let bounds = this.Bounds;
- return (
- <div style={{
- top: bounds.y, left: bounds.x,
- height: bounds.b - bounds.y,
- width: bounds.r - bounds.x
- }}>
-
- </div>
- )
+ return <div style={{
+ top: bounds.y, left: bounds.x,
+ height: bounds.b - bounds.y,
+ width: bounds.r - bounds.x
+ }} />;
}
} \ No newline at end of file
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 411b0d3a0..74211cc90 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -1,18 +1,14 @@
+import { computed } from "mobx";
import { observer } from "mobx-react";
-import { observable, trace, runInAction, computed } from "mobx";
-import { InkingControl } from "./InkingControl";
-import React = require("react");
-import { InkTool, InkField, InkData } from "../../new_fields/InkField";
-import "./InkingStroke.scss";
-import { AudioBox } from "./nodes/AudioBox";
-import { Doc, FieldResult } from "../../new_fields/Doc";
-import { createSchema, makeInterface, listSpec } from "../../new_fields/Schema";
import { documentSchema } from "../../new_fields/documentSchemas";
+import { InkData, InkField, InkTool } from "../../new_fields/InkField";
+import { makeInterface } from "../../new_fields/Schema";
+import { Cast } from "../../new_fields/Types";
import { DocExtendableComponent } from "./DocComponent";
-import { FieldViewProps, FieldView } from "./nodes/FieldView";
-import { Transform } from "../util/Transform";
-import { Cast, FieldValue } from "../../new_fields/Types";
-import { List } from "../../new_fields/List";
+import { InkingControl } from "./InkingControl";
+import "./InkingStroke.scss";
+import { FieldView, FieldViewProps } from "./nodes/FieldView";
+import React = require("react");
type InkDocument = makeInterface<[typeof documentSchema]>;
const InkDocument = makeInterface(documentSchema);
@@ -40,7 +36,7 @@ export class InkingStroke extends DocExtendableComponent<FieldViewProps, InkDocu
render() {
// let pathData = this.parseData(this.props.line);
- let data: InkData = Cast(this.Document.data, InkField) ?.inkData ?? [];
+ let data: InkData = Cast(this.Document.data, InkField)?.inkData ?? [];
let xs = data.map(p => p.x);
let ys = data.map(p => p.y);
let left = Math.min(...xs);
diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss
index 9cbe6e144..465527468 100644
--- a/src/client/views/Main.scss
+++ b/src/client/views/Main.scss
@@ -27,7 +27,7 @@ div {
pointer-events: none;
border-radius: inherit;
position: inherit;
- background: inherit;
+ // background: inherit;
}
p {
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 96265385e..1df5f49c4 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -10,6 +10,7 @@ import { Template, Templates } from "./Templates";
import React = require("react");
import { Doc } from "../../new_fields/Doc";
import { StrCast } from "../../new_fields/Types";
+import { emptyFunction } from "../../Utils";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -46,10 +47,13 @@ export interface TemplateMenuProps {
templates: Map<Template, boolean>;
}
+
@observer
export class TemplateMenu extends React.Component<TemplateMenuProps> {
@observable private _hidden: boolean = true;
- dragRef = React.createRef<HTMLUListElement>();
+ private _downx = 0;
+ private _downy = 0;
+ private _dragRef = React.createRef<HTMLUListElement>();
toggleCustom = (e: React.ChangeEvent<HTMLInputElement>): void => {
this.props.docs.map(dv => dv.setCustomView(e.target.checked));
@@ -122,6 +126,43 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
layout.chromeStatus = (layout.chromeStatus !== "disabled" ? "disabled" : "enabled");
});
}
+ onAliasButtonUp = (e: PointerEvent): void => {
+ document.removeEventListener("pointermove", this.onAliasButtonMoved);
+ document.removeEventListener("pointerup", this.onAliasButtonUp);
+ e.stopPropagation();
+ }
+
+ onAliasButtonDown = (e: React.PointerEvent): void => {
+ this._downx = e.clientX;
+ this._downy = e.clientY;
+ e.stopPropagation();
+ e.preventDefault();
+ document.removeEventListener("pointermove", this.onAliasButtonMoved);
+ document.addEventListener("pointermove", this.onAliasButtonMoved);
+ document.removeEventListener("pointerup", this.onAliasButtonUp);
+ document.addEventListener("pointerup", this.onAliasButtonUp);
+ }
+ onAliasButtonMoved = (e: PointerEvent): void => {
+ if (this._dragRef.current !== null && (Math.abs(e.clientX - this._downx) > 4 || Math.abs(e.clientY - this._downy) > 4)) {
+ document.removeEventListener("pointermove", this.onAliasButtonMoved);
+ document.removeEventListener("pointerup", this.onAliasButtonUp);
+
+ let dragDocView = this.props.docs[0];
+ let dragData = new DragManager.DocumentDragData([dragDocView.props.Document]);
+ const [left, top] = dragDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+ dragData.embedDoc = true;
+ dragData.dropAction = "alias";
+ DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, {
+ offsetX: dragData.offset[0],
+ offsetY: dragData.offset[1],
+ handlers: {
+ dragComplete: action(emptyFunction),
+ },
+ hideSource: false
+ });
+ }
+ e.stopPropagation();
+ }
render() {
let layout = Doc.Layout(this.props.docs[0].Document);
@@ -132,9 +173,9 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
templateMenu.push(<OtherToggle key={"custom"} name={"Custom"} checked={StrCast(this.props.docs[0].Document.layoutKey, "layout") !== "layout"} toggle={this.toggleCustom} />);
templateMenu.push(<OtherToggle key={"chrome"} name={"Chrome"} checked={layout.chromeStatus !== "disabled"} toggle={this.toggleChrome} />);
return (
- <div className="templating-menu" >
- <div title="Template Options" className="templating-button" onClick={() => this.toggleTemplateActivity()}>+</div>
- <ul id="template-list" ref={this.dragRef} style={{ display: this._hidden ? "none" : "block" }}>
+ <div className="templating-menu" onPointerDown={this.onAliasButtonDown}>
+ <div title="Drag:(create alias). Tap:(modify layout)." className="templating-button" onClick={() => this.toggleTemplateActivity()}>+</div>
+ <ul id="template-list" ref={this._dragRef} style={{ display: this._hidden ? "none" : "block" }}>
{templateMenu}
{<button onClick={this.clearTemplates}>Restore Defaults</button>}
</ul>
diff --git a/src/client/views/collections/CollectionStaffView.tsx b/src/client/views/collections/CollectionStaffView.tsx
index eea05ea61..40e860b12 100644
--- a/src/client/views/collections/CollectionStaffView.tsx
+++ b/src/client/views/collections/CollectionStaffView.tsx
@@ -1,6 +1,6 @@
import { CollectionSubView } from "./CollectionSubView";
import { Transform } from "../../util/Transform";
-import React = require("react")
+import React = require("react");
import { computed, action, IReactionDisposer, reaction, runInAction, observable } from "mobx";
import { Doc, HeightSym } from "../../../new_fields/Doc";
import { NumCast } from "../../../new_fields/Types";
@@ -36,7 +36,7 @@ export class CollectionStaffView extends CollectionSubView(doc => doc) {
for (let i = 0; i < this._staves; i++) {
let rows = [];
for (let j = 0; j < 5; j++) {
- rows.push(<div key={`staff-${i}-${j}`} className="collectionStaffView-line"></div>)
+ rows.push(<div key={`staff-${i}-${j}`} className="collectionStaffView-line"></div>);
}
staves.push(<div key={`staff-${i}`} className="collectionStaffView-staff">
{rows}
@@ -51,11 +51,9 @@ export class CollectionStaffView extends CollectionSubView(doc => doc) {
}
render() {
- return (
- <div className="collectionStaffView" ref={this._mainCont}>
- {this.staves}
- {this.addStaffButton}
- </div>
- )
+ return <div className="collectionStaffView" ref={this._mainCont}>
+ {this.staves}
+ {this.addStaffButton}
+ </div>;
}
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 8f1278670..347fa7d0d 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -168,7 +168,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
case CollectionViewType.Schema: return (<CollectionSchemaView key="collview" {...props} />);
case CollectionViewType.Docking: return (<CollectionDockingView key="collview" {...props} />);
case CollectionViewType.Tree: return (<CollectionTreeView key="collview" {...props} />);
- case CollectionViewType.Staff: return (<CollectionStaffView chromeCollapsed={true} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />)
+ case CollectionViewType.Staff: return (<CollectionStaffView chromeCollapsed={true} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />);
case CollectionViewType.Linear: { return (<CollectionLinearView key="collview" {...props} />); }
case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (<CollectionStackingView key="collview" {...props} />); }
case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (<CollectionStackingView key="collview" {...props} />); }
@@ -229,7 +229,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
let more = ContextMenu.Instance.findByDescription("More...");
let moreItems = more && "subitems" in more ? more.subitems : [];
moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) });
- !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" })
+ !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
}
}
diff --git a/src/client/views/collections/ParentDocumentSelector.scss b/src/client/views/collections/ParentDocumentSelector.scss
index c186d15f8..aa25a900c 100644
--- a/src/client/views/collections/ParentDocumentSelector.scss
+++ b/src/client/views/collections/ParentDocumentSelector.scss
@@ -23,6 +23,12 @@
.parentDocumentSelector-button {
pointer-events: all;
}
+.parentDocumentSelector-metadata {
+ pointer-events: auto;
+ padding-right: 5px;
+ width: 25px;
+ display: inline-block;
+}
.buttonSelector {
position: absolute;
display: inline-block;
diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx
index 8b6fa330c..ba83630a4 100644
--- a/src/client/views/collections/ParentDocumentSelector.tsx
+++ b/src/client/views/collections/ParentDocumentSelector.tsx
@@ -13,10 +13,14 @@ import { DocumentManager } from "../../util/DocumentManager";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEdit } from "@fortawesome/free-solid-svg-icons";
import { library } from "@fortawesome/fontawesome-svg-core";
+import { MetadataEntryMenu } from "../MetadataEntryMenu";
+const higflyout = require("@hig/flyout");
+export const { anchorPoints } = higflyout;
+export const Flyout = higflyout.default;
library.add(faEdit);
-type SelectorProps = { Document: Doc, Stack?: any, addDocTab(doc: Doc, dataDoc: Doc | undefined, location: string): void };
+type SelectorProps = { Document: Doc, Views: DocumentView[], Stack?: any, addDocTab(doc: Doc, dataDoc: Doc | undefined, location: string): void };
@observer
export class SelectorContextMenu extends React.Component<SelectorProps> {
@observable private _docs: { col: Doc, target: Doc }[] = [];
@@ -53,16 +57,23 @@ export class SelectorContextMenu extends React.Component<SelectorProps> {
this.props.addDocTab(col, undefined, "inTab"); // bcz: dataDoc?
};
}
+ get metadataMenu() {
+ return <div className="parentDocumentSelector-metadata">
+ <Flyout anchorPoint={anchorPoints.TOP_LEFT}
+ content={<MetadataEntryMenu docs={() => this.props.Views.map(dv => dv.props.Document)} suggestWithFunction />}>{/* tfs: @bcz This might need to be the data document? */}
+ <div className="docDecs-tagButton" title="Add fields"><FontAwesomeIcon className="documentdecorations-icon" icon="tag" size="sm" /></div>
+ </Flyout>
+ </div>;
+ }
render() {
- return (
- <>
- <p key="contexts">Contexts:</p>
- {this._docs.map(doc => <p key={doc.col[Id] + doc.target[Id]}><a onClick={this.getOnClick(doc)}>{doc.col.title}</a></p>)}
- {this._otherDocs.length ? <hr key="hr" /> : null}
- {this._otherDocs.map(doc => <p key="p"><a onClick={this.getOnClick(doc)}>{doc.col.title}</a></p>)}
- </>
- );
+ return <div >
+ <div key="metadata">Metadata: {this.metadataMenu}</div>
+ <p key="contexts">Contexts:</p>
+ {this._docs.map(doc => <p key={doc.col[Id] + doc.target[Id]}><a onClick={this.getOnClick(doc)}>{doc.col.title}</a></p>)}
+ {this._otherDocs.length ? <hr key="hr" /> : null}
+ {this._otherDocs.map(doc => <p key="p"><a onClick={this.getOnClick(doc)}>{doc.col.title}</a></p>)}
+ </div>;
}
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index db36c4391..d2731703f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -45,7 +45,6 @@
// linear-gradient(to bottom, $light-color-secondary 1px, transparent 1px);
// background-size: 30px 30px;
// }
- opacity: 0.99;
border: 0px solid $light-color-secondary;
border-radius: inherit;
box-sizing: border-box;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 59858df8d..210a5132a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -4,43 +4,41 @@ import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrows
import { action, computed, observable, trace } from "mobx";
import { observer } from "mobx-react";
import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../new_fields/Doc";
+import { documentSchema, positionSchema } from "../../../../new_fields/documentSchemas";
import { Id } from "../../../../new_fields/FieldSymbols";
-import { InkField, PointData, InkTool } from "../../../../new_fields/InkField";
+import { InkTool } from "../../../../new_fields/InkField";
import { createSchema, makeInterface } from "../../../../new_fields/Schema";
import { ScriptField } from "../../../../new_fields/ScriptField";
import { BoolCast, Cast, DateCast, NumCast, StrCast } from "../../../../new_fields/Types";
import { CurrentUserUtils } from "../../../../server/authentication/models/current_user_utils";
import { aggregateBounds, emptyFunction, intersectRect, returnOne, Utils } from "../../../../Utils";
-import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
import { DocServer } from "../../../DocServer";
import { Docs } from "../../../documents/Documents";
import { DocumentType } from "../../../documents/DocumentTypes";
import { DocumentManager } from "../../../util/DocumentManager";
import { DragManager } from "../../../util/DragManager";
import { HistoryUtil } from "../../../util/History";
+import { InteractionUtils } from "../../../util/InteractionUtils";
import { SelectionManager } from "../../../util/SelectionManager";
import { Transform } from "../../../util/Transform";
import { undoBatch, UndoManager } from "../../../util/UndoManager";
import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss";
import { ContextMenu } from "../../ContextMenu";
import { ContextMenuProps } from "../../ContextMenuItem";
-import { InkingCanvas } from "../../InkingCanvas";
+import { InkingControl } from "../../InkingControl";
+import { CreatePolyline } from "../../InkingStroke";
import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView";
import { DocumentViewProps } from "../../nodes/DocumentView";
import { FormattedTextBox } from "../../nodes/FormattedTextBox";
import { pageSchema } from "../../nodes/ImageBox";
+import PDFMenu from "../../pdf/PDFMenu";
import { CollectionSubView } from "../CollectionSubView";
import { computePivotLayout, ViewDefResult } from "./CollectionFreeFormLayoutEngines";
import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCursors";
import "./CollectionFreeFormView.scss";
+import MarqueeOptionsMenu from "./MarqueeOptionsMenu";
import { MarqueeView } from "./MarqueeView";
import React = require("react");
-import { InteractionUtils } from "../../../util/InteractionUtils";
-import MarqueeOptionsMenu from "./MarqueeOptionsMenu";
-import PDFMenu from "../../pdf/PDFMenu";
-import { documentSchema, positionSchema } from "../../../../new_fields/documentSchemas";
-import { InkingControl } from "../../InkingControl";
-import { InkingStroke, CreatePolyline } from "../../InkingStroke";
library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
@@ -273,7 +271,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
onPointerDown = (e: React.PointerEvent): void => {
if (e.nativeEvent.cancelBubble) return;
this._hitCluster = this.props.Document.useClusters ? this.pickCluster(this.getTransform().transformPoint(e.clientX, e.clientY)) !== -1 : false;
- if (e.button === 0 && !e.shiftKey && !e.altKey && !e.ctrlKey && (!this.isAnnotationOverlay || this.zoomScaling() !== 1) && this.props.active()) {
+ if (e.button === 0 && !e.shiftKey && !e.altKey && !e.ctrlKey && this.props.active()) {
document.removeEventListener("pointermove", this.onPointerMove);
document.removeEventListener("pointerup", this.onPointerUp);
document.addEventListener("pointermove", this.onPointerMove);
@@ -344,14 +342,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]],
[range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]];
}, [[minx, maxx], [miny, maxy]]);
- let ink = this.extensionDoc && Cast(this.extensionDoc.ink, InkField);
- if (ink && ink.inkData) {
- // ink.inkData.forEach((value: PointData, key: string) => {
- // let bounds = InkingCanvas.StrokeRect(value);
- // ranges[0] = [Math.min(ranges[0][0], bounds.left), Math.max(ranges[0][1], bounds.right)];
- // ranges[1] = [Math.min(ranges[1][0], bounds.top), Math.max(ranges[1][1], bounds.bottom)];
- // });
- }
let cscale = this.props.ContainingCollectionDoc ? NumCast(this.props.ContainingCollectionDoc.scale) : 1;
let panelDim = this.props.ScreenToLocalTransform().transformDirection(this.props.PanelWidth() / this.zoomScaling() * cscale,
@@ -757,11 +747,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}
analyzeStrokes = async () => {
- const extensionDoc = this.extensionDoc;
- let data = extensionDoc && Cast(extensionDoc.ink, InkField);
- if (data && extensionDoc) {
- CognitiveServices.Inking.Appliers.ConcatenateHandwriting(extensionDoc, ["inkAnalysis", "handwriting"], data.inkData);
- }
+ // CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.dataDoc, ["inkAnalysis", "handwriting"], data.inkData);
}
onContextMenu = (e: React.MouseEvent) => {
@@ -852,8 +838,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
children = () => {
let eles: JSX.Element[] = [];
- this.currentStroke && (eles.push(this.currentStroke));
this.extensionDoc && (eles.push(...this.childViews()));
+ this.currentStroke && (eles.push(this.currentStroke));
eles.push(<CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />);
return eles;
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index 91fcad4be..28ddc19d7 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -1,4 +1,4 @@
-import React = require("react")
+import React = require("react");
import AntimodeMenu from "../../AntimodeMenu";
import { observer } from "mobx-react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -40,7 +40,7 @@ export default class MarqueeOptionsMenu extends AntimodeMenu {
onPointerDown={this.delete}>
<FontAwesomeIcon icon="trash-alt" size="lg" />
</button>,
- ]
+ ];
return this.getElement(buttons);
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 5083b45f1..338cf6202 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -537,7 +537,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
return (showTitle ? 25 : 0) + 1;
}
- @computed get finalLayoutKey() { return this.props.layoutKey || "layout" }
+ @computed get finalLayoutKey() { return this.props.layoutKey || "layout"; }
childScaling = () => (this.layoutDoc.fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling());
@computed get contents() {
// trace();
@@ -645,7 +645,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
const ruleRounding = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleRounding_" + this.Document.heading]) : undefined;
const colorSet = this.setsLayoutProp("backgroundColor");
const clusterCol = this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.clusterOverridesDefaultBackground;
- const backgroundColor = this.Document.isBackground || (clusterCol && !colorSet) ?
+ const backgroundColor = (clusterCol && !colorSet) ?
this.props.backgroundColor(this.Document) || StrCast(this.layoutDoc.backgroundColor) :
ruleColor && !colorSet ? ruleColor : StrCast(this.layoutDoc.backgroundColor) || this.props.backgroundColor(this.Document);
@@ -672,7 +672,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
background: this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc.viewType === CollectionViewType.Linear ? undefined : backgroundColor,
width: animwidth,
height: animheight,
- //transform: `scale(${this.layoutDoc.fitWidth ? 1 : this.props.ContentScaling()})`,
opacity: this.Document.opacity
}} >
{this.innards}
diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss
index b9f1e9940..269a3ca68 100644
--- a/src/client/views/nodes/FormattedTextBox.scss
+++ b/src/client/views/nodes/FormattedTextBox.scss
@@ -45,10 +45,18 @@
position: relative;
overflow: auto;
display: inline-block;
- padding: 10px 10px;
width: 100%;
height: 100%;
}
+.formattedTextBox-sidebar,.formattedTextBox-sidebar-inking {
+ border-left: solid 1px black;
+ height: 100%;
+ display: inline-block;
+}
+
+.formattedTextBox-sidebar-inking {
+ pointer-events: all;
+}
.formattedTextBox-inner-rounded {
height: 70%;
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index ef54a387c..0e5fae4af 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -46,6 +46,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { documentSchema } from '../../../new_fields/documentSchemas';
import { AudioBox } from './AudioBox';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
+import { InkTool } from '../../../new_fields/InkField';
library.add(faEdit);
library.add(faSmile, faTextHeight, faUpload);
@@ -1049,7 +1050,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
<div className={`formattedTextBox-outer`} style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, }}>
<div className={`formattedTextBox-inner${rounded}`} style={{ whiteSpace: "pre-wrap", pointerEvents: ((this.Document.isButton || this.props.onClick) && !this.props.isSelected()) ? "none" : undefined }} ref={this.createDropTarget} />
</div>
- {this.sidebarWidthPercent === "0%" ? (null) : <div style={{ borderLeft: "solid 1px black", width: `${this.sidebarWidthPercent}`, height: "100%", display: "inline-block" }}>
+ {this.sidebarWidthPercent === "0%" ? (null) : <div className={"formattedTextBox-sidebar" + (InkingControl.Instance.selectedTool !== InkTool.None ? "-inking" : "")} style={{ width: `${this.sidebarWidthPercent}` }}>
<CollectionFreeFormView {...this.props}
PanelHeight={() => this.props.PanelHeight()}
PanelWidth={() => this.sidebarWidth}
@@ -1058,7 +1059,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
focus={this.props.focus}
isSelected={this.props.isSelected}
select={emptyFunction}
- active={this.active}
+ active={this.annotationsActive}
ContentScaling={returnOne}
whenActiveChanged={this.whenActiveChanged}
removeDocument={this.removeDocument}
diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss
index 57c024bbf..dcecbdc6e 100644
--- a/src/client/views/nodes/ImageBox.scss
+++ b/src/client/views/nodes/ImageBox.scss
@@ -11,6 +11,7 @@
}
.imageBox-container {
+ pointer-events: all;
border-radius: inherit;
width:100%;
height:100%;
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 7a9ebc00a..86dc4fccc 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -342,7 +342,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
focus={this.props.focus}
isSelected={this.props.isSelected}
select={emptyFunction}
- active={this.active}
+ active={this.annotationsActive}
ContentScaling={returnOne}
whenActiveChanged={this.whenActiveChanged}
removeDocument={this.removeDocument}
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 3685df91f..4c826f835 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -344,7 +344,7 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
isSelected={this.props.isSelected}
isAnnotationOverlay={true}
select={emptyFunction}
- active={this.active}
+ active={this.annotationsActive}
ContentScaling={returnOne}
whenActiveChanged={this.whenActiveChanged}
removeDocument={this.removeDocument}
diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss
index 6f9dbb78d..ac018aa0e 100644
--- a/src/client/views/pdf/PDFViewer.scss
+++ b/src/client/views/pdf/PDFViewer.scss
@@ -54,7 +54,7 @@
opacity: 0.1;
}
- .pdfViewer-overlay {
+ .pdfViewer-overlay, .pdfViewer-overlay-inking {
transform-origin: left top;
position: absolute;
top: 0px;
@@ -63,6 +63,11 @@
width:100%;
pointer-events: none;
}
+ .pdfViewer-overlay-inking {
+ .collectionfreeformview-container {
+ pointer-events: all;
+ }
+ }
.pdfViewer-annotationLayer {
position: absolute;
transform-origin: left top;
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index de9eeaf97..c56422076 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -27,6 +27,8 @@ import { DocAnnotatableComponent } from "../DocComponent";
import { DocumentType } from "../../documents/DocumentTypes";
import { documentSchema } from "../../../new_fields/documentSchemas";
import { DocumentDecorations } from "../DocumentDecorations";
+import { InkingControl } from "../InkingControl";
+import { InkTool } from "../../../new_fields/InkField";
const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer");
const pdfjsLib = require("pdfjs-dist");
@@ -628,7 +630,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
panelWidth = () => (this.Document.scrollHeight || this.Document.nativeHeight || 0);
panelHeight = () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : (this.Document.nativeWidth || 0);
@computed get overlayLayer() {
- return <div className="pdfViewer-overlay" id="overlay" style={{ transform: `scale(${this._zoomed})` }}>
+ return <div className={`pdfViewer-overlay${InkingControl.Instance.selectedTool !== InkTool.None ? "-inking" : ""}`} id="overlay" style={{ transform: `scale(${this._zoomed})` }}>
<CollectionFreeFormView {...this.props}
annotationsKey={this.annotationsKey}
setPreviewCursor={this.setPreviewCursor}
@@ -639,7 +641,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
isSelected={this.props.isSelected}
isAnnotationOverlay={true}
select={emptyFunction}
- active={this.active}
+ active={this.annotationsActive}
ContentScaling={this.contentZoom}
whenActiveChanged={this.whenActiveChanged}
removeDocument={this.removeDocument}
@@ -652,7 +654,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
ContainingCollectionDoc={this.props.ContainingCollectionView?.props.Document}
chromeCollapsed={true}>
</CollectionFreeFormView>
- </div>
+ </div>;
}
@computed get pdfViewerDiv() {
return <div className={"pdfViewer-text" + ((!DocumentDecorations.Instance.Interacting && (this.props.isSelected() || this.props.isChildActive())) ? "-selected" : "")} ref={this._viewer} />;
diff --git a/src/server/ApiManagers/GooglePhotosManager.ts b/src/server/ApiManagers/GooglePhotosManager.ts
index 1138dede1..c7af69375 100644
--- a/src/server/ApiManagers/GooglePhotosManager.ts
+++ b/src/server/ApiManagers/GooglePhotosManager.ts
@@ -31,6 +31,9 @@ interface NewMediaItem {
}
const prefix = "google_photos_";
+/**
+ * This manager handles the creation of routes for google photos functionality.
+ */
export default class GooglePhotosManager extends ApiManager {
protected initialize(register: Registration): void {
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 20f6cc8c7..052aa54a6 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -11,9 +11,10 @@ import { listSpec } from "../../../new_fields/Schema";
import { ScriptField, ComputedField } from "../../../new_fields/ScriptField";
import { Cast, PromiseValue } from "../../../new_fields/Types";
import { Utils } from "../../../Utils";
-import { InkingControl } from "../../../client/views/InkingControl";
-import { DragManager } from "../../../client/util/DragManager";
+import { ButtonBox } from "../../../client/views/nodes/ButtonBox";
import { nullAudio } from "../../../new_fields/URLField";
+import { DragManager } from "../../../client/util/DragManager";
+import { InkingControl } from "../../../client/views/InkingControl";
export class CurrentUserUtils {
private static curr_id: string;
diff --git a/src/server/index.ts b/src/server/index.ts
index ad9c5886c..01ebf0ac1 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -43,7 +43,7 @@ async function preliminaryFunctions() {
// divide the public directory based on type
await Promise.all(Object.keys(Partitions).map(partition => DashUploadUtils.createIfNotExists(filesDirectory + partition)));
// connect to the database
- await log_execution("attempting to initialize database connection", "connected", Database.tryInitializeConnection);
+ await Database.tryInitializeConnection();
}
/**