aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormehekj <mehek.jethani@gmail.com>2021-09-13 20:19:56 -0400
committermehekj <mehek.jethani@gmail.com>2021-09-13 20:19:56 -0400
commit1ce13f912afc7edd1073e6e8204f8f5fb52cd4b0 (patch)
treed972cbbd1fd0c7c7ba47e9bd18da0bb180f25da3
parentd71bc56628c2193b537b92a186785eaffa3a1eef (diff)
parentaf246480e97554233293ab1dfb08b5af5e1f9d7c (diff)
Merge branch 'master' into temporalmedia-mehek
-rw-r--r--src/Utils.ts10
-rw-r--r--src/client/util/CurrentUserUtils.ts53
-rw-r--r--src/client/util/DocumentManager.ts9
-rw-r--r--src/client/views/ContextMenu.tsx15
-rw-r--r--src/client/views/DocComponent.tsx2
-rw-r--r--src/client/views/DocumentButtonBar.tsx2
-rw-r--r--src/client/views/DocumentDecorations.tsx22
-rw-r--r--src/client/views/MainView.tsx21
-rw-r--r--src/client/views/MarqueeAnnotator.tsx2
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx4
-rw-r--r--src/client/views/collections/TreeView.tsx10
-rw-r--r--src/client/views/nodes/AudioBox.scss279
-rw-r--r--src/client/views/nodes/AudioBox.tsx6
-rw-r--r--src/client/views/nodes/DocumentView.tsx21
-rw-r--r--src/client/views/nodes/ImageBox.tsx2
-rw-r--r--src/client/views/nodes/PDFBox.tsx6
-rw-r--r--src/client/views/nodes/WebBox.tsx27
-rw-r--r--src/client/views/nodes/button/FontIconBox.scss16
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx63
-rw-r--r--src/client/views/nodes/button/colorDropdown/ColorDropdown.tsx10
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.scss1
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx15
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx14
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx8
-rw-r--r--src/client/views/pdf/AnchorMenu.tsx5
25 files changed, 381 insertions, 242 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index 3fffadb6d..ddc16dceb 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -82,15 +82,7 @@ export namespace Utils {
}
export function CopyText(text: string) {
- const textArea = document.createElement("textarea");
- textArea.value = text;
- document.body.appendChild(textArea);
- textArea.focus();
- textArea.select();
-
- try { document.execCommand('copy'); } catch (err) { }
-
- document.body.removeChild(textArea);
+ navigator.clipboard.writeText(text);
}
export function decimalToHexString(number: number) {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index d6050d631..6a7523d5b 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -574,11 +574,11 @@ export class CurrentUserUtils {
return [
{ title: "Dashboards", target: Cast(doc.myDashboards, Doc, null), icon: "desktop", click: 'selectMainMenu(self)' },
{ title: "Search", target: Cast(doc.mySearchPanel, Doc, null), icon: "search", click: 'selectMainMenu(self)' },
- { title: "File Manager", target: Cast(doc.myFilesystem, Doc, null), icon: "folder-open", click: 'selectMainMenu(self)' },
+ { title: "Files", target: Cast(doc.myFilesystem, Doc, null), icon: "folder-open", click: 'selectMainMenu(self)' },
{ title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)', hidden: "IsNoviceMode()" },
- { title: "Uploads", target: Cast(doc.myUploadDocs, Doc, null), icon: "upload", click: 'selectMainMenu(self)' },
+ { title: "Imports", target: Cast(doc.myImportDocs, Doc, null), icon: "upload", click: 'selectMainMenu(self)' },
{ title: "Recently Closed", target: Cast(doc.myRecentlyClosedDocs, Doc, null), icon: "archive", click: 'selectMainMenu(self)' },
- { title: "Sharing", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc },
+ { title: "Shared with me", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc },
{ title: "Trails", target: Cast(doc.myTrails, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' },
{ title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)', hidden: "IsNoviceMode()" },
];
@@ -806,13 +806,15 @@ export class CurrentUserUtils {
// setup dashboards library item
await doc.myDashboards;
if (doc.myDashboards === undefined) {
+ const newDashboard = ScriptField.MakeScript(`createNewDashboard(Doc.UserDoc())`);
+ const newDashboardButton: Doc = Docs.Create.FontIconDocument({ onClick: newDashboard, _forceActive: true, toolTip: "Create new dashboard", _stayInCollection: true, _hideContextMenu: true, title: "new dashboard", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New trail", icon: "plus", system: true });
doc.myDashboards = new PrefetchProxy(Docs.Create.TreeDocument([], {
title: "My Dashboards", _showTitle: "title", _height: 400, childHideLinkButton: true,
treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
- treeViewTruncateTitleWidth: 150, ignoreClick: true,
- _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", treeViewType: "fileSystem", isFolder: true, system: true
+ treeViewTruncateTitleWidth: 150, ignoreClick: true, buttonMenu: true, buttonMenuDoc: newDashboardButton,
+ _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", treeViewType: "fileSystem", isFolder: true, system: true,
+ explainer: "This is your collection of dashboards. A dashboard represents the tab configuration of your workspace. To manage documents as folders, go to the Files."
}));
- const newDashboard = ScriptField.MakeScript(`createNewDashboard(Doc.UserDoc())`);
// const toggleTheme = ScriptField.MakeScript(`Doc.UserDoc().darkScheme = !Doc.UserDoc().darkScheme`);
// const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
// const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`);
@@ -820,7 +822,7 @@ export class CurrentUserUtils {
const removeDashboard = ScriptField.MakeScript('removeDashboard(self)');
(doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, shareDashboard!, removeDashboard!]);
(doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Share Dashboard", "Remove Dashboard"]);
- (doc.myDashboards as any as Doc).childContextMenuIcons = new List<string>(["plus", "share", "times"]);
+ (doc.myDashboards as any as Doc).childContextMenuIcons = new List<string>(["plus", "user-friends", "times"]);
// (doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, toggleTheme!, toggleComic!, snapshotDashboard!, shareDashboard!, removeDashboard!]);
// (doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]);
}
@@ -831,7 +833,7 @@ export class CurrentUserUtils {
await doc.myTrails;
if (doc.myTrails === undefined) {
const newTrail = ScriptField.MakeScript(`createNewPresentation()`);
- const newTrailButton: Doc = Docs.Create.FontIconDocument({ onClick: newTrail, _forceActive: true, toolTip: "New trail", _stayInCollection: true, _hideContextMenu: true, title: "New trail", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New trail", icon: "plus", system: true });
+ const newTrailButton: Doc = Docs.Create.FontIconDocument({ onClick: newTrail, _forceActive: true, toolTip: "Create new trail", _stayInCollection: true, _hideContextMenu: true, title: "New trail", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New trail", icon: "plus", system: true });
doc.myTrails = new PrefetchProxy(Docs.Create.TreeDocument([], {
title: "My Trails", _showTitle: "title", _height: 100,
treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _fitWidth: true, _gridGap: 5, _forceActive: true, childDropAction: "alias",
@@ -841,6 +843,7 @@ export class CurrentUserUtils {
}));
(doc.myTrails as any as Doc).contextMenuScripts = new List<ScriptField>([newTrail!]);
(doc.myTrails as any as Doc).contextMenuLabels = new List<string>(["Create New Trail"]);
+ (doc.myTrails as any as Doc).childContextMenuIcons = new List<string>(["plus"]);
}
return doc.myTrails as any as Doc;
}
@@ -851,7 +854,7 @@ export class CurrentUserUtils {
doc.myFileOrphans = Docs.Create.TreeDocument([], { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true });
// doc.myFileRoot = Docs.Create.TreeDocument([], { title: "file root", _stayInCollection: true, system: true, isFolder: true });
const newFolder = ScriptField.MakeFunction(`doc.makeFolder()`, { doc: doc.myFilesystem })!;
- const newFolderButton: Doc = Docs.Create.FontIconDocument({ onClick: newFolder, _forceActive: true, toolTip: "New folder", _stayInCollection: true, _hideContextMenu: true, title: "New folder", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New folder", icon: "folder-plus", system: true });
+ const newFolderButton: Doc = Docs.Create.FontIconDocument({ onClick: newFolder, _forceActive: true, toolTip: "Create new folder", _stayInCollection: true, _hideContextMenu: true, title: "New folder", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New folder", icon: "folder-plus", system: true });
doc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([doc.myFileOrphans as Doc], {
title: "My Documents", _showTitle: "title", buttonMenu: true, buttonMenuDoc: newFolderButton, _height: 100,
treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
@@ -860,8 +863,9 @@ export class CurrentUserUtils {
_lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "proto", system: true,
explainer: "This is your file manager where you can create folders to keep track of documents independently of your dashboard."
}));
- (doc.myTrails as any as Doc).contextMenuScripts = new List<ScriptField>([newFolder]);
- (doc.myTrails as any as Doc).contextMenuLabels = new List<string>(["Create new folder"]);
+ (doc.myFilesystem as any as Doc).contextMenuScripts = new List<ScriptField>([newFolder]);
+ (doc.myFilesystem as any as Doc).contextMenuLabels = new List<string>(["Create new folder"]);
+ (doc.myFilesystem as any as Doc).childContextMenuIcons = new List<string>(["plus"]);
}
return doc.myFilesystem as any as Doc;
}
@@ -926,7 +930,7 @@ export class CurrentUserUtils {
static async setupSidebarButtons(doc: Doc) {
CurrentUserUtils.setupSidebarContainer(doc);
await CurrentUserUtils.setupToolsBtnPanel(doc);
- CurrentUserUtils.setupUploadSidebar(doc);
+ CurrentUserUtils.setupImportSidebar(doc);
CurrentUserUtils.setupDashboards(doc);
CurrentUserUtils.setupPresentations(doc);
CurrentUserUtils.setupFilesystem(doc);
@@ -1194,7 +1198,7 @@ export class CurrentUserUtils {
title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "all", childLimitHeight: 0, _yMargin: 50, _gridGap: 15,
_showTitle: "title", treeViewHideTitle: true, ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment,
_chromeHidden: true, boxShadow: "0 0",
- explainer: "This is where documents or dashboards that other users have shared with you will appear."
+ explainer: "This is where documents or dashboards that other users have shared with you will appear. To share a document or dashboard right click and select 'Share'"
}, sharingDocumentId + "outer", sharingDocumentId);
(sharedDocs as Doc)["acl-Public"] = (sharedDocs as Doc)[DataSym]["acl-Public"] = SharingPermissions.Augment;
}
@@ -1213,13 +1217,13 @@ export class CurrentUserUtils {
}
// Import sidebar is where shared documents are contained
- static setupUploadSidebar(doc: Doc) {
- if (doc.myUploadDocs === undefined) {
- const newUploadButton: Doc = Docs.Create.FontIconDocument({ onClick: ScriptField.MakeScript("importDocument()"), _forceActive: true, toolTip: "Upload from computer", _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true, title: "Upload", btnType: ButtonType.ClickButton, buttonText: "Upload", icon: "upload", system: true });
- doc.myUploadDocs = new PrefetchProxy(Docs.Create.StackingDocument([], {
- title: "My Uploads", _forceActive: true, buttonMenu: true, buttonMenuDoc: newUploadButton, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0,
+ static setupImportSidebar(doc: Doc) {
+ if (doc.myImportDocs === undefined) {
+ const newImportButton: Doc = Docs.Create.FontIconDocument({ onClick: ScriptField.MakeScript("importDocument()"), _forceActive: true, toolTip: "Import from computer", _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true, title: "Import", btnType: ButtonType.ClickButton, buttonText: "Import", icon: "upload", system: true });
+ doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([], {
+ title: "My Imports", _forceActive: true, buttonMenu: true, buttonMenuDoc: newImportButton, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0,
childDropAction: "copy", _autoHeight: true, _yMargin: 50, _gridGap: 15, boxShadow: "0 0", _lockedPosition: true, system: true, _chromeHidden: true,
- explainer: "This is where documents that are uploaded into Dash will go."
+ explainer: "This is where documents that are Imported into Dash will go."
}));
}
}
@@ -1322,7 +1326,7 @@ export class CurrentUserUtils {
doc.filterDocCount = 0;
this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon
this.setupDocTemplates(doc); // sets up the template menu of templates
- this.setupUploadSidebar(doc); // sets up the import sidebar
+ this.setupImportSidebar(doc); // sets up the import sidebar
this.setupSearchSidebar(doc); // sets up the search sidebar
this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
this.setupOverlays(doc); // documents in overlay layer
@@ -1449,7 +1453,7 @@ export class CurrentUserUtils {
}
}
} else if (input.files && input.files.length !== 0) {
- const importDocs = Cast(Doc.UserDoc().myUploadDocs, Doc, null);
+ const importDocs = Cast(Doc.UserDoc().myImportDocs, Doc, null);
const disposer = OverlayView.ShowSpinner();
DocListCastAsync(importDocs.data).then(async list => {
const results = await DocUtils.uploadFilesToDocs(Array.from(input.files || []), {});
@@ -1473,7 +1477,6 @@ export class CurrentUserUtils {
}
public static createNewDashboard = async (userDoc: Doc, id?: string) => {
- const myTrails = await userDoc.myTrails as Doc;
const presentation = Doc.MakeCopy(userDoc.emptyPresentation as Doc, true);
const dashboards = await Cast(userDoc.myDashboards, Doc) as Doc;
const dashboardCount = DocListCast(dashboards.data).length + 1;
@@ -1516,9 +1519,9 @@ export class CurrentUserUtils {
CurrentUserUtils.openDashboard(userDoc, dashboardDoc);
}
- public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, noMargins?: boolean, annotationOn?: Doc, maxHeight?: number) {
+ public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, noMargins?: boolean, annotationOn?: Doc, maxHeight?: number, backgroundColor?: string) {
const tbox = Docs.Create.TextDocument("", {
- _xMargin: noMargins ? 0 : undefined, _yMargin: noMargins ? 0 : undefined, annotationOn, docMaxAutoHeight: maxHeight,
+ _xMargin: noMargins ? 0 : undefined, _yMargin: noMargins ? 0 : undefined, annotationOn, docMaxAutoHeight: maxHeight, backgroundColor: backgroundColor,
_width: width || 200, _height: height || 100, x: x, y: y, _fitWidth: true, _autoHeight: true, _fontSize: StrCast(Doc.UserDoc().fontSize),
_fontFamily: StrCast(Doc.UserDoc().fontFamily), title
});
@@ -1560,6 +1563,8 @@ Scripting.addGlobal(function createNewDashboard() { return CurrentUserUtils.crea
"creates a new dashboard when called");
Scripting.addGlobal(function createNewPresentation() { return MainView.Instance.createNewPresentation(); },
"creates a new presentation when called");
+Scripting.addGlobal(function createNewFolder() { return MainView.Instance.createNewFolder(); },
+ "creates a new folder in myFiles when called");
Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); },
"returns all the links to the document or its annotations", "(doc: any)");
Scripting.addGlobal(function importDocument() { return CurrentUserUtils.importDocument(); },
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 9e190ad02..dfec9823b 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -158,7 +158,8 @@ export class DocumentManager {
closeContextIfNotFound: boolean = false, // after opening a context where the document should be, this determines whether the context should be closed if the Doc isn't actually there
originatingDoc: Opt<Doc> = undefined, // doc that initiated the display of the target odoc
finished?: () => void,
- originalTarget?: Doc
+ originalTarget?: Doc,
+ noSelect?: boolean
): Promise<void> => {
originalTarget = originalTarget ?? targetDoc;
const getFirstDocView = LightboxView.LightboxDoc ? DocumentManager.Instance.getLightboxDocumentView : DocumentManager.Instance.getFirstDocumentView;
@@ -172,7 +173,7 @@ export class DocumentManager {
}
} else {
targetDoc.hidden && (targetDoc.hidden = undefined);
- docView?.select(false);
+ !noSelect && docView?.select(false);
}
finished?.();
return false;
@@ -189,7 +190,7 @@ export class DocumentManager {
annoContainerView.focus(targetDoc); // this allows something like a PDF view to remove its doc filters to expose the target so that it can be found in the retry code below
}
if (focusView) {
- Doc.linkFollowHighlight(focusView.rootDoc);
+ !noSelect && Doc.linkFollowHighlight(focusView.rootDoc); //TODO:glr make this a setting in PresBox
focusView.focus(targetDoc, {
originalTarget, willZoom, afterFocus: (didFocus: boolean) =>
new Promise<ViewAdjustment>(res => {
@@ -222,7 +223,7 @@ export class DocumentManager {
retryDocView.props.focus(targetDoc, {
willZoom, afterFocus: (didFocus: boolean) =>
new Promise<ViewAdjustment>(res => {
- focusAndFinish(didFocus);
+ !noSelect && focusAndFinish(didFocus);
res();
})
}); // focus on the target in the context
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index c4fabbf99..78564a11b 100644
--- a/src/client/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
@@ -47,11 +47,17 @@ export class ContextMenu extends React.Component {
this._mouseDown = false;
const curX = e.clientX;
const curY = e.clientY;
- if (this._mouseX !== curX || this._mouseY !== curY) {
+ if (Math.abs(this._mouseX - curX) > 1 || Math.abs(this._mouseY - curY) > 1) {
this._shouldDisplay = false;
}
- this._shouldDisplay && (this._display = true);
+ if (this._shouldDisplay) {
+ if (this._onDisplay) {
+ this._onDisplay();
+ } else {
+ this._display = true;
+ }
+ }
}
componentWillUnmount() {
document.removeEventListener("pointerdown", this.onPointerDown);
@@ -138,9 +144,9 @@ export class ContextMenu extends React.Component {
return y;
}
-
+ _onDisplay?: () => void = undefined;
@action
- displayMenu = (x: number, y: number, initSearch = "", showSearch = false) => {
+ displayMenu = (x: number, y: number, initSearch = "", showSearch = false, onDisplay?: () => void) => {
//maxX and maxY will change if the UI/font size changes, but will work for any amount
//of items added to the menu
@@ -149,6 +155,7 @@ export class ContextMenu extends React.Component {
this._pageY = y;
this._searchString = initSearch;
this._shouldDisplay = true;
+ this._onDisplay = onDisplay;
}
@action
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index cb36f4270..32c351bf5 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -176,7 +176,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
return false;
}
@action.bound
- addDocument(doc: Doc | Doc[], annotationKey?: string): boolean {
+ addDocument = (doc: Doc | Doc[], annotationKey?: string): boolean => {
const docs = doc instanceof Doc ? [doc] : doc;
if (this.props.filterAddDocument?.(docs) === false ||
docs.find(doc => Doc.AreProtosEqual(doc, this.props.Document) && Doc.LayoutField(doc) === Doc.LayoutField(this.props.Document))) {
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 5640e5132..7f428a881 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -203,7 +203,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
<div className="dash-tooltip">{SelectionManager.Views().length > 1 ? "Pin multiple documents to presentation" : "Pin to presentation"}</div>}>
<div className="documentButtonBar-icon"
style={{ color: "white" }}
- onClick={undoBatch(e => this.props.views().map(view => view && TabDocView.PinDoc(view.props.Document, { setPosition: e.shiftKey ? true : undefined })))}>
+ onClick={undoBatch(e => this.props.views().map(view => view && this.pinWithView(view.props.Document)))}>
<FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
</div>
</Tooltip>;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index a570bdb34..6ca8dbec6 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -136,7 +136,6 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
return true;
}
- @undoBatch
onCloseClick = () => {
const selected = SelectionManager.Views().slice();
SelectionManager.DeselectAll();
@@ -153,8 +152,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
return true;
}, emptyFunction, this.onMaximizeClick, false, false);
}
- @undoBatch
- @action
+
onMaximizeClick = (e: any): void => {
const selectedDocs = SelectionManager.Views();
if (selectedDocs.length) {
@@ -176,7 +174,6 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
SelectionManager.DeselectAll();
}
- @undoBatch
onIconifyClick = (): void => {
SelectionManager.Views().forEach(dv => dv?.iconify());
SelectionManager.DeselectAll();
@@ -319,11 +316,12 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
let height = (doc._height || (nheight / nwidth * width));
height = !height || isNaN(height) ? 20 : height;
const scale = docView.props.ScreenToLocalTransform().Scale;
+ const canModifyNativeDim = e.ctrlKey || doc.allowReflow;
if (nwidth && nheight) {
if (nwidth / nheight !== width / height && !dragBottom) {
height = nheight / nwidth * width;
}
- if (e.ctrlKey && !dragBottom) { // ctrl key enables modification of the nativeWidth or nativeHeight durin the interaction
+ if (canModifyNativeDim && !dragBottom) { // ctrl key enables modification of the nativeWidth or nativeHeight durin the interaction
if (Math.abs(dW) > Math.abs(dH)) dH = dW * nheight / nwidth;
else dW = dH * nwidth / nheight;
}
@@ -333,7 +331,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
doc.x = (doc.x || 0) + dX * (actualdW - width);
doc.y = (doc.y || 0) + dY * (actualdH - height);
const fixedAspect = (nwidth && nheight);
- if (e.ctrlKey && [DocumentType.IMG, DocumentType.SCREENSHOT, DocumentType.VID].includes(doc.type as DocumentType)) {
+ if (canModifyNativeDim && [DocumentType.IMG, DocumentType.SCREENSHOT, DocumentType.VID].includes(doc.type as DocumentType)) {
dW !== 0 && runInAction(() => {
const dataDoc = doc[DataSym];
const nw = Doc.NativeWidth(dataDoc);
@@ -343,22 +341,22 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
});
}
else if (fixedAspect) {
- if ((Math.abs(dW) > Math.abs(dH) && (!dragBottom || !e.ctrlKey)) || dragRight) {
- if (dragRight && e.ctrlKey) {
+ if ((Math.abs(dW) > Math.abs(dH) && (!dragBottom || !canModifyNativeDim)) || dragRight) {
+ if (dragRight && canModifyNativeDim) {
doc._nativeWidth = actualdW / (doc._width || 1) * Doc.NativeWidth(doc);
} else {
if (!doc._fitWidth) doc._height = nheight / nwidth * actualdW;
- else if (!e.ctrlKey || dragBotRight) doc._height = actualdH;
+ else if (!canModifyNativeDim || dragBotRight) doc._height = actualdH;
}
doc._width = actualdW;
}
else {
- if (dragBottom && (e.ctrlKey || docView.layoutDoc._fitWidth)) { // frozen web pages and others that fitWidth can't grow horizontally to match a vertical resize so the only choice is to change the nativeheight even if the ctrl key isn't used
+ if (dragBottom && (canModifyNativeDim || docView.layoutDoc._fitWidth)) { // frozen web pages and others that fitWidth can't grow horizontally to match a vertical resize so the only choice is to change the nativeheight even if the ctrl key isn't used
doc._nativeHeight = actualdH / (doc._height || 1) * Doc.NativeHeight(doc);
doc._autoHeight = false;
} else {
if (!doc._fitWidth) doc._width = nwidth / nheight * actualdH;
- else if (!e.ctrlKey || dragBotRight) doc._width = actualdW;
+ else if (!canModifyNativeDim || dragBotRight) doc._width = actualdW;
}
doc._height = actualdH;
}
@@ -432,7 +430,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
const topBtn = (key: string, icon: string, pointerDown: undefined | ((e: React.PointerEvent) => void), click: undefined | ((e: any) => void), title: string) => (
<Tooltip key={key} title={<div className="dash-tooltip">{title}</div>} placement="top">
<div className={`documentDecorations-${key}Button`} onContextMenu={e => e.preventDefault()}
- onPointerDown={pointerDown ?? (e => setupMoveUpEvents(this, e, returnFalse, click!, emptyFunction))} >
+ onPointerDown={pointerDown ?? (e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(e => click!(e))))} >
<FontAwesomeIcon icon={icon as any} />
</div>
</Tooltip>);
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 5c1a51052..9b1cc3499 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -63,6 +63,8 @@ import { PropertiesView } from './PropertiesView';
import { DashboardStyleProvider, DefaultStyleProvider } from './StyleProvider';
import { TopBar } from './topbar/TopBar';
import { RichTextMenu } from './nodes/formattedText/RichTextMenu';
+import { ScriptField } from '../../fields/ScriptField';
+import { ButtonType } from './nodes/button/FontIconBox';
const _global = (window /* browser */ || global /* node */) as any;
@observer
@@ -239,6 +241,25 @@ export class MainView extends React.Component {
Doc.AddDocToList(this.userDoc.myTrails as Doc, "data", pres);
}
+ @action
+ createNewFolder = async () => {
+ if (!await this.userDoc.myFilesystem) {
+ this.userDoc.myFileOrphans = Docs.Create.TreeDocument([], { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true });
+ const newFolder = ScriptField.MakeFunction(`createNewFolder()`, { scriptContext: "any" })!;
+ const newFolderButton: Doc = Docs.Create.FontIconDocument({ onClick: newFolder, _forceActive: true, toolTip: "New folder", _stayInCollection: true, _hideContextMenu: true, title: "New folder", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "New folder", icon: "folder-plus", system: true });
+ this.userDoc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([this.userDoc.myFileOrphans as Doc], {
+ title: "My Documents", _showTitle: "title", buttonMenu: true, buttonMenuDoc: newFolderButton, _height: 100,
+ treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
+ treeViewTruncateTitleWidth: 150, ignoreClick: true,
+ isFolder: true, treeViewType: "fileSystem", childHideLinkButton: true,
+ _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "proto", system: true,
+ explainer: "This is your file manager where you can create folders to keep track of documents independently of your dashboard."
+ }));
+ }
+ const folder = Docs.Create.TreeDocument([], { title: "Untitled folder", _stayInCollection: true, isFolder: true });
+ Doc.AddDocToList(this.userDoc.myFilesystem as Doc, "data", folder);
+ }
+
getPWidth = () => this._panelWidth - this.propertiesWidth();
getPHeight = () => this._panelHeight - (CollectionMenu.Instance?.Pinned ? 35 : 0);
getContentsHeight = () => this._panelHeight;
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index eee365ed8..26e76090a 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -81,7 +81,7 @@ export class MarqueeAnnotator extends React.Component<MarqueeAnnotatorProps> {
return annoDoc;
};
const targetCreator = (annotationOn: Doc | undefined) => {
- const target = CurrentUserUtils.GetNewTextDoc("Note linked to " + this.props.rootDoc.title, 0, 0, 100, 100, undefined, annotationOn);
+ const target = CurrentUserUtils.GetNewTextDoc("Note linked to " + this.props.rootDoc.title, 0, 0, 100, 100, undefined, annotationOn, undefined, "yellow");
FormattedTextBox.SelectOnLoad = target[Id];
return target;
};
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index eee1df921..2e9525577 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -43,6 +43,7 @@ import {
import { LabelBox } from "../nodes/LabelBox";
import "./CollectionStackedTimeline.scss";
import { Colors } from "../global/globalEnums";
+import { DocumentManager } from "../../util/DocumentManager";
type PanZoomDocument = makeInterface<[]>;
const PanZoomDocument = makeInterface();
@@ -246,7 +247,7 @@ export class CollectionStackedTimeline extends CollectionSubView<
Math.abs(movement[0]) > 15 &&
!this.props.trimming
) {
- CollectionStackedTimeline.createAnchor(
+ const anchor = CollectionStackedTimeline.createAnchor(
this.rootDoc,
this.dataDoc,
this.props.fieldKey,
@@ -255,6 +256,7 @@ export class CollectionStackedTimeline extends CollectionSubView<
this._markerStart,
this._markerEnd
);
+ setTimeout(() => DocumentManager.Instance.getDocumentView(anchor)?.select(false));
}
(!isClick || !wasSelecting) &&
(CollectionStackedTimeline.SelectingRegion = undefined);
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 8cf34ddcc..aa7b164b0 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -54,7 +54,7 @@ export interface TreeViewProps {
indentDocument?: (editTitle: boolean) => void;
outdentDocument?: (editTitle: boolean) => void;
ScreenToLocalTransform: () => Transform;
- contextMenuItems: { script: ScriptField, filter: ScriptField, label: string }[];
+ contextMenuItems: { script: ScriptField, filter: ScriptField, icon: string, label: string }[];
dontRegisterView?: boolean;
styleProvider?: StyleProviderFunc | undefined;
treeViewHideHeaderFields: () => boolean;
@@ -240,7 +240,7 @@ export class TreeView extends React.Component<TreeViewProps> {
}
makeFolder = () => {
- const folder = Docs.Create.TreeDocument([], { title: "-folder-", _stayInCollection: true, isFolder: true });
+ const folder = Docs.Create.TreeDocument([], { title: "Untitled folder", _stayInCollection: true, isFolder: true });
TreeView._editTitleOnLoad = { id: folder[Id], parent: this.props.parentTreeView };
return this.props.addDocument(folder);
}
@@ -512,9 +512,9 @@ export class TreeView extends React.Component<TreeViewProps> {
DocumentViewInternal.SelectAfterContextMenu = true;
}
contextMenuItems = () => {
- const makeFolder = { script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" };
- const openAlias = { script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" };
- const focusDoc = { script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" };
+ const makeFolder = { script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, icon: "folder-plus", label: "New Folder" };
+ const openAlias = { script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, icon: "copy", label: "Open Alias" };
+ const focusDoc = { script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, icon: "eye", label: "Focus or Open" };
return [...this.props.contextMenuItems.filter(mi => !mi.filter ? true : mi.filter.script.run({ doc: this.doc })?.result), ... (this.doc.isFolder ? [makeFolder] :
Doc.IsSystem(this.doc) ? [] :
this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) ?
diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 93ad7ebcd..cf9d97128 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -49,8 +49,10 @@
pointer-events: all;
width: 100%;
height: 100%;
+ position: inherit;
+ display: flex;
position: relative;
- }
+ cursor: default;
.audiobox-record {
pointer-events: none;
@@ -94,116 +96,213 @@
padding: 5px;
}
}
+ .audiobox-buttons {
+ display: flex;
+ width: 100%;
+ align-items: center;
+ height: 100%;
- .audiobox-controls {
- width: 100%;
- height: 100%;
- position: relative;
- display: flex;
- background: $dark-gray;
+ .audiobox-dictation {
+ position: relative;
+ width: 30px;
+ height: 100%;
+ align-items: center;
+ display: inherit;
+ background: $medium-gray;
+ left: 0px;
+ color: $dark-gray;
- .audiobox-dictation {
- position: absolute;
- width: 40px;
- height: 100%;
- align-items: center;
- display: inherit;
- background: $medium-gray;
- left: 0px;
+ &:hover {
+ color: $black;
+ cursor: pointer;
+ }
+ }
}
- .audiobox-player {
- margin-top: auto;
- margin-bottom: auto;
- width: 100%;
- position: relative;
- padding-right: 5px;
- display: flex;
- flex-direction: column;
- justify-content: center;
+ .audiobox-control,
+ .audiobox-control-interactive {
+ top: 0;
+ max-height: 32px;
+ width: 100%;
+ display: inline-block;
+ pointer-events: none;
+ }
+
+ .audiobox-control-interactive {
+ pointer-events: all;
+ }
- .audiobox-buttons {
+ .audiobox-record-interactive,
+ .audiobox-record {
+ pointer-events: all;
+ cursor: pointer;
+ width: 100%;
+ height: 100%;
position: relative;
- margin-top: auto;
- margin-bottom: auto;
- width: 30px;
- height: 30px;
- border-radius: 50%;
- background-color: $dark-gray;
- color: $white;
display: flex;
+ flex-direction: row;
align-items: center;
justify-content: center;
- left: 5px;
- &:hover {
- background-color: $black;
- }
+ gap: 10px;
+ color: white;
+ font-weight: bold;
+ }
- svg {
- width: 100%;
- position: absolute;
- border-width: "thin";
- border-color: "white";
- }
- }
+ .audiobox-record {
+ pointer-events: none;
+ }
- .audiobox-dictation {
- position: relative;
+ .recording {
margin-top: auto;
margin-bottom: auto;
- width: 25px;
+ width: 100%;
+ height: 100%;
+ position: relative;
+ padding-right: 5px;
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
align-items: center;
- display: inherit;
- background: $medium-gray;
- }
+ gap: 7px;
+ background-color: $medium-blue;
+ padding: 10px;
+
+ .time {
+ position: relative;
+ height: 100%;
+ width: 100%;
+ font-size: 16px;
+ text-align: center;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-weight: bold;
+ }
+
+ .buttons {
+ cursor: pointer;
+ position: relative;
+ margin-top: auto;
+ margin-bottom: auto;
+ width: 25px;
+ width: 25px;
+ padding: 5px;
+ color: $dark-gray;
+
+ &:hover {
+ color: $black;
+ }
+ }
+ }
- .audiobox-timeline {
- position: absolute;
+ .audiobox-controls {
width: 100%;
- z-index: 1000;
- overflow: hidden;
- border-right: 5px solid black;
- }
+ height: 100%;
+ position: relative;
+ display: flex;
+ background: $dark-gray;
- .audioBox-total-time,
- .audioBox-current-time {
- position: absolute;
- font-size: $small-text;
- top: 100%;
- color: $white;
- }
- .audioBox-current-time {
- left: 42px;
- }
+ .audiobox-dictation {
+ position: absolute;
+ width: 40px;
+ height: 100%;
+ align-items: center;
+ display: inherit;
+ background: $medium-gray;
+ left: 0px;
+ }
- .audioBox-total-time {
- right: 2px;
- }
+ .audiobox-player {
+ margin-top: auto;
+ margin-bottom: auto;
+ width: 100%;
+ position: relative;
+ padding-right: 5px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+
+ .audiobox-buttons {
+ position: relative;
+ margin-top: auto;
+ margin-bottom: auto;
+ width: 30px;
+ height: 30px;
+ border-radius: 50%;
+ background-color: $dark-gray;
+ color: $white;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ left: 5px;
+
+ &:hover {
+ background-color: $black;
+ }
+
+ svg {
+ width: 100%;
+ position: absolute;
+ border-width: "thin";
+ border-color: "white";
+ }
+ }
+
+ .audiobox-dictation {
+ position: relative;
+ margin-top: auto;
+ margin-bottom: auto;
+ width: 25px;
+ align-items: center;
+ display: inherit;
+ background: $medium-gray;
+ }
+
+ .audiobox-timeline {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ overflow: hidden;
+ border-right: 5px solid black;
+ }
+
+ .audioBox-total-time,
+ .audioBox-current-time {
+ position: absolute;
+ font-size: $small-text;
+ top: 100%;
+ color: $white;
+ }
+
+ .audioBox-current-time {
+ left: 42px;
+ }
+
+ .audioBox-total-time {
+ right: 2px;
+ }
+ }
}
- }
}
@media only screen and (max-device-width: 480px) {
- .audiobox-dictation {
- font-size: 5em;
- display: flex;
- width: 100;
- justify-content: center;
- flex-direction: column;
- align-items: center;
- }
+ .audiobox-dictation {
+ font-size: 5em;
+ display: flex;
+ width: 100;
+ justify-content: center;
+ flex-direction: column;
+ align-items: center;
+ }
- .audiobox-container .audiobox-record,
- .audiobox-container-interactive .audiobox-record {
- font-size: 3em;
- }
+ .audiobox-container .audiobox-record,
+ .audiobox-container-interactive .audiobox-record {
+ font-size: 3em;
+ }
- .audiobox-container .audiobox-controls .audiobox-player .audiobox-buttons,
- .audiobox-container .audiobox-controls .audiobox-player .audiobox-dictation,
- .audiobox-container-interactive
- .audiobox-controls
- .audiobox-player
- .audiobox-buttons {
- width: 70px;
- }
-}
+ .audiobox-container .audiobox-controls .audiobox-player .audiobox-buttons,
+ .audiobox-container .audiobox-controls .audiobox-player .audiobox-dictation,
+ .audiobox-container-interactive .audiobox-controls .audiobox-player .audiobox-buttons {
+ width: 70px;
+ }
+} \ No newline at end of file
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 05dd64b68..cdb37bf92 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -605,10 +605,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
<div className="audiobox-dictation" onClick={this.onFile}>
<FontAwesomeIcon
style={{
- width: "30px",
- background: !this.layoutDoc.dontAutoPlayFollowedLinks
- ? Colors.LIGHT_BLUE
- : "rgba(0,0,0,0)",
+ width: "30px"
}}
icon="file-alt"
size={this.props.PanelHeight() < 36 ? "1x" : "2x"}
@@ -642,6 +639,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
className={`audiobox-record${interactive}`}
style={{ backgroundColor: Colors.DARK_GRAY }}
>
+ <FontAwesomeIcon icon="microphone" />
RECORD
</div>
)}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a2d2f17b6..193befa5d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -13,7 +13,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Ty
import { AudioField } from "../../../fields/URLField";
import { GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util';
import { MobileInterface } from '../../../mobile/MobileInterface';
-import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils, lightOrDark } from "../../../Utils";
+import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils, lightOrDark, simulateMouseClick } from "../../../Utils";
import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
import { Docs, DocUtils } from "../../documents/Documents";
import { DocumentType } from '../../documents/DocumentTypes';
@@ -49,6 +49,7 @@ import { RadialMenu } from './RadialMenu';
import { ScriptingBox } from "./ScriptingBox";
import { PresBox } from './trails/PresBox';
import React = require("react");
+import { IconProp } from "@fortawesome/fontawesome-svg-core";
const { Howl } = require('howler');
interface Window {
@@ -153,7 +154,7 @@ export interface DocumentViewProps extends DocumentViewSharedProps {
NativeWidth?: () => number;
NativeHeight?: () => number;
LayoutTemplate?: () => Opt<Doc>;
- contextMenuItems?: () => { script: ScriptField, label: string }[];
+ contextMenuItems?: () => { script: ScriptField, filter?: ScriptField, label: string, icon: string }[];
onClick?: () => ScriptField;
onDoubleClick?: () => ScriptField;
onPointerDown?: () => ScriptField;
@@ -535,6 +536,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
onPointerMove = (e: PointerEvent): void => {
+ if (e.cancelBubble) return;
if ((InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || [InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool))) return;
if (e.cancelBubble && this.props.isDocumentActive?.()) {
document.removeEventListener("pointermove", this.onPointerMove); // stop listening to pointerMove if something else has stopPropagated it (e.g., the MarqueeView)
@@ -669,11 +671,23 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
const cm = ContextMenu.Instance;
if (!cm || (e as any)?.nativeEvent?.SchemaHandled) return;
+ if (e?.buttons === 2) {
+ const onDisplay = () => setTimeout(() => {
+ DocumentViewInternal.SelectAfterContextMenu && !this.props.isSelected(true) && SelectionManager.SelectView(this.props.DocumentView(), false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear.
+ setTimeout(() => {
+ const ele = document.elementFromPoint(e.clientX, e.clientY);
+ simulateMouseClick(ele, e.clientX, e.clientY, e.screenX, e.screenY);
+ });
+ });
+ cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15, undefined, undefined, onDisplay);
+ return;
+ }
+
const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []);
StrListCast(this.Document.contextMenuLabels).forEach((label, i) =>
cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ documentView: this, this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" }));
this.props.contextMenuItems?.().forEach(item =>
- item.label && cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" }));
+ item.label && cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: item.icon as IconProp }));
if (!this.props.Document.isFolder) {
const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null);
@@ -775,7 +789,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
if (!this.topMost) e?.stopPropagation(); // DocumentViews should stop propagation of this event
cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15);
- DocumentViewInternal.SelectAfterContextMenu && !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView(), false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear.
}
rootSelected = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false;
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 38deb4a73..b41bfd3ea 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -144,9 +144,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
const funcs: ContextMenuProps[] = [];
funcs.push({ description: "Rotate Clockwise 90", event: this.rotate, icon: "expand-arrows-alt" });
funcs.push({ description: `Show ${this.layoutDoc._showFullRes ? "Dynamic Res" : "Full Res"}`, event: this.resolution, icon: "expand-arrows-alt" });
+ funcs.push({ description: "Copy path", event: () => Utils.CopyText(this.choosePath(field.url)), icon: "expand-arrows-alt" });
if (!Doc.UserDoc().noviceMode) {
funcs.push({ description: "Export to Google Photos", event: () => GooglePhotos.Transactions.UploadImages([this.props.Document]), icon: "caret-square-right" });
- funcs.push({ description: "Copy path", event: () => Utils.CopyText(field.url.href), icon: "expand-arrows-alt" });
const existingAnalyze = ContextMenu.Instance?.findByDescription("Analyzers...");
const modes: ContextMenuProps[] = existingAnalyze && "subitems" in existingAnalyze ? existingAnalyze.subitems : [];
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 9706d73c7..ce851b830 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -226,10 +226,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
specificContextMenu = (e: React.MouseEvent): void => {
const funcs: ContextMenuProps[] = [];
- funcs.push({ description: "Copy path", event: () => this.pdfUrl && Utils.CopyText(this.pdfUrl.url.pathname), icon: "expand-arrows-alt" });
- funcs.push({ description: "Toggle Fit Width " + (this.Document._fitWidth ? "Off" : "On"), event: () => this.Document._fitWidth = !this.Document._fitWidth, icon: "expand-arrows-alt" });
- funcs.push({ description: "Toggle Annotation View ", event: () => this.Document._showSidebar = !this.Document._showSidebar, icon: "expand-arrows-alt" });
- funcs.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" });
+ funcs.push({ description: "Copy path", event: () => this.pdfUrl && Utils.CopyText(Utils.prepend("") + this.pdfUrl.url.pathname), icon: "expand-arrows-alt" });
+ //funcs.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" });
ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 7e46d8433..19135b6dd 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -69,13 +69,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
constructor(props: any) {
super(props);
- if (true) {// his.webField) {
- Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || 850);
- Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || this.Document[HeightSym]() / this.Document[WidthSym]() * 850);
- }
- if (this.layoutDoc[this.fieldKey + "-contentWidth"] === undefined) {
- this.layoutDoc[this.fieldKey + "-contentWidth"] = Doc.NativeWidth(this.layoutDoc);
- }
+ // if (true) {// his.webField) {
+ // Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || 850);
+ // Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || this.Document[HeightSym]() / this.Document[WidthSym]() * 850);
+ // }
}
async componentDidMount() {
@@ -323,13 +320,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (future === undefined) this.dataDoc[this.fieldKey + "-future"] = new List<string>([this._url]);
else this.dataDoc[this.fieldKey + "-future"] = new List<string>([...future, this._url]);
this.dataDoc[this.fieldKey] = new WebField(new URL(history.pop()!));
+ console.log(this._urlHash);
return true;
}
return false;
}
static urlHash = (s: string) => {
- return s.split('').reduce((a: any, b: any) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0);
+ return Math.abs(s.split('').reduce((a: any, b: any) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0));
}
@action
@@ -397,8 +395,15 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const cm = ContextMenu.Instance;
const funcs: ContextMenuProps[] = [];
funcs.push({ description: (this.layoutDoc.useCors ? "Don't Use" : "Use") + " Cors", event: () => this.layoutDoc.useCors = !this.layoutDoc.useCors, icon: "snowflake" });
- funcs.push({ description: (this.layoutDoc[this.fieldKey + "-contentWidth"] ? "Unfreeze" : "Freeze") + " Content Width", event: () => this.layoutDoc[this.fieldKey + "-contentWidth"] = this.layoutDoc[this.fieldKey + "-contentWidth"] ? undefined : Doc.NativeWidth(this.layoutDoc), icon: "snowflake" });
- funcs.push({ description: "Toggle Annotation View ", event: () => this.Document._showSidebar = !this.Document._showSidebar, icon: "expand-arrows-alt" });
+ funcs.push({
+ description: (!this.layoutDoc.allowReflow ? "Allow" : "Prevent") + " Reflow", event: () => {
+ const nw = !this.layoutDoc.allowReflow ? undefined : Doc.NativeWidth(this.layoutDoc) - this.sidebarWidth() / (this.props.scaling?.() || 1);
+ this.layoutDoc.allowReflow = !nw;
+ if (nw) {
+ Doc.SetInPlace(this.layoutDoc, this.fieldKey + "-nativeWidth", nw, true);
+ }
+ }, icon: "snowflake"
+ });
cm.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
}
@@ -487,7 +492,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@computed get content() {
return <div className={"webBox-cont" + (!this.props.docViewPath().lastElement()?.docView?._pendingDoubleClick && this.props.isContentActive() && CurrentUserUtils.SelectedTool === InkTool.None && !DocumentDecorations.Instance?.Interacting ? "-interactive" : "")}
- style={{ width: NumCast(this.layoutDoc[this.fieldKey + "-contentWidth"]) || `${100 / (this.props.scaling?.() || 1)}%`, }}>
+ style={{ width: !this.layoutDoc.allowReflow ? NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]) || `100%` : "100%", }}>
{this.urlContent}
</div>;
}
diff --git a/src/client/views/nodes/button/FontIconBox.scss b/src/client/views/nodes/button/FontIconBox.scss
index a2da35fe1..079c767b9 100644
--- a/src/client/views/nodes/button/FontIconBox.scss
+++ b/src/client/views/nodes/button/FontIconBox.scss
@@ -342,14 +342,18 @@
}
&.editableText {
- cursor: pointer;
- background: transparent;
+ cursor: text;
+ display: flex;
+ flex-direction: row;
+ gap: 5px;
+ padding-left: 10px;
+ justify-content: flex-start;
+ color: black;
+ background-color: $light-gray;
+ padding: 5px;
+ padding-left: 10px;
width: 100%;
height: 100%;
-
- &:hover {
- background-color: $close-red;
- }
}
&.drpDownBtn {
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index b1d74261b..9d1ef937f 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -26,12 +26,10 @@ import { SetActiveInkColor, ActiveFillColor, SetActiveFillColor, ActiveInkWidth,
import { StyleProp } from '../../StyleProvider';
import { FieldView, FieldViewProps } from '.././FieldView';
import { RichTextMenu } from '../formattedText/RichTextMenu';
-import { TextButton } from './textButton';
-import { ToggleButton } from './toggleButton';
+import { Utils } from '../../../../Utils';
import { IButtonProps } from './ButtonInterface';
import { FontIconBadge } from './FontIconBadge';
import './FontIconBox.scss';
-import { undo } from 'prosemirror-history';
import { WebBox } from '../WebBox';
const FontIconSchema = createSchema({
icon: "string",
@@ -246,7 +244,6 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
let text: string | undefined;
let dropdown = true;
let icon: IconProp = "caret-down";
- let noneSelected: boolean = false;
if (script === 'setView') {
const selected = SelectionManager.Docs().lastElement();
@@ -301,7 +298,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
<div className={`menuButton ${this.type} ${active}`}
style={{ backgroundColor: this.rootDoc.dropDownOpen ? Colors.MEDIUM_BLUE : backgroundColor, color: color, display: dropdown ? undefined : "flex" }}
onClick={dropdown ? () => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen : undefined}>
- {dropdown || noneSelected ? (null) : <FontAwesomeIcon style={{ marginLeft: 5 }} className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />}
+ {dropdown ? (null) : <FontAwesomeIcon style={{ marginLeft: 5 }} className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />}
<div className="menuButton-dropdown-header">
{text && text[0].toUpperCase() + text.slice(1)}
</div>
@@ -334,23 +331,14 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
const scriptCheck: string = script + "(undefined, true)";
const boolResult = ScriptField.MakeScript(scriptCheck)?.script.run().result;
- let stroke: boolean = false;
- let strokeIcon: any;
- // if (script === "setStrokeColor") {
- // stroke = true;
- // const checkWidth = ScriptField.MakeScript("setStrokeWidth(0, true)")?.script.run().result;
- // const width = 20 + (checkWidth / 100) * 70;
- // const height = 20 + (checkWidth / 100) * 70;
- // strokeIcon = (<div style={{ borderRadius: "100%", width: width + '%', height: height + '%', backgroundColor: boolResult ? boolResult : "#FFFFFF" }} />);
- // }
-
const colorOptions: string[] = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
'#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
'#FFFFFF', '#f1efeb', "transparent"];
const colorBox = (func: (color: ColorState) => void) => <SketchPicker
- disableAlpha={!stroke}
- onChange={func} color={boolResult ? boolResult : "#FFFFFF"}
+ disableAlpha={false}
+ onChange={func}
+ color={boolResult ? boolResult : "#FFFFFF"}
presetColors={colorOptions} />;
const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
<div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
@@ -364,21 +352,16 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
</div>;
const click = (value: ColorState) => {
- const hex: string = value.hex;
- const s = ScriptField.MakeScript(script + '("' + hex + '", false)');
- if (s) {
- undoBatch(() => s.script.run().result)();
- }
+ const s = ScriptField.MakeScript(script + '("' + Utils.colorString(value) + '", false)');
+ s && undoBatch(() => s.script.run().result)();
};
return (
<div className={`menuButton ${this.type} ${active}`}
style={{ color: color, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
onClick={() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen}
onPointerDown={e => e.stopPropagation()}>
- {stroke ? strokeIcon : <><FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
- <div className="colorButton-color"
- style={{ backgroundColor: boolResult ? boolResult : "#FFFFFF" }}
- ></div></>}
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ <div className="colorButton-color" style={{ backgroundColor: boolResult ? boolResult : "#FFFFFF" }} />
{label}
{/* {dropdownCaret} */}
{this.rootDoc.dropDownOpen ?
@@ -499,7 +482,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
backgroundColor: backgroundColor,
icon: this.icon,
color: color
- }
+ };
const buttonText = StrCast(this.rootDoc.buttonText);
@@ -522,7 +505,6 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
// button = <TextButton {...buttonProps}></TextButton>
break;
case ButtonType.EditableText:
- console.log("Editable text");
button = this.editableText;
break;
case ButtonType.NumberButton:
@@ -592,7 +574,6 @@ Scripting.addGlobal(function setBackgroundColor(color?: string, checkResult?: bo
const selected = SelectionManager.Docs().lastElement();
if (checkResult) {
if (selected) {
- console.log("[Background] (selected): " + StrCast(selected._backgroundColor));
return selected._backgroundColor;
} else {
return "#FFFFFF";
@@ -605,6 +586,9 @@ Scripting.addGlobal(function setBackgroundColor(color?: string, checkResult?: bo
// toggle: Set overlay status of selected document
Scripting.addGlobal(function setHeaderColor(color?: string, checkResult?: boolean) {
+ if (checkResult) {
+ return Doc.SharingDoc().userColor;
+ }
Doc.SharingDoc().userColor = undefined;
Doc.GetProto(Doc.SharingDoc()).userColor = color;
Doc.UserDoc().showTitle = color === "transparent" ? undefined : StrCast(Doc.UserDoc().showTitle, "creationDate");
@@ -685,14 +669,12 @@ Scripting.addGlobal(function setBulletList(mapStyle: "bullet" | "decimal", check
const editorView = RichTextMenu.Instance?.TextView?.EditorView;
if (checkResult) {
const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
- console.log(active, mapStyle);
if (active === mapStyle) return Colors.MEDIUM_BLUE;
else return "transparent";
}
if (editorView) {
const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
if (active === mapStyle) {
- console.log("set bullet list");
editorView?.state && RichTextMenu.Instance.changeListType(editorView.state.schema.nodes.ordered_list.create({ mapStyle: "" }));
} else {
editorView?.state && RichTextMenu.Instance.changeListType(editorView.state.schema.nodes.ordered_list.create({ mapStyle: mapStyle }));
@@ -707,10 +689,8 @@ Scripting.addGlobal(function setFontColor(color?: string, checkResult?: boolean)
if (checkResult) {
if (selected) {
- console.log("[Font color] (selected): " + StrCast(selected._fontColor));
return selected._fontColor;
} else {
- console.log("[Font color] (global): " + StrCast(Doc.UserDoc()._fontColor));
return Doc.UserDoc()._fontColor;
}
}
@@ -760,12 +740,16 @@ Scripting.addGlobal(function setFontSize(size: string, checkResult?: boolean) {
Scripting.addGlobal(function toggleBold(checkResult?: boolean) {
if (checkResult) {
- if (Doc.UserDoc().bold) return Colors.MEDIUM_BLUE;
+ const editorView = RichTextMenu.Instance.TextView?.EditorView;
+ if (editorView) {
+ const bold: boolean = editorView?.state && RichTextMenu.Instance.getBoldStatus();
+ if (bold) return Colors.MEDIUM_BLUE;
+ else return "transparent";
+ }
else return "transparent";
}
const editorView = RichTextMenu.Instance.TextView?.EditorView;
if (editorView) {
- console.log("editorView");
editorView?.state && RichTextMenu.Instance.toggleBold(editorView, true);
}
SelectionManager.Docs().filter(doc => StrCast(doc.type) === DocumentType.RTF).map(doc => doc.bold = !doc.bold);
@@ -775,12 +759,10 @@ Scripting.addGlobal(function toggleBold(checkResult?: boolean) {
Scripting.addGlobal(function toggleUnderline(checkResult?: boolean) {
if (checkResult) {
- if (Doc.UserDoc().underline) return Colors.MEDIUM_BLUE;
- else return "transparent";
+ return "transparent";
}
const editorView = RichTextMenu.Instance.TextView?.EditorView;
if (editorView) {
- console.log("editorView");
editorView?.state && RichTextMenu.Instance.toggleUnderline(editorView, true);
}
SelectionManager.Docs().filter(doc => StrCast(doc.type) === DocumentType.RTF).map(doc => doc.underline = !doc.underline);
@@ -790,12 +772,10 @@ Scripting.addGlobal(function toggleUnderline(checkResult?: boolean) {
Scripting.addGlobal(function toggleItalic(checkResult?: boolean) {
if (checkResult) {
- if (Doc.UserDoc().italic) return Colors.MEDIUM_BLUE;
- else return "transparent";
+ return "transparent";
}
const editorView = RichTextMenu.Instance.TextView?.EditorView;
if (editorView) {
- console.log("editorView");
editorView?.state && RichTextMenu.Instance.toggleItalic(editorView, true);
}
SelectionManager.Docs().filter(doc => StrCast(doc.type) === DocumentType.RTF).map(doc => doc.italic = !doc.italic);
@@ -909,7 +889,6 @@ Scripting.addGlobal(function webBack() {
**/
Scripting.addGlobal(function toggleSchemaPreview(checkResult?: boolean) {
const selected = SelectionManager.Docs().lastElement();
- console.log(selected && selected.title);
if (checkResult && selected) {
const result: boolean = NumCast(selected.schemaPreviewWidth) > 0;
if (result) return Colors.MEDIUM_BLUE;
diff --git a/src/client/views/nodes/button/colorDropdown/ColorDropdown.tsx b/src/client/views/nodes/button/colorDropdown/ColorDropdown.tsx
index 1809f4e2e..235495250 100644
--- a/src/client/views/nodes/button/colorDropdown/ColorDropdown.tsx
+++ b/src/client/views/nodes/button/colorDropdown/ColorDropdown.tsx
@@ -14,8 +14,7 @@ export class ColorDropdown extends Component<IButtonProps> {
const scriptCheck: string = script + "(undefined, true)";
const boolResult = ScriptField.MakeScript(scriptCheck)?.script.run().result;
- let stroke: boolean = false;
- let strokeIcon: any;
+ const stroke: boolean = false;
// if (script === "setStrokeColor") {
// stroke = true;
// const checkWidth = ScriptField.MakeScript("setStrokeWidth(0, true)")?.script.run().result;
@@ -55,10 +54,9 @@ export class ColorDropdown extends Component<IButtonProps> {
style={{ color: this.props.color, borderBottomLeftRadius: active ? 0 : undefined }}
onClick={() => this.props.rootDoc.dropDownOpen = !this.props.rootDoc.dropDownOpen}
onPointerDown={e => e.stopPropagation()}>
- {stroke ? strokeIcon : <><FontAwesomeIcon className={`fontIconBox-icon-${this.props.type}`} icon={this.props.icon} color={this.props.color} />
- <div className="colorButton-color"
- style={{ backgroundColor: boolResult ? boolResult : "#FFFFFF" }}
- ></div></>}
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.props.type}`} icon={this.props.icon} color={this.props.color} />
+ <div className="colorButton-color"
+ style={{ backgroundColor: boolResult ? boolResult : "#FFFFFF" }} />
{label}
{/* {dropdownCaret} */}
{this.props.rootDoc.dropDownOpen ?
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index 4134e3c67..27817f317 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -71,6 +71,7 @@ audiotag:hover {
//top: calc(50% - 17.5px); // use this to center vertically -- make sure it looks okay for slide views
width: 17px;
height: 17px;
+ font-size: 11px;
border-radius: 3px;
color: white;
background: $medium-gray;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index e7a44f113..acc2892d8 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -214,6 +214,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
@action
setupAnchorMenu = () => {
AnchorMenu.Instance.Status = "marquee";
+
+ AnchorMenu.Instance.OnClick = (e: PointerEvent) => {
+ !this.layoutDoc.showSidebar && this.toggleSidebar();
+ this._sidebarRef.current?.anchorMenuClick(this.getAnchor());
+ };
AnchorMenu.Instance.Highlight = action((color: string, isLinkButton: boolean) => {
this._editorView?.state && RichTextMenu.Instance.setHighlight(color, this._editorView, this._editorView?.dispatch);
return undefined;
@@ -818,11 +823,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this._disposers.breakupDictation = reaction(() => DocumentManager.Instance.RecordingEvent, this.breakupDictation);
this._disposers.autoHeight = reaction(() => this.autoHeight, autoHeight => autoHeight && this.tryUpdateScrollHeight());
this._disposers.scrollHeight = reaction(() => ({ scrollHeight: this.scrollHeight, autoHeight: this.autoHeight, width: NumCast(this.layoutDoc._width) }),
- ({ width, scrollHeight, autoHeight }) => width && autoHeight && this.resetNativeHeight(scrollHeight)
+ ({ width, scrollHeight, autoHeight }) => {
+ width && autoHeight && this.resetNativeHeight(scrollHeight);
+ }, { fireImmediately: true }
);
this._disposers.componentHeights = reaction( // set the document height when one of the component heights changes and autoHeight is on
() => ({ sidebarHeight: this.sidebarHeight, textHeight: this.textHeight, autoHeight: this.autoHeight, marginsHeight: this.autoHeightMargins }),
- ({ sidebarHeight, textHeight, autoHeight, marginsHeight }) => autoHeight && this.props.setHeight(marginsHeight + Math.max(sidebarHeight, textHeight)));
+ ({ sidebarHeight, textHeight, autoHeight, marginsHeight }) => {
+ autoHeight && this.props.setHeight(marginsHeight + Math.max(sidebarHeight, textHeight));
+ }, { fireImmediately: true });
this._disposers.links = reaction(() => DocListCast(this.Document.links), // if a link is deleted, then remove all hyperlinks that reference it from the text's marks
newLinks => {
this._cachedLinks.forEach(l => !newLinks.includes(l) && this.RemoveLinkFromDoc(l));
@@ -1156,7 +1165,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
selectOnLoad && this._editorView!.focus();
// add user mark for any first character that was typed since the user mark that gets set in KeyPress won't have been called yet.
if (this._editorView && !this._editorView.state.storedMarks?.some(mark => mark.type === schema.marks.user_mark)) {
- this._editorView.state.storedMarks = [...(this._editorView!.state.storedMarks ?? []), schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })];
+ this._editorView.state.storedMarks = [...(this._editorView.state.storedMarks ?? []), schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })];
}
}
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 3919fbf94..86f2810ab 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -142,6 +142,18 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
}
+ getBoldStatus() {
+ if (this.view && this.TextView.props.isSelected(true)) {
+ const path = (this.view.state.selection.$from as any).path;
+ for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) {
+ if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) {
+ console.log(path[i].attrs);
+ return path[i].attrs.strong;
+ }
+ }
+ }
+ }
+
// finds font sizes and families in selection
getActiveAlignment() {
if (this.view && this.TextView.props.isSelected(true)) {
@@ -208,7 +220,6 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
const found = new Set<Mark>();
const { from, to } = state.selection as TextSelection;
state.doc.nodesBetween(from, to, (node) => node.marks.forEach(m => found.add(m)));
- console.log("Marks: " + found);
return found;
}
@@ -590,7 +601,6 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
@undoBatch
makeLinkToURL = (target: string, lcoation: string) => {
((this.view as any)?.TextView as FormattedTextBox).makeLinkAnchor(undefined, "onRadd:rightight", target, target);
- console.log((this.view as any)?.TextView);
}
@undoBatch
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 1abe26c20..add84ff83 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -401,11 +401,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
LightboxView.SetLightboxDoc(targetDoc);
} else if (curDoc.presMovement === PresMovement.Pan && targetDoc) {
LightboxView.SetLightboxDoc(undefined);
- await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection); // documents open in new tab instead of on right
+ await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true); // documents open in new tab instead of on right
} else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) {
LightboxView.SetLightboxDoc(undefined);
//awaiting jump so that new scale can be found, since jumping is async
- await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection); // documents open in new tab instead of on right
+ await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true); // documents open in new tab instead of on right
}
// After navigating to the document, if it is added as a presPinView then it will
// adjust the pan and scale to that of the pinView when it was added.
@@ -413,8 +413,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
// if targetDoc is not displayed but one of its aliases is, then we need to modify that alias, not the original target
this.navigateToView(targetDoc, activeItem);
}
- // TODO: Add progressivize for navigating web (storing websites for given frames)
-
}
/**
@@ -1220,7 +1218,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
<input className="presBox-input"
type="number" value={duration}
onChange={action((e) => this.setDurationTime(e.target.value))} /> s
- </div>
+ </div>
<div className="ribbon-propertyUpDown">
<div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), 1000))}>
<FontAwesomeIcon icon={"caret-up"} />
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index 3ba427c29..ad3afb775 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -155,9 +155,10 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
</button>
</Tooltip>,
//NOTE: link popup is currently in progress
- <Tooltip key="link" title={<div className="dash-tooltip">{"Link selected text to document"}</div>}>
+ <Tooltip key="link" title={<div className="dash-tooltip">{"Find document to link to selected text"}</div>}>
<button className="antimodeMenu-button link" onPointerDown={this.toggleLinkPopup} style={{}}>
- <FontAwesomeIcon icon="link" size="lg" />
+ <FontAwesomeIcon style={{ position: "absolute", transform: "scale(1.5)" }} icon={"search"} size="lg" />
+ <FontAwesomeIcon style={{ position: "absolute", transform: "scale(0.5)", transformOrigin: "top left", top: 12, left: 12 }} icon={"link"} size="lg" />
</button>
</Tooltip>,
<LinkPopup key="popup" showPopup={this._showLinkPopup} linkFrom={this.onMakeAnchor} />