From 606088e419f0e146715244d00840349b587c80ba Mon Sep 17 00:00:00 2001
From: bobzel
Date: Sun, 17 Mar 2024 11:50:15 -0400
Subject: use metakey to edit computedfield result instead of expression in
schema cell, set default new field values on data doc. fixed stacking view
from autoresizing when switching to a different collection view. changed
syntax for setting fields in text docs to use ':=' for computed fields.
Added call to Chat in computed functions when (( )) is used. Added caching
of computed function result when a function called by ComputedField uses the
_setCacheResult_ method (currently only gptCallChat).
---
.../collectionSchema/CollectionSchemaView.tsx | 11 ++++++-----
.../collectionSchema/SchemaTableCell.tsx | 23 ++++++++++++----------
2 files changed, 19 insertions(+), 15 deletions(-)
(limited to 'src/client/views/collections/collectionSchema')
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 12f0ad5e9..4a0ca8fe5 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -1,5 +1,6 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, makeObservable, observable, ObservableMap, observe, trace } from 'mobx';
+import { Popup, PopupTrigger, Type } from 'browndash-components';
+import { action, computed, makeObservable, observable, ObservableMap, observe } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, Field, NumListCast, Opt, StrListCast } from '../../../../fields/Doc';
@@ -12,12 +13,13 @@ import { Docs, DocumentOptions, DocUtils, FInfo } from '../../../documents/Docum
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager, dropActionType } from '../../../util/DragManager';
import { SelectionManager } from '../../../util/SelectionManager';
+import { SettingsManager } from '../../../util/SettingsManager';
import { undoable, undoBatch } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
import { EditableView } from '../../EditableView';
import { Colors } from '../../global/globalEnums';
import { DocumentView } from '../../nodes/DocumentView';
-import { FocusViewOptions, FieldViewProps } from '../../nodes/FieldView';
+import { FieldViewProps, FocusViewOptions } from '../../nodes/FieldView';
import { KeyValueBox } from '../../nodes/KeyValueBox';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { DefaultStyleProvider, StyleProp } from '../../StyleProvider';
@@ -25,8 +27,7 @@ import { CollectionSubView } from '../CollectionSubView';
import './CollectionSchemaView.scss';
import { SchemaColumnHeader } from './SchemaColumnHeader';
import { SchemaRowBox } from './SchemaRowBox';
-import { Popup, PopupTrigger, Type } from 'browndash-components';
-import { SettingsManager } from '../../../util/SettingsManager';
+import { DocData } from '../../../../fields/DocSymbols';
const { default: { SCHEMA_NEW_NODE_HEIGHT } } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore
export enum ColumnType {
@@ -284,7 +285,7 @@ export class CollectionSchemaView extends CollectionSubView() {
};
@action
- addNewKey = (key: string, defaultVal: any) => this.childDocs.forEach(doc => (doc[key] = defaultVal));
+ addNewKey = (key: string, defaultVal: any) => this.childDocs.forEach(doc => (doc[DocData][key] = defaultVal));
@undoBatch
removeColumn = (index: number) => {
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index ed1b519b4..711ef507c 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -1,8 +1,11 @@
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Popup, Size, Type } from 'browndash-components';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import { extname } from 'path';
import * as React from 'react';
import DatePicker from 'react-datepicker';
+import 'react-datepicker/dist/react-datepicker.css';
import Select from 'react-select';
import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../../Utils';
import { DateField } from '../../../../fields/DateField';
@@ -12,6 +15,8 @@ import { BoolCast, Cast, DateCast, DocCast, FieldValue, StrCast } from '../../..
import { ImageField } from '../../../../fields/URLField';
import { FInfo, FInfoFieldType } from '../../../documents/Documents';
import { DocFocusOrOpen } from '../../../util/DocumentManager';
+import { dropActionType } from '../../../util/DragManager';
+import { SettingsManager } from '../../../util/SettingsManager';
import { Transform } from '../../../util/Transform';
import { undoBatch, undoable } from '../../../util/UndoManager';
import { EditableView } from '../../EditableView';
@@ -24,12 +29,7 @@ import { KeyValueBox } from '../../nodes/KeyValueBox';
import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
import { ColumnType, FInfotoColType } from './CollectionSchemaView';
import './CollectionSchemaView.scss';
-import 'react-datepicker/dist/react-datepicker.css';
-import { Popup, Size, Type } from 'browndash-components';
-import { IconLookup, faCaretDown } from '@fortawesome/free-solid-svg-icons';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { SettingsManager } from '../../../util/SettingsManager';
-import { dropActionType } from '../../../util/DragManager';
+import { SnappingManager } from '../../../util/SnappingManager';
export interface SchemaTableCellProps {
Document: Doc;
@@ -129,10 +129,12 @@ export class SchemaTableCell extends ObservableReactComponent Field.toKeyValueString(this._props.Document, this._props.fieldKey)}
+ GetValue={() => Field.toKeyValueString(this._props.Document, this._props.fieldKey, SnappingManager.MetaKey)}
SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => {
if (shiftDown && enterKey) {
this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value);
+ this._props.finishEdit?.();
+ return true;
}
const ret = KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(this._props.Document) ? true : undefined);
this._props.finishEdit?.();
@@ -345,8 +347,7 @@ export class SchemaBoolCell extends ObservableReactComponent | undefined) => {
if ((value?.nativeEvent as any).shiftKey) {
this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + value?.target?.checked.toString());
- }
- KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + value?.target?.checked.toString());
+ } else KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + value?.target?.checked.toString());
})}
/>
{
if (shiftDown && enterKey) {
this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value);
+ this._props.finishEdit?.();
+ return true;
}
- const set = KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value);
+ const set = KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(this._props.Document) ? true : undefined);
this._props.finishEdit?.();
return set;
})}
--
cgit v1.2.3-70-g09d2
From 4ea0ea97359cf2f3e97367dafbfaf9157ecc987b Mon Sep 17 00:00:00 2001
From: bobzel
Date: Sat, 23 Mar 2024 15:30:49 -0400
Subject: made backspace deleting a schema row undoable. fixed calling chat on
string fields
---
src/client/views/collections/collectionSchema/CollectionSchemaView.tsx | 2 +-
src/client/views/nodes/KeyValueBox.tsx | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
(limited to 'src/client/views/collections/collectionSchema')
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 4a0ca8fe5..5f4948808 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -238,7 +238,7 @@ export class CollectionSchemaView extends CollectionSubView() {
}
break;
case 'Backspace': {
- this.removeDocument(this._selectedDocs);
+ undoable(() => this.removeDocument(this._selectedDocs), 'delete schema row');
break;
}
case 'Escape': {
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index d85432631..5394c7dbb 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -105,7 +105,8 @@ export class KeyValueBox extends ObservableReactComponent {
default: {
const _setCacheResult_ = (value: FieldResult) => {
field = value as Field;
- setResult?.(value);
+ if (setResult) setResult?.(value);
+ else target[key] = field;
};
const res = script.run({ this: Doc.Layout(doc), self: doc, _setCacheResult_ }, console.log);
if (!res.success) {
--
cgit v1.2.3-70-g09d2
From 2e0cb3e0a470994eecbb7f6b2ec87296baf517b9 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Sun, 24 Mar 2024 19:04:42 -0400
Subject: fixed linkdocpreviews to sequence through multiple links. fixed text
boxes to update text when dashfieldView text changes (but the fieldview
doesn't), fixed dashFieldViews to be editable cleanly, and to allow
sub-dashFieldViews to be editbale. allowed toggle on/off of dashFieldView
fieldKey. got rid of sidebars in scemaCells. fied editing dashFieldViews
in captions and as childrend of dashFieldViews by passing rootSelected
---
.../collectionSchema/SchemaTableCell.tsx | 9 ++++-
src/client/views/nodes/DocumentView.tsx | 1 +
src/client/views/nodes/LinkDocPreview.tsx | 1 +
.../views/nodes/formattedText/DashFieldView.scss | 32 ++++++++++-----
.../views/nodes/formattedText/DashFieldView.tsx | 45 ++++++++++++++--------
.../views/nodes/formattedText/FormattedTextBox.tsx | 26 +++++++++----
6 files changed, 80 insertions(+), 34 deletions(-)
(limited to 'src/client/views/collections/collectionSchema')
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index 711ef507c..ce73ff8a4 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -51,6 +51,8 @@ export interface SchemaTableCellProps {
options?: string[];
menuTarget: HTMLDivElement | null;
transform: () => Transform;
+ autoFocus?: boolean; // whether to set focus on creation, othwerise wait for a click
+ rootSelected?: () => boolean;
}
@observer
@@ -89,6 +91,7 @@ export class SchemaTableCell extends ObservableReactComponent
this._props.autoFocus && r?.setIsFocused(true)}
oneLine={this._props.oneLine}
allowCRs={this._props.allowCRs}
contents={undefined}
@@ -314,13 +319,15 @@ export class SchemaRTFCell extends ObservableReactComponent this.selected;
render() {
const { color, textDecoration, fieldProps, cursor, pointerEvents } = SchemaTableCell.renderProps(this._props);
fieldProps.isContentActive = this.selectedFunc;
return (
- {this.selected ? : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
+ {this.selected ? this._props.finishEdit?.()} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
);
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index e9ce98583..1044d6609 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -892,6 +892,7 @@ export class DocumentViewInternal extends DocComponent this._expanded && this._props.editable;
- finishEdit = action(() => (this._expanded = false));
+
+ finishEdit = action(() => {
+ if (this._expanded) {
+ this._expanded = false;
+ // if the edit finishes, then we want to lose focus on the textBox unless something else in the textBox got focus
+ // the timeout allows switching focus from one dashFieldView to another in the same text box
+ setTimeout(() => !this._props.tbox.ProseRef?.contains(document.activeElement) && this._props.tbox._props.onBlur?.());
+ }
+ });
selectedCell = (): [Doc, number] => [this._dashDoc!, 0];
+ columnWidth = () => Math.min(this._props.tbox._props.PanelWidth(), Math.max(50, this._props.tbox._props.PanelWidth() - 100)); // try to leave room for the fieldKey
// set the display of the field's value (checkbox for booleans, span of text for strings)
@computed get fieldValueContent() {
return !this._dashDoc ? null : (
- (this._expanded = !this._props.editable ? !this._expanded : true))} style={{ fontSize: 'smaller', width: this._props.hideKey ? this._props.tbox._props.PanelWidth() - 20 : undefined }}>
+
(this._expanded = !this._props.editable ? !this._expanded : true))} style={{ fontSize: 'smaller', width: !this._hideKey && this._expanded ? this.columnWidth() : undefined }}>
);
@@ -187,12 +198,12 @@ export class DashFieldViewInternal extends ObservableReactComponent
{
+ onPointerDownLabelSpan = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, returnFalse, returnFalse, e => {
DashFieldViewMenu.createFieldView = this.createPivotForField;
DashFieldViewMenu.toggleFieldHide = this.toggleFieldHide;
@@ -215,7 +226,7 @@ export class DashFieldViewInternal extends ObservableReactComponent
+
{this.values.map(val => (
{val.label}
))}
@@ -272,14 +283,18 @@ export class DashFieldViewMenu extends AntimodeMenu {
};
render() {
return this.getElement(
- {`Show Pivot Viewer for '${this._fieldKey}'`} }>
-
-
-
-
-
-
-
+ <>
+ {`Show Pivot Viewer for '${this._fieldKey}'`}}>
+
+
+
+
+ Toggle view of field key}>
+
+
+
+
+ >
);
}
}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 2b48494f2..793595694 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -21,7 +21,7 @@ import { List } from '../../../../fields/List';
import { PrefetchProxy } from '../../../../fields/Proxy';
import { RichTextField } from '../../../../fields/RichTextField';
import { ComputedField } from '../../../../fields/ScriptField';
-import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { BoolCast, Cast, DocCast, FieldValue, NumCast, RTFCast, ScriptCast, StrCast } from '../../../../fields/Types';
import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util';
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, DivWidth, emptyFunction, numberRange, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, unimplementedFunction, Utils } from '../../../../Utils';
import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT';
@@ -68,8 +68,13 @@ import { RichTextRules } from './RichTextRules';
import { schema } from './schema_rts';
import { SummaryView } from './SummaryView';
// import * as applyDevTools from 'prosemirror-dev-tools';
+
+interface FormattedTextBoxProps extends FieldViewProps {
+ onBlur?: () => void; // callback when text loses focus
+ autoFocus?: boolean; // whether text should get input focus when created
+}
@observer
-export class FormattedTextBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface {
+export class FormattedTextBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface {
public static LayoutString(fieldStr: string) {
return FieldView.LayoutString(FormattedTextBox, fieldStr);
}
@@ -200,7 +205,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent {
if (node.type === this._editorView?.state.schema.nodes.dashField) {
const refDoc = !node.attrs.docId ? this.Document : (DocServer.GetCachedRefField(node.attrs.docId as string) as Doc);
- return Field.toJavascriptString(refDoc[node.attrs.fieldKey as string] as Field);
+ const fieldKey = StrCast(node.attrs.fieldKey);
+ return fieldKey + ':' + Field.toJavascriptString(refDoc[fieldKey] as Field);
}
return '';
};
@@ -359,15 +365,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent this._editorView!.focus()); // not sure why setTimeout is needed but editing dashFieldView's doesn't work without it.
}
// 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.
@@ -1724,6 +1732,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent !this.ProseRef?.contains(document.activeElement) && this._props.onBlur?.());
};
onKeyDown = (e: React.KeyboardEvent) => {
--
cgit v1.2.3-70-g09d2
From ab76273acd2126d92455ff12c4ba80d8bb9473c5 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Sun, 24 Mar 2024 19:22:41 -0400
Subject: fixed crash on richtextfield to string when there's no data. fixed
schema cells not to edit unless selected.
---
src/client/views/collections/collectionSchema/SchemaTableCell.tsx | 2 +-
src/fields/RichTextField.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
(limited to 'src/client/views/collections/collectionSchema')
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index ce73ff8a4..67dc508d5 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -141,7 +141,7 @@ export class SchemaTableCell extends ObservableReactComponent
Date: Tue, 26 Mar 2024 22:34:10 -0400
Subject: added empty image tool and click on empty image to select from
filesystem. fixed following links in lightbox and showing links to
stackedTimelines. fixed embedding docs into text. fixed not resizing text
boxes that also show up in pivot view. prevent context menu from going off
top of screen. fixed freeform clustering colors and click to type. fixed
links to stackedTimeline marks, and titles for marks. made title editing
from doc deco and header use same syntax as keyValue. fixed marquee
selection on webBoxes. turn off transitions in freeformdocview after
timeout. enabled iconifying templates to propagate to "offspring". fixes
images in templates. don't show headr on schema views.
---
src/client/documents/Documents.ts | 52 ++++++++--------
src/client/util/DocumentManager.ts | 4 +-
src/client/views/ContextMenu.tsx | 6 +-
src/client/views/DocumentDecorations.tsx | 71 ++++++++--------------
src/client/views/FieldsDropdown.tsx | 1 -
src/client/views/LightboxView.tsx | 2 +
src/client/views/MarqueeAnnotator.tsx | 19 ++++--
src/client/views/ObservableReactComponent.tsx | 3 +-
src/client/views/PropertiesView.tsx | 2 +-
src/client/views/StyleProvider.tsx | 6 +-
.../collections/CollectionStackedTimeline.tsx | 13 ++--
.../CollectionFreeFormLayoutEngines.tsx | 2 +-
.../collectionFreeForm/CollectionFreeFormView.tsx | 11 ++--
.../collections/collectionFreeForm/MarqueeView.tsx | 4 +-
.../collectionSchema/SchemaTableCell.tsx | 2 +-
src/client/views/global/globalScripts.ts | 4 +-
.../views/nodes/CollectionFreeFormDocumentView.tsx | 24 ++++++--
src/client/views/nodes/DocumentContentsView.tsx | 7 ++-
src/client/views/nodes/DocumentView.tsx | 35 +++++++----
src/client/views/nodes/FieldView.tsx | 1 +
src/client/views/nodes/ImageBox.tsx | 55 +++++++++++++----
src/client/views/nodes/KeyValueBox.tsx | 2 +-
src/client/views/nodes/LabelBox.tsx | 2 +-
src/client/views/nodes/LinkBox.tsx | 47 ++++++++++----
src/client/views/nodes/VideoBox.tsx | 5 +-
src/client/views/nodes/WebBox.tsx | 65 ++++++++++++++------
.../views/nodes/formattedText/FormattedTextBox.tsx | 17 ++++--
src/client/views/nodes/trails/PresBox.tsx | 2 +-
src/fields/Doc.ts | 29 +++++----
src/fields/PresField.ts | 6 --
src/fields/RichTextField.ts | 7 ---
31 files changed, 311 insertions(+), 195 deletions(-)
delete mode 100644 src/fields/PresField.ts
(limited to 'src/client/views/collections/collectionSchema')
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 17cb6fef8..b63c5e429 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1017,8 +1017,8 @@ export namespace Docs {
}
export function ImageDocument(url: string | ImageField, options: DocumentOptions = {}, overwriteDoc?: Doc) {
- const imgField = url instanceof ImageField ? url : new ImageField(url);
- return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: basename(imgField.url.href), ...options }, undefined, undefined, undefined, overwriteDoc);
+ const imgField = url instanceof ImageField ? url : url ? new ImageField(url) : undefined;
+ return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: basename(imgField?.url.href ?? '-no image-'), ...options }, undefined, undefined, undefined, overwriteDoc);
}
export function PresDocument(options: DocumentOptions = {}) {
@@ -1950,6 +1950,31 @@ export namespace DocUtils {
return dd;
}
+ export function assignImageInfo(result: Upload.FileInformation, proto: Doc) {
+ if (Upload.isImageInformation(result)) {
+ const maxNativeDim = Math.min(Math.max(result.nativeHeight, result.nativeWidth), defaultNativeImageDim);
+ const exifRotation = StrCast((result.exifData?.data as any)?.Orientation).toLowerCase();
+ proto['data-nativeOrientation'] = result.exifData?.data?.image?.Orientation ?? (exifRotation.includes('rotate 90') || exifRotation.includes('rotate 270') ? 5 : undefined);
+ proto['data_nativeWidth'] = result.nativeWidth < result.nativeHeight ? (maxNativeDim * result.nativeWidth) / result.nativeHeight : maxNativeDim;
+ proto['data_nativeHeight'] = result.nativeWidth < result.nativeHeight ? maxNativeDim : maxNativeDim / (result.nativeWidth / result.nativeHeight);
+ if (NumCast(proto['data-nativeOrientation']) >= 5) {
+ proto['data_nativeHeight'] = result.nativeWidth < result.nativeHeight ? (maxNativeDim * result.nativeWidth) / result.nativeHeight : maxNativeDim;
+ proto['data_nativeWidth'] = result.nativeWidth < result.nativeHeight ? maxNativeDim : maxNativeDim / (result.nativeWidth / result.nativeHeight);
+ }
+ proto.data_exif = JSON.stringify(result.exifData?.data);
+ proto.data_contentSize = result.contentSize;
+ // exif gps data coordinates are stored in DMS (Degrees Minutes Seconds), the following operation converts that to decimal coordinates
+ const latitude = result.exifData?.data?.GPSLatitude;
+ const latitudeDirection = result.exifData?.data?.GPSLatitudeRef;
+ const longitude = result.exifData?.data?.GPSLongitude;
+ const longitudeDirection = result.exifData?.data?.GPSLongitudeRef;
+ if (latitude !== undefined && longitude !== undefined && latitudeDirection !== undefined && longitudeDirection !== undefined) {
+ proto.latitude = ConvertDMSToDD(latitude[0], latitude[1], latitude[2], latitudeDirection);
+ proto.longitude = ConvertDMSToDD(longitude[0], longitude[1], longitude[2], longitudeDirection);
+ }
+ }
+ }
+
async function processFileupload(generatedDocuments: Doc[], name: string, type: string, result: Error | Upload.FileInformation, options: DocumentOptions, overwriteDoc?: Doc) {
if (result instanceof Error) {
alert(`Upload failed: ${result.message}`);
@@ -1961,28 +1986,7 @@ export namespace DocUtils {
if (doc) {
const proto = Doc.GetProto(doc);
proto.text = result.rawText;
- if (Upload.isImageInformation(result)) {
- const maxNativeDim = Math.min(Math.max(result.nativeHeight, result.nativeWidth), defaultNativeImageDim);
- const exifRotation = StrCast((result.exifData?.data as any)?.Orientation).toLowerCase();
- proto['data-nativeOrientation'] = result.exifData?.data?.image?.Orientation ?? (exifRotation.includes('rotate 90') || exifRotation.includes('rotate 270') ? 5 : undefined);
- proto['data_nativeWidth'] = result.nativeWidth < result.nativeHeight ? (maxNativeDim * result.nativeWidth) / result.nativeHeight : maxNativeDim;
- proto['data_nativeHeight'] = result.nativeWidth < result.nativeHeight ? maxNativeDim : maxNativeDim / (result.nativeWidth / result.nativeHeight);
- if (NumCast(proto['data-nativeOrientation']) >= 5) {
- proto['data_nativeHeight'] = result.nativeWidth < result.nativeHeight ? (maxNativeDim * result.nativeWidth) / result.nativeHeight : maxNativeDim;
- proto['data_nativeWidth'] = result.nativeWidth < result.nativeHeight ? maxNativeDim : maxNativeDim / (result.nativeWidth / result.nativeHeight);
- }
- proto.data_exif = JSON.stringify(result.exifData?.data);
- proto.data_contentSize = result.contentSize;
- // exif gps data coordinates are stored in DMS (Degrees Minutes Seconds), the following operation converts that to decimal coordinates
- const latitude = result.exifData?.data?.GPSLatitude;
- const latitudeDirection = result.exifData?.data?.GPSLatitudeRef;
- const longitude = result.exifData?.data?.GPSLongitude;
- const longitudeDirection = result.exifData?.data?.GPSLongitudeRef;
- if (latitude !== undefined && longitude !== undefined && latitudeDirection !== undefined && longitudeDirection !== undefined) {
- proto.latitude = ConvertDMSToDD(latitude[0], latitude[1], latitude[2], latitudeDirection);
- proto.longitude = ConvertDMSToDD(longitude[0], longitude[1], longitude[2], longitudeDirection);
- }
- }
+ !(result instanceof Error) && DocUtils.assignImageInfo(result, proto);
if (Upload.isVideoInformation(result)) {
proto.data_duration = result.duration;
}
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index a38a330da..40d28c690 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -59,7 +59,7 @@ export class DocumentManager {
private _viewRenderedCbs: { doc: Doc; func: (dv: DocumentView) => any }[] = [];
public AddViewRenderedCb = (doc: Opt, func: (dv: DocumentView) => any) => {
if (doc) {
- const dv = this.getDocumentView(doc);
+ const dv = LightboxView.LightboxDoc ? this.getLightboxDocumentView(doc) : this.getDocumentView(doc);
this._viewRenderedCbs.push({ doc, func });
if (dv) {
this.callAddViewFuncs(dv);
@@ -262,7 +262,7 @@ export class DocumentManager {
return res(this.getDocumentView(docContextPath[0])!);
}
options.didMove = true;
- docContextPath.some(doc => TabDocView.Activate(doc)) || DocumentViewInternal.addDocTabFunc(docContextPath[0], options.openLocation ?? OpenWhere.addRight);
+ (!LightboxView.LightboxDoc && docContextPath.some(doc => TabDocView.Activate(doc))) || DocumentViewInternal.addDocTabFunc(docContextPath[0], options.openLocation ?? OpenWhere.addRight);
this.AddViewRenderedCb(docContextPath[0], dv => res(dv));
}));
if (options.openLocation === OpenWhere.lightbox) {
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index 8f4e43978..ca877b93e 100644
--- a/src/client/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
@@ -218,11 +218,12 @@ export class ContextMenu extends ObservableReactComponent<{}> {
this._width = DivWidth(r);
this._height = DivHeight(r);
}
+ this._searchRef.current?.focus();
})}
style={{
display: this._display ? '' : 'none',
left: this.pageX,
- ...(this._yRelativeToTop ? { top: this.pageY } : { bottom: this.pageY }),
+ ...(this._yRelativeToTop ? { top: Math.max(0, this.pageY) } : { bottom: this.pageY }),
background: SettingsManager.userBackgroundColor,
color: SettingsManager.userColor,
}}>
@@ -265,7 +266,8 @@ export class ContextMenu extends ObservableReactComponent<{}> {
const item = this.flatItems[this._selectedIndex];
if (item) {
item.event({ x: this.pageX, y: this.pageY });
- } else if (this._searchString.startsWith(this._defaultPrefix)) {
+ } else {
+ //if (this._searchString.startsWith(this._defaultPrefix)) {
this._defaultItem?.(this._searchString.substring(this._defaultPrefix.length));
}
this.closeMenu();
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 2fb9f0fc1..4d9b93896 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -34,6 +34,7 @@ import { Colors } from './global/globalEnums';
import { DocumentView, OpenWhereMod } from './nodes/DocumentView';
import { ImageBox } from './nodes/ImageBox';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
+import { KeyValueBox } from './nodes/KeyValueBox';
interface DocumentDecorationsProps {
PanelWidth: number;
@@ -57,7 +58,7 @@ export class DocumentDecorations extends ObservableReactComponent {
- if (this._accumulatedTitle.startsWith('#') || this._accumulatedTitle.startsWith('=')) {
+ if (this._accumulatedTitle.startsWith('$')) {
this._titleControlString = this._accumulatedTitle;
- } else if (this._titleControlString.startsWith('#')) {
+ } else if (this._titleControlString.startsWith('$')) {
if (this._accumulatedTitle.startsWith('-->#')) {
SelectionManager.Docs.forEach(doc => (doc[DocData].onViewMounted = ScriptField.MakeScript(`updateTagsCollection(this)`)));
}
@@ -131,26 +132,7 @@ export class DocumentDecorations extends ObservableReactComponent')) {
- const title = titleField.toString().replace(/\.?/, '');
- const curKey = Doc.LayoutFieldKey(d.Document);
- if (curKey !== title) {
- if (title) {
- if (d.dataDoc[title] === undefined || d.dataDoc[title] instanceof RichTextField || typeof d.dataDoc[title] === 'string') {
- d.Document.layout_fieldKey = `layout_${title}`;
- d.Document[`layout_${title}`] = FormattedTextBox.LayoutString(title);
- d.Document[`${title}_nativeWidth`] = d.Document[`${title}_nativeHeight`] = 0;
- }
- } else {
- d.Document.layout_fieldKey = undefined;
- }
- }
- } else {
- Doc.SetInPlace(d.Document, titleFieldKey, titleField, true);
- }
+ KeyValueBox.SetField(d.Document, titleFieldKey, this._accumulatedTitle);
}),
'edit title'
);
@@ -181,7 +163,8 @@ export class DocumentDecorations extends ObservableReactComponent this.onBackgroundMove(true, e),
emptyFunction,
action(e => {
- !this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('#') ? this.selectionTitle : this._titleControlString);
+ const selected = SelectionManager.Views.length === 1 ? SelectionManager.Docs[0] : undefined;
+ !this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('$') ? (selected && Field.toKeyValueString(selected, this._titleControlString.substring(1))) || '-unset-' : this._titleControlString);
this._editingTitle = true;
this._keyinput.current && setTimeout(this._keyinput.current.focus);
})
@@ -622,11 +605,8 @@ export class DocumentDecorations extends ObservableReactComponent {
- this._editingTitle = false;
- !hideTitle && this.titleBlur();
- })}
- onChange={action(e => !hideTitle && (this._accumulatedTitle = e.target.value))}
- onKeyDown={hideTitle ? emptyFunction : this.titleEntered}
- onPointerDown={e => e.stopPropagation()}
- />
+ <>
+ {r - x < 150 ? null : {this._titleControlString + ':'} }
+ {
+ this._editingTitle = false;
+ !hideTitle && this.titleBlur();
+ })}
+ onChange={action(e => !hideTitle && (this._accumulatedTitle = e.target.value))}
+ onKeyDown={hideTitle ? emptyFunction : this.titleEntered}
+ onPointerDown={e => e.stopPropagation()}
+ />
+ >
) : (
{hideTitle ? null : (
diff --git a/src/client/views/FieldsDropdown.tsx b/src/client/views/FieldsDropdown.tsx
index 5638d34c6..6a5c2cb4c 100644
--- a/src/client/views/FieldsDropdown.tsx
+++ b/src/client/views/FieldsDropdown.tsx
@@ -61,7 +61,6 @@ export class FieldsDropdown extends ObservableReactComponent
filteredOptions.push(pair[0]));
const options = filteredOptions.sort().map(facet => ({ value: facet, label: facet }));
- console.log(options);
return (
{
}}>
(this._docView = r !== null ? r : undefined))}
Document={this._doc}
PanelWidth={this.lightboxWidth}
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index bd6be2519..c29474fcd 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -34,7 +34,7 @@ export interface MarqueeAnnotatorProps {
annotationLayer: HTMLDivElement;
addDocument: (doc: Doc) => boolean;
getPageFromScroll?: (top: number) => number;
- finishMarquee: (x?: number, y?: number, PointerEvent?: PointerEvent) => void;
+ finishMarquee: (x?: number, y?: number) => void;
anchorMenuClick?: () => undefined | ((anchor: Doc) => void);
anchorMenuCrop?: (anchor: Doc | undefined, addCrop: boolean) => Doc | undefined;
highlightDragSrcColor?: string;
@@ -168,7 +168,6 @@ export class MarqueeAnnotator extends ObservableReactComponent {
+ const movLoc = this.getTransformedScreenPt(pt);
+ this._width = movLoc.x - this._start.x;
+ this._height = movLoc.y - this._start.y;
+ };
+
@action
onSelectMove = (e: PointerEvent) => {
const movLoc = this.getTransformedScreenPt([e.clientX, e.clientY]);
@@ -248,9 +254,12 @@ export class MarqueeAnnotator extends ObservableReactComponent {
e.stopPropagation();
+ this.onEnd(e.clientX, e.clientY);
+ };
+ @action
+ onEnd = (x: number, y: number) => {
const marquees = this.props.marqueeContainer.getElementsByClassName('marqueeAnnotator-dragBox');
const marqueeStyle = (Array.from(marquees).lastElement() as HTMLDivElement)?.style;
if (!this.isEmpty && marqueeStyle) {
@@ -266,9 +275,9 @@ export class MarqueeAnnotator extends ObservableReactComponent extends React.Component
makeObservable(this);
}
componentDidUpdate(prevProps: Readonly): void {
- Object.keys(prevProps).forEach(action(pkey =>
- (prevProps as any)[pkey] !== (this.props as any)[pkey] &&
+ Object.keys(prevProps).filter(pkey => (prevProps as any)[pkey] !== (this.props as any)[pkey]).forEach(action(pkey =>
((this._props as any)[pkey] = (this.props as any)[pkey]))); // prettier-ignore
}
}
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index cbd3ff358..195b1a04c 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -1399,7 +1399,7 @@ export class PropertiesView extends ObservableReactComponent
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 1adb0d9e5..7a15e67e4 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -25,6 +25,7 @@ import { FieldViewProps } from './nodes/FieldView';
import { KeyValueBox } from './nodes/KeyValueBox';
import { PropertiesView } from './PropertiesView';
import './StyleProvider.scss';
+import { CollectionSchemaView } from './collections/collectionSchema/CollectionSchemaView';
export enum StyleProp {
TreeViewIcon = 'treeView_Icon',
@@ -137,14 +138,15 @@ export function DefaultStyleProvider(doc: Opt, props: Opt boolean | undefined;
ScreenToLocalTransform: () => Transform;
+ containerViewPath?: () => DocumentView[];
_timeline: HTMLDivElement | null;
focus: FocusFuncType;
currentTimecode: () => number;
@@ -796,12 +798,15 @@ class StackedTimelineAnchor extends ObservableReactComponent {
+ this._props.mark[DocData].title = ComputedField.MakeFunction(
+ `["${this._props.endTag}"] ? "#" + formatToTime(this["${this._props.startTag}"]) + "-" + formatToTime(this["${this._props.endTag}"]) : "#" + formatToTime(this["${this._props.startTag}"]`
+ );
+ };
// context menu
contextMenuItems = () => {
const resetTitle = {
- script: ScriptField.MakeFunction(
- `this.title = this["${this._props.endTag}"] ? "#" + formatToTime(this["${this._props.startTag}"]) + "-" + formatToTime(this["${this._props.endTag}"]) : "#" + formatToTime(this["${this._props.startTag}"])`
- )!,
+ method: this.resetTitle,
icon: 'folder-plus',
label: 'Reset Title',
};
@@ -826,7 +831,7 @@ class StackedTimelineAnchor extends ObservableReactComponent (anchor.view = r))}
Document={mark}
TemplateDataDocument={undefined}
- containerViewPath={returnEmptyDoclist}
+ containerViewPath={this._props.containerViewPath}
pointerEvents={this.noEvents ? returnNone : undefined}
styleProvider={this._props.styleProvider}
renderDepth={this._props.renderDepth + 1}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index b8c0967c1..6484658e0 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -388,7 +388,7 @@ function normalizeResults(
minWidth: number,
extras: ViewDefBounds[]
): ViewDefResult[] {
- const grpEles = groupNames.map(gn => ({ x: gn.x, y: gn.y, width: gn.width, height: gn.height } as ViewDefBounds));
+ const grpEles = groupNames.map(gn => ({ x: gn.x, y: gn.y, width: gn.width, height: gn.height }) as ViewDefBounds);
const docEles = Array.from(docMap.entries()).map(ele => ele[1]);
const aggBounds = aggregateBounds(
extras.concat(grpEles.concat(docEles.map(de => ({ ...de, type: 'doc', payload: '' })))).filter(e => e.zIndex !== -99),
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 1fd453e96..5495735ea 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -565,7 +565,7 @@ export class CollectionFreeFormView extends CollectionSubView, props: Opt, property: string) => {
let styleProp = this._props.styleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1
if (doc && this.childDocList?.includes(doc))
- switch (property) {
+ switch (property.split(':')[0]) {
case StyleProp.BackgroundColor:
const cluster = NumCast(doc?.layout_cluster);
if (this.Document._freeform_useClusters && doc?.type !== DocumentType.IMG) {
@@ -590,7 +590,7 @@ export class CollectionFreeFormView extends CollectionSubView {
- if (this._hitCluster !== -1) {
+ if (addToSel && this._hitCluster !== -1) {
!addToSel && SelectionManager.DeselectAll();
const eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => (this.Document._freeform_useClusters ? NumCast(cd.layout_cluster) : NumCast(cd.group, -1)) === this._hitCluster);
this.selectDocuments(eles);
@@ -1288,15 +1288,16 @@ export class CollectionFreeFormView extends CollectionSubView this._props.addDocTab(Docs.Create.WebDocument(`https://bing.com/search?q=${str}`, { _width: 400, x, y, _height: 512, _nativeWidth: 850, title: 'bing', data_useCors: true }), OpenWhere.addRight));
+ cm.setDefaultItem('?', (str: string) =>
+ this._props.addDocTab(Docs.Create.WebDocument(`https://wikipedia.org/wiki/${str}`, { _width: 400, x, y, _height: 512, _nativeWidth: 850, title: `wiki:${str}`, data_useCors: true }), OpenWhere.addRight)
+ );
cm.displayMenu(this._downX, this._downY, undefined, true);
e.stopPropagation();
} else if (e.key === 'u' && this._props.ungroup) {
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index 67dc508d5..bda8afa41 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -213,7 +213,7 @@ export class SchemaImageCell extends ObservableReactComponent Cast(doc[Doc.LayoutFieldKey(doc)], ImageField, null)?.url)
.filter(url => url)
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 3fdc9a488..d12639fc7 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -87,8 +87,8 @@ ScriptingGlobals.add(function setHeaderColor(color?: string, checkResult?: boole
});
} else {
Doc.SharingDoc().headingColor = undefined;
- Doc.GetProto(Doc.SharingDoc()).headingColor = color;
- Doc.UserDoc().layout_showTitle = color === 'transparent' ? undefined : StrCast(Doc.UserDoc().layout_showTitle, 'author_date');
+ Doc.GetProto(Doc.SharingDoc()).headingColor = color === 'transparent' ? undefined : color;
+ Doc.UserDoc().layout_showTitle = color === 'transparent' ? undefined : StrCast(Doc.UserDoc().layout_showTitle, 'title');
}
});
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 2800ea200..0d0a7c623 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,4 +1,4 @@
-import { action, makeObservable, observable } from 'mobx';
+import { action, makeObservable, observable, trace } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { OmitKeys, numberRange } from '../../../Utils';
@@ -17,6 +17,7 @@ import { CollectionFreeFormView } from '../collections/collectionFreeForm/Collec
import './CollectionFreeFormDocumentView.scss';
import { DocumentView, DocumentViewProps, OpenWhere } from './DocumentView';
import { FieldViewProps } from './FieldView';
+import { TransitionTimer } from '../../../fields/DocSymbols';
/// Ugh, typescript has no run-time way of iterating through the keys of an interface. so we need
/// manaully keep this list of keys in synch wih the fields of the freeFormProps interface
@@ -91,6 +92,16 @@ export class CollectionFreeFormDocumentView extends DocComponent (this.Document[TransitionTimer] = this.Transition = undefined)),
+ num
+ );
+ }
+ }
+
componentDidUpdate(prevProps: Readonly>) {
super.componentDidUpdate(prevProps);
this.WrapperKeys.forEach(action(keys => ((this as any)[keys.upper] = (this.props as any)[keys.lower])));
@@ -98,14 +109,14 @@ export class CollectionFreeFormDocumentView extends DocComponent this._props.transition; // prettier-ignore
+ DataTransition = () => this.Transition || StrCast(this.Document.dataTransition); // prettier-ignore
RenderCutoffProvider = this.props.RenderCutoffProvider; // needed for type checking
PanelWidth = () => this._props.autoDim ? this._props.PanelWidth?.() : this.Width; // prettier-ignore
PanelHeight = () => this._props.autoDim ? this._props.PanelHeight?.() : this.Height; // prettier-ignore
styleProvider = (doc: Doc | undefined, props: Opt, property: string) => {
if (doc === this.layoutDoc) {
- switch (property) {
+ switch (property.split(':')[0]) {
case StyleProp.Opacity: return this.Opacity; // only change the opacity for this specific document, not its children
case StyleProp.BackgroundColor: return this.BackgroundColor;
case StyleProp.Color: return this.Color;
@@ -224,7 +235,8 @@ export class CollectionFreeFormDocumentView extends DocComponent {
if (this.CollectionFreeFormView.isAnyChildContentActive()) return undefined;
- const isGroup = this.dataDoc.isGroup && (!this.layoutDoc.backgroundColor || this.layoutDoc.backgroundColor === 'transparent');
+ const backColor = this.BackgroundColor;
+ const isGroup = this.dataDoc.isGroup && (!backColor || backColor === 'transparent');
return isGroup ? (this._props.isDocumentActive?.() ? 'group' : this._props.isGroupActive?.() ? 'child' : 'inactive') : this._props.isGroupActive?.() ? 'child' : undefined;
};
render() {
@@ -237,7 +249,7 @@ export class CollectionFreeFormDocumentView extends DocComponent
@@ -251,6 +263,8 @@ export class CollectionFreeFormDocumentView extends DocComponent
)}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 5a326ecb0..e729e2fa2 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -7,7 +7,7 @@ import { OmitKeys, Without, emptyPath } from '../../../Utils';
import { Doc, Opt } from '../../../fields/Doc';
import { AclPrivate, DocData } from '../../../fields/DocSymbols';
import { ScriptField } from '../../../fields/ScriptField';
-import { Cast, StrCast } from '../../../fields/Types';
+import { Cast, DocCast, StrCast } from '../../../fields/Types';
import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
import { InkingStroke } from '../InkingStroke';
import { ObservableReactComponent } from '../ObservableReactComponent';
@@ -128,7 +128,9 @@ export class DocumentContentsView extends ObservableReactComponentawaiting layout
';
if (this._props.layoutFieldKey === 'layout_keyValue') return StrCast(this._props.Document.layout_keyValue, KeyValueBox.LayoutString());
- const layout = Cast(this.layoutDoc[this.layoutDoc === this._props.Document && this._props.layoutFieldKey ? this._props.layoutFieldKey : StrCast(this.layoutDoc.layout_fieldKey, 'layout')], 'string');
+ const tempLayout = DocCast(this.layoutDoc[this.layoutDoc === this._props.Document && this._props.layoutFieldKey ? this._props.layoutFieldKey : StrCast(this.layoutDoc.layout_fieldKey, 'layout')]);
+ const layoutDoc = tempLayout ?? this.layoutDoc;
+ const layout = Cast(layoutDoc[layoutDoc === this._props.Document && this._props.layoutFieldKey ? this._props.layoutFieldKey : StrCast(layoutDoc.layout_fieldKey, 'layout')], 'string');
if (layout === undefined) return this._props.Document.data ? " " : KeyValueBox.LayoutString();
if (typeof layout === 'string') return layout;
return 'Loading layout
';
@@ -154,6 +156,7 @@ export class DocumentContentsView extends ObservableReactComponent string | undefined;
NativeWidth?: () => number;
NativeHeight?: () => number;
- contextMenuItems?: () => { script: ScriptField; filter?: ScriptField; label: string; icon: string }[];
+ contextMenuItems?: () => { script?: ScriptField; method?: () => void; filter?: ScriptField; label: string; icon: string }[];
dragConfig?: (data: DragManager.DocumentDragData) => void;
dragStarting?: () => void;
dragEnding?: () => void;
@@ -560,7 +559,13 @@ export class DocumentViewInternal extends DocComponent
cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ documentView: this, this: this.Document, scriptContext: this._props.scriptContext }), icon: 'sticky-note' })
);
- this._props.contextMenuItems?.().forEach(item => item.label && cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.Document, scriptContext: this._props.scriptContext }), icon: item.icon as IconProp }));
+ this._props
+ .contextMenuItems?.()
+ .forEach(
+ item =>
+ item.label &&
+ cm.addItem({ description: item.label, event: () => (item.method ? item.method() : item.script?.script.run({ this: this.Document, documentView: this, scriptContext: this._props.scriptContext })), icon: item.icon as IconProp })
+ );
if (!this.Document.isFolder) {
const templateDoc = Cast(this.Document[StrCast(this.Document.layout_fieldKey)], Doc, null);
@@ -597,7 +602,7 @@ export class DocumentViewInternal extends DocComponent this.toggleFollowLink(false, false), icon: 'link' });
!Doc.noviceMode && onClicks.push({ description: 'Edit onClick Script', event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.Document, undefined, 'onClick'), 'edit onClick'), icon: 'terminal' });
- cm.addItem({ description: 'OnClick...', noexpand: true, subitems: onClicks, icon: 'mouse-pointer' });
+ !existingOnClick && cm.addItem({ description: 'OnClick...', noexpand: true, subitems: onClicks, icon: 'mouse-pointer' });
} else if (LinkManager.Links(this.Document).length) {
onClicks.push({ description: 'Restore On Click default', event: () => this.noOnClick(), icon: 'link' });
onClicks.push({ description: 'Follow Link on Click', event: () => this.followLinkOnClick(), icon: 'link' });
@@ -810,8 +815,7 @@ export class DocumentViewInternal extends DocComponent Field.toString(targetDoc[field.trim()] as Field))
+ .map(field => Field.toJavascriptString(this.Document[field] as Field))
.join(' \\ ') || '-unset-'
}
display="block"
oneLine={true}
fontSize={(this.titleHeight / 15) * 10}
- GetValue={() => (showTitle.split(';').length !== 1 ? '#' + showTitle : Field.toKeyValueString(this.Document, showTitle.split(';')[0]))}
+ GetValue={() =>
+ showTitle
+ .split(';')
+ .map(field => Field.toKeyValueString(this.Document, field))
+ .join('\\')
+ }
SetValue={undoBatch((input: string) => {
- if (input?.startsWith('#')) {
+ if (input?.startsWith('$')) {
if (this.layoutDoc.layout_showTitle) {
- this.layoutDoc._layout_showTitle = input?.substring(1);
+ this.layoutDoc._layout_showTitle = input?.substring(1) ? input.substring(1) : undefined;
} else if (!this._props.layout_showTitle) {
- Doc.UserDoc().layout_showTitle = input?.substring(1) ?? 'author_date';
+ Doc.UserDoc().layout_showTitle = input?.substring(1) ? input.substring(1) : 'title';
}
- } else if (showTitle && !showTitle.includes('Date') && showTitle !== 'author') {
+ } else if (showTitle && !showTitle.includes(';') && !showTitle.includes('Date') && showTitle !== 'author') {
KeyValueBox.SetField(targetDoc, showTitle, input);
}
return true;
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 5b47dd91d..771856788 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -92,6 +92,7 @@ export interface FieldViewSharedProps {
waitForDoubleClickToClick?: () => 'never' | 'always' | undefined;
defaultDoubleClick?: () => 'default' | 'ignore' | undefined;
pointerEvents?: () => Opt;
+ suppressSetHeight?: boolean;
}
/**
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 251235b93..86e8ed60a 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -9,7 +9,7 @@ import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { ObjectField } from '../../../fields/ObjectField';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
import { DashColor, emptyFunction, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils';
@@ -29,6 +29,12 @@ import { OpenWhere } from './DocumentView';
import { FocusViewOptions, FieldView, FieldViewProps } from './FieldView';
import './ImageBox.scss';
import { PinProps, PresBox } from './trails';
+import { Colors } from 'browndash-components';
+import { listSpec } from '../../../fields/Schema';
+import { List } from '../../../fields/List';
+import { url } from 'inspector';
+import { OverlayView } from '../OverlayView';
+import { Networking } from '../../Network';
@observer
export class ImageBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface {
@@ -134,7 +140,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() impl
if (de.metaKey || targetIsBullseye(e.target as HTMLElement)) {
added = de.complete.docDragData.droppedDocuments.reduce((last: boolean, drop: Doc) => {
this.layoutDoc[this.fieldKey + '_usePath'] = 'alternate:hover';
- return last && Doc.AddDocToList(this.dataDoc, this.fieldKey + '-alternates', drop);
+ return last && Doc.AddDocToList(this.dataDoc, this.fieldKey + '_alternates', drop);
}, true);
} else if (de.altKey || !this.dataDoc[this.fieldKey]) {
const layoutDoc = de.complete.docDragData?.draggedDocuments[0];
@@ -259,7 +265,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() impl
const lower = url.href.toLowerCase();
if (url.protocol === 'data') return url.href;
if (url.href.indexOf(window.location.origin) === -1 && url.href.indexOf('dashblobstore') === -1) return Utils.CorsProxy(url.href);
- if (!/\.(png|jpg|jpeg|gif|webp)$/.test(lower)) return `/assets/unknown-file-icon-hi.png`;
+ if (!/\.(png|jpg|jpeg|gif|webp)$/.test(lower) || lower.endsWith('/assets/unknown-file-icon-hi.png')) return `/assets/unknown-file-icon-hi.png`;
const ext = extname(url.href);
return url.href.replace(ext, (this._error ? '_o' : this._curSuffix) + ext);
@@ -297,7 +303,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() impl
ref={this._overlayIconRef}
onPointerDown={e => setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, e => (this.layoutDoc[`_${this.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : usePath === 'alternate' ? 'alternate:hover' : undefined))}
style={{
- display: (this._props.isContentActive() !== false && DragManager.DocDragData?.canEmbed) || DocListCast(this.dataDoc[this.fieldKey + '-alternates']).length ? 'block' : 'none',
+ display: (this._props.isContentActive() !== false && DragManager.DocDragData?.canEmbed) || this.dataDoc[this.fieldKey + '_alternates'] ? 'block' : 'none',
width: 'min(10%, 25px)',
height: 'min(10%, 25px)',
background: usePath === undefined ? 'white' : usePath === 'alternate' ? 'black' : 'gray',
@@ -311,13 +317,15 @@ export class ImageBox extends ViewBoxAnnotatableComponent() impl
@computed get paths() {
const field = Cast(this.dataDoc[this.fieldKey], ImageField, null); // retrieve the primary image URL that is being rendered from the data doc
- const alts = DocListCast(this.dataDoc[this.fieldKey + '-alternates']); // retrieve alternate documents that may be rendered as alternate images
- const altpaths = alts
- .map(doc => Cast(doc[Doc.LayoutFieldKey(doc)], ImageField, null)?.url)
- .filter(url => url)
- .map(url => this.choosePath(url)); // access the primary layout data of the alternate documents
+ const alts = this.dataDoc[this.fieldKey + '_alternates'] as any as List; // retrieve alternate documents that may be rendered as alternate images
+ const defaultUrl = new URL(Utils.prepend('/assets/unknown-file-icon-hi.png'));
+ const altpaths =
+ alts
+ ?.map(doc => (doc instanceof Doc ? ImageCast(doc[Doc.LayoutFieldKey(doc)])?.url ?? defaultUrl : defaultUrl))
+ .filter(url => url)
+ .map(url => this.choosePath(url)) ?? []; // acc ess the primary layout data of the alternate documents
const paths = field ? [this.choosePath(field.url), ...altpaths] : altpaths;
- return paths.length ? paths : [Utils.CorsProxy('https://cs.brown.edu/~bcz/noImage.png')];
+ return paths.length ? paths : [defaultUrl.href];
}
@observable _error = '';
@@ -326,7 +334,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() impl
@computed get content() {
TraceMobx();
- const backColor = DashColor(this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor));
+ const backColor = DashColor(this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) ?? Colors.WHITE);
const backAlpha = backColor.red() === 0 && backColor.green() === 0 && backColor.blue() === 0 ? backColor.alpha() : 1;
const srcpath = this.layoutDoc.hideImage ? '' : this.paths[0];
const fadepath = this.layoutDoc.hideImage ? '' : this.paths.lastElement();
@@ -370,6 +378,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() impl
}
screenToLocalTransform = () => this.ScreenToLocalBoxXf().translate(0, NumCast(this.layoutDoc._layout_scrollTop) * this.ScreenToLocalBoxXf().Scale);
marqueeDown = (e: React.PointerEvent) => {
+ if (!this.dataDoc[this.fieldKey]) return this.chooseImage();
if (!e.altKey && e.button === 0 && NumCast(this.layoutDoc._freeform_scale, 1) <= NumCast(this.dataDoc.freeform_scaleMin, 1) && this._props.isContentActive() && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
setupMoveUpEvents(
this,
@@ -468,4 +477,28 @@ export class ImageBox extends ViewBoxAnnotatableComponent() impl
);
}
+
+ public chooseImage = () => {
+ const input = document.createElement('input');
+ input.type = 'file';
+ input.multiple = true;
+ input.accept = 'image/*';
+ input.onchange = async _e => {
+ const file = input.files?.[0];
+ if (file) {
+ const disposer = OverlayView.ShowSpinner();
+ const [{ result }] = await Networking.UploadFilesToServer({ file });
+ if (result instanceof Error) {
+ alert('Error uploading files - possibly due to unsupported file types');
+ } else {
+ this.dataDoc[this.fieldKey] = new ImageField(result.accessPaths.agnostic.client);
+ !(result instanceof Error) && DocUtils.assignImageInfo(result, this.dataDoc);
+ }
+ disposer();
+ } else {
+ console.log('No file selected');
+ }
+ };
+ input.click();
+ };
}
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 5394c7dbb..78e4435ce 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -113,7 +113,7 @@ export class KeyValueBox extends ObservableReactComponent {
if (key) target[key] = script.originalScript;
return false;
}
- field === undefined && (field = res.result);
+ field === undefined && (field = res.result instanceof Array ? new List(res.result) : res.result);
}
}
if (!key) return false;
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index be20b5934..74e78c671 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -41,7 +41,7 @@ export class LabelBox extends ViewBoxBaseComponent() {
}
@computed get Title() {
- return Field.toString(this.dataDoc[this.fieldKey] as Field);
+ return Field.toString(this.dataDoc[this.fieldKey] as Field) || StrCast(this.Document.title);
}
protected createDropTarget = (ele: HTMLDivElement) => {
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 6e4d0e92a..0809e2ad6 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -2,12 +2,13 @@ import { action, computed, IReactionDisposer, makeObservable, observable, reacti
import { observer } from 'mobx-react';
import * as React from 'react';
import Xarrow from 'react-xarrows';
+import { FieldResult } from '../../../fields/Doc';
import { DocCss, DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { DocCast, NumCast, StrCast } from '../../../fields/Types';
+import { TraceMobx } from '../../../fields/util';
import { DashColor, emptyFunction, lightOrDark, returnFalse } from '../../../Utils';
import { DocumentManager } from '../../util/DocumentManager';
-import { LinkManager } from '../../util/LinkManager';
import { SnappingManager } from '../../util/SnappingManager';
import { ViewBoxBaseComponent } from '../DocComponent';
import { EditableView } from '../EditableView';
@@ -22,8 +23,8 @@ export class LinkBox extends ViewBoxBaseComponent() {
public static LayoutString(fieldKey: string = 'link') {
return FieldView.LayoutString(LinkBox, fieldKey);
}
- disposer: IReactionDisposer | undefined;
- @observable _forceAnimate = 0; // forces xArrow to animate when a transition animation is detected on something that affects an anchor
+ _disposer: IReactionDisposer | undefined;
+ @observable _forceAnimate: number = 0; // forces xArrow to animate when a transition animation is detected on something that affects an anchor
@observable _hide = false; // don't render if anchor is not visible since that breaks xAnchor
constructor(props: FieldViewProps) {
@@ -39,11 +40,11 @@ export class LinkBox extends ViewBoxBaseComponent() {
return DocumentManager.Instance.getDocumentView(anchor, this.DocumentView?.().containerViewPath?.().lastElement());
};
componentWillUnmount() {
- this.disposer?.();
+ this._disposer?.();
}
componentDidMount() {
this._props.setContentViewBox?.(this);
- this.disposer = reaction(
+ this._disposer = reaction(
() => ({ drag: SnappingManager.IsDragging }),
({ drag }) => {
!LightboxView.Contains(this.DocumentView?.()) &&
@@ -64,12 +65,13 @@ export class LinkBox extends ViewBoxBaseComponent() {
}
})
);
- },
- { fireImmediately: true }
+ }
);
}
render() {
+ TraceMobx();
+
if (this._hide) return null;
const a = this.anchor1;
const b = this.anchor2;
@@ -92,18 +94,34 @@ export class LinkBox extends ViewBoxBaseComponent() {
const at = a.getBounds?.transition; // these force re-render when a or b change size and at the end of an animated transition
const bt = b.getBounds?.transition; // inquring getBounds() also causes text anchors to update whether or not they reflow (any size change triggers an invalidation)
+ var foundParent = false;
+ const getAnchor = (field: FieldResult): Element[] => {
+ const doc = DocCast(field);
+ const ele = document.getElementById(doc[Id]);
+ if (ele?.getBoundingClientRect().width) return [ele];
+ const eles = Array.from(document.getElementsByClassName(doc[Id])).filter(ele => ele?.getBoundingClientRect().width);
+ const annoOn = DocCast(doc.annotationOn);
+ if (eles.length || !annoOn) return eles;
+ const pareles = getAnchor(annoOn);
+ foundParent = pareles.length ? true : false;
+ return pareles;
+ };
// if there's an element in the DOM with a classname containing a link anchor's id (eg a hypertext ),
// then that DOM element is a hyperlink source for the current anchor and we want to place our link box at it's top right
// otherwise, we just use the computed nearest point on the document boundary to the target Document
- const targetAhyperlink = Array.from(document.getElementsByClassName(DocCast(this.dataDoc.link_anchor_1)[Id])).lastElement();
- const targetBhyperlink = Array.from(document.getElementsByClassName(DocCast(this.dataDoc.link_anchor_2)[Id])).lastElement();
+ const targetAhyperlinks = getAnchor(this.dataDoc.link_anchor_1);
+ const targetBhyperlinks = getAnchor(this.dataDoc.link_anchor_2);
- const aid = targetAhyperlink?.id || a.Document[Id];
- const bid = targetBhyperlink?.id || b.Document[Id];
- if (!document.getElementById(aid) || !document.getElementById(bid)) {
+ const container = this.DocumentView?.().containerViewPath?.().lastElement().ContentDiv;
+ const aid = targetAhyperlinks?.find(alink => container?.contains(alink))?.id ?? targetAhyperlinks?.lastElement()?.id;
+ const bid = targetBhyperlinks?.find(blink => container?.contains(blink))?.id ?? targetBhyperlinks?.lastElement()?.id;
+ if (!aid || !bid) {
setTimeout(action(() => (this._forceAnimate = this._forceAnimate + 0.01)));
return null;
}
+ if (foundParent) {
+ setTimeout(action(() => (this._forceAnimate = this._forceAnimate + 1)));
+ }
if (at || bt) setTimeout(action(() => (this._forceAnimate = this._forceAnimate + 0.01))); // this forces an update during a transition animation
const highlight = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting);
@@ -192,6 +210,11 @@ export class LinkBox extends ViewBoxBaseComponent() {
>
);
}
+
+ setTimeout(
+ action(() => (this._forceAnimate = this._forceAnimate + 1)),
+ 2
+ );
return (
() impl
Doc.SetNativeHeight(imageSnapshot[DocData], Doc.NativeHeight(this.layoutDoc));
this._props.addDocument?.(imageSnapshot);
const link = DocUtils.MakeLink(imageSnapshot, this.getAnchor(true), { link_relationship: 'video snapshot' });
- link && (DocCast(link.link_anchor_2)[DocData].timecodeToHide = NumCast(DocCast(link.link_anchor_2).timecodeToShow) + 3);
+ // link && (DocCast(link.link_anchor_2)[DocData].timecodeToHide = NumCast(DocCast(link.link_anchor_2).timecodeToShow) + 3); // do we need to set an end time? should default to +0.1
setTimeout(() => downX !== undefined && downY !== undefined && DocumentManager.Instance.getFirstDocumentView(imageSnapshot)?.startDragging(downX, downY, dropActionType.move, true));
};
@@ -373,7 +373,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent() impl
getView = (doc: Doc, options: FocusViewOptions) => {
if (this._stackedTimeline?.makeDocUnfiltered(doc)) {
if (this.heightPercent === 100) {
- this.layoutDoc._layout_timelineHeightPercent = VideoBox.heightPercent;
+ // do we want to always open up the timeline when followin a link? kind of clunky visually
+ //this.layoutDoc._layout_timelineHeightPercent = VideoBox.heightPercent;
options.didMove = true;
}
return this._stackedTimeline.getView(doc, options);
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index c9340edc0..f4d5eef05 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,6 +1,6 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { htmlToText } from 'html-to-text';
-import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction, trace } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import * as WebRequest from 'web-request';
@@ -340,8 +340,18 @@ export class WebBox extends ViewBoxAnnotatableComponent() implem
_textAnnotationCreator: (() => ObservableMap) | undefined;
savedAnnotationsCreator: () => ObservableMap = () => this._textAnnotationCreator?.() || this._savedAnnotations;
+ @action
+ iframeMove = (e: PointerEvent) => {
+ const theclick = this.props
+ .ScreenToLocalTransform()
+ .inverse()
+ .transformPoint(e.clientX, e.clientY - NumCast(this.layoutDoc.layout_scrollTop));
+ this._marqueeref.current?.onMove(theclick);
+ };
@action
iframeUp = (e: PointerEvent) => {
+ this._iframe?.contentDocument?.removeEventListener('pointermove', this.iframeMove);
+ this.marqueeing = undefined;
this._getAnchor = AnchorMenu.Instance?.GetAnchor; // need to save AnchorMenu's getAnchor since a subsequent selection on another doc will overwrite this value
this._textAnnotationCreator = undefined;
this.DocumentView?.()?.cleanupPointerEvents(); // pointerup events aren't generated on containing document view, so we have to invoke it here.
@@ -358,6 +368,29 @@ export class WebBox extends ViewBoxAnnotatableComponent() implem
GPTPopup.Instance.setSidebarId(`${this._props.fieldKey}_${this._urlHash ? this._urlHash + '_' : ''}sidebar`);
GPTPopup.Instance.addDoc = this.sidebarAddDocument;
}
+ } else {
+ const theclick = this.props
+ .ScreenToLocalTransform()
+ .inverse()
+ .transformPoint(e.clientX, e.clientY - NumCast(this.layoutDoc.layout_scrollTop));
+ if (!this._marqueeref.current?.isEmpty) this._marqueeref.current?.onEnd(theclick[0], theclick[1]);
+ else {
+ if (!(e.target as any)?.tagName?.includes('INPUT')) this.finishMarquee(theclick[0], theclick[1]);
+ this._getAnchor = AnchorMenu.Instance?.GetAnchor;
+ this.marqueeing = undefined;
+ }
+
+ ContextMenu.Instance.closeMenu();
+ ContextMenu.Instance.setIgnoreEvents(false);
+ if (e?.button === 2 || e?.altKey) {
+ e?.preventDefault();
+ e?.stopPropagation();
+ setTimeout(() => {
+ // if menu comes up right away, the down event can still be active causing a menu item to be selected
+ this.specificContextMenu(undefined as any);
+ this.DocumentView?.().onContextMenu(undefined, theclick[0], theclick[1]);
+ });
+ }
}
};
@action
@@ -400,6 +433,12 @@ export class WebBox extends ViewBoxAnnotatableComponent() implem
};
@action
iframeDown = (e: PointerEvent) => {
+ this._textAnnotationCreator = undefined;
+ const sel = this._url ? this._iframe?.contentDocument?.getSelection() : window.document.getSelection();
+ if (sel?.empty)
+ sel.empty(); // Chrome
+ else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox
+
this._props.select(false);
const theclick = this.props
.ScreenToLocalTransform()
@@ -409,6 +448,8 @@ export class WebBox extends ViewBoxAnnotatableComponent() implem
const word = getWordAtPoint(e.target, e.clientX, e.clientY);
if (!word && !(e.target as any)?.className?.includes('rangeslider') && !(e.target as any)?.onclick && !(e.target as any)?.parentNode?.onclick) {
this.marqueeing = theclick;
+ this._marqueeref.current?.onInitiateSelection(this.marqueeing);
+ this._iframe?.contentDocument?.addEventListener('pointermove', this.iframeMove);
e.preventDefault();
}
};
@@ -739,28 +780,10 @@ export class WebBox extends ViewBoxAnnotatableComponent() implem
this.marqueeing = undefined;
}
};
- @action finishMarquee = (x?: number, y?: number, e?: PointerEvent) => {
+ @action finishMarquee = (x?: number, y?: number) => {
this._getAnchor = AnchorMenu.Instance?.GetAnchor;
this.marqueeing = undefined;
- this._textAnnotationCreator = undefined;
- const sel = this._url ? this._iframe?.contentDocument?.getSelection() : window.document.getSelection();
- if (sel?.empty)
- sel.empty(); // Chrome
- else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox
this._setPreviewCursor?.(x ?? 0, y ?? 0, false, !this._marqueeref.current?.isEmpty, this.Document);
- if (x !== undefined && y !== undefined) {
- ContextMenu.Instance.closeMenu();
- ContextMenu.Instance.setIgnoreEvents(false);
- if (e?.button === 2 || e?.altKey) {
- e?.preventDefault();
- e?.stopPropagation();
- setTimeout(() => {
- // if menu comes up right away, the down event can still be active causing a menu item to be selected
- this.specificContextMenu(undefined as any);
- this.DocumentView?.().onContextMenu(undefined, x, y);
- });
- }
- }
};
@observable lighttext = false;
@@ -992,6 +1015,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() implem
}
childPointerEvents = () => (this._props.isContentActive() ? 'all' : undefined);
@computed get webpage() {
+ TraceMobx();
const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as any);
const scale = previewScale * (this._props.NativeDimScaling?.() || 1);
@@ -1071,6 +1095,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() implem
: 'none';
annotationPointerEvents = () => (this._props.isContentActive() && (SnappingManager.IsDragging || Doc.ActiveTool !== InkTool.None) ? 'all' : 'none');
render() {
+ TraceMobx();
const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as any);
const scale = previewScale * (this._props.NativeDimScaling?.() || 1);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 793595694..eb7293054 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -450,16 +450,23 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent {
const newAutoLinks = new Set();
- const oldAutoLinks = LinkManager.Links(this.Document).filter(link => link.link_relationship === LinkManager.AutoKeywords);
+ const oldAutoLinks = LinkManager.Links(this.Document).filter(
+ link =>
+ ((!Doc.isTemplateForField(this.Document) &&
+ (!Doc.isTemplateForField(DocCast(link.link_anchor_1)) || !Doc.AreProtosEqual(DocCast(link.link_anchor_1), this.Document)) &&
+ (!Doc.isTemplateForField(DocCast(link.link_anchor_2)) || !Doc.AreProtosEqual(DocCast(link.link_anchor_2), this.Document))) ||
+ (Doc.isTemplateForField(this.Document) && (link.link_anchor_1 === this.Document || link.link_anchor_2 === this.Document))) &&
+ link.link_relationship === LinkManager.AutoKeywords
+ ); // prettier-ignore
if (this._editorView?.state.doc.textContent) {
- const isNodeSel = this._editorView.state.selection instanceof NodeSelection;
const f = this._editorView.state.selection.from;
+
const t = this._editorView.state.selection.to;
var tr = this._editorView.state.tr as any;
const autoAnch = this._editorView.state.schema.marks.autoLinkAnchor;
tr = tr.removeMark(0, tr.doc.content.size, autoAnch);
Doc.MyPublishedDocs.filter(term => term.title).forEach(term => (tr = this.hyperlinkTerm(tr, term, newAutoLinks)));
- tr = tr.setSelection(isNodeSel && false ? new NodeSelection(tr.doc.resolve(f)) : new TextSelection(tr.doc.resolve(f), tr.doc.resolve(t)));
+ tr = tr.setSelection(new TextSelection(tr.doc.resolve(f), tr.doc.resolve(t)));
this._editorView?.dispatch(tr);
}
oldAutoLinks.filter(oldLink => !newAutoLinks.has(oldLink) && oldLink.link_anchor_2 !== this.Document).forEach(LinkManager.Instance.deleteLink);
@@ -624,7 +631,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent p + toHgt(child), margins);
const scrollHeight = this.ProseRef && proseHeight;
- if (this._props.setHeight && scrollHeight && !this._props.dontRegisterView) {
+ if (this._props.setHeight && !this._props.suppressSetHeight && scrollHeight && !this._props.dontRegisterView) {
// if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
const setScrollHeight = () => (this.dataDoc[this.fieldKey + '_scrollHeight'] = scrollHeight);
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index e34144fae..ae6da8fb0 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -703,7 +703,7 @@ export class PresBox extends ViewBoxBaseComponent() {
if (pinProps.pinData.temporal) {
pinDoc.config_clipStart = targetDoc._layout_currentTimecode;
const duration = NumCast(pinDoc[`${Doc.LayoutFieldKey(pinDoc)}_duration`], NumCast(targetDoc.config_clipStart) + 0.1);
- pinDoc.config_clipEnd = NumCast(targetDoc.clipEnd, duration);
+ pinDoc.config_clipEnd = NumCast(pinDoc.config_clipStart) + NumCast(targetDoc.clipEnd, duration);
}
}
if (pinProps?.pinViewport) {
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 246828709..1bd49cf3f 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -45,18 +45,23 @@ export namespace Field {
export function toKeyValueString(doc: Doc, key: string, showComputedValue?: boolean): string {
const onDelegate = !Doc.IsDataProto(doc) && Object.keys(doc).includes(key.replace(/^_/, ''));
const field = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
- return !Field.IsField(field)
- ? key.startsWith('_')
- ? '='
- : ''
- : (onDelegate ? '=' : '') +
- (field instanceof ComputedField && showComputedValue
- ? field._lastComputedResult
- : field instanceof ComputedField
- ? `:=${field.script.originalScript.replace(/dashCallChat\(_setCacheResult_, this, `(.*)`\)/, '(($1))')}`
- : field instanceof ScriptField
- ? `$=${field.script.originalScript}`
- : Field.toScriptString(field));
+ const valFunc = (field: Field): string => {
+ const res =
+ field instanceof ComputedField && showComputedValue
+ ? field._lastComputedResult
+ : field instanceof ComputedField
+ ? `:=${field.script.originalScript.replace(/dashCallChat\(_setCacheResult_, this, `(.*)`\)/, '(($1))')}`
+ : field instanceof ScriptField
+ ? `$=${field.script.originalScript}`
+ : Field.toScriptString(field);
+ const resStr = (res + '').replace(/^`(.*)`$/, '$1');
+ return typeof field === 'string' && (+resStr).toString() !== resStr && !Array.from('+-*/.').some(k => Array.from(resStr).includes(k))
+ ? resStr
+ : (res + '') // adjust the key value string to be easier to enter: represent any initial list as an array with []
+ .trim()
+ .replace(/^new List\((.*)\)$/, '$1');
+ };
+ return !Field.IsField(field) ? (key.startsWith('_') ? '=' : '') : (onDelegate ? '=' : '') + valFunc(field);
}
export function toScriptString(field: Field) {
switch (typeof field) {
diff --git a/src/fields/PresField.ts b/src/fields/PresField.ts
deleted file mode 100644
index f236a04fd..000000000
--- a/src/fields/PresField.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-//insert code here
-import { ObjectField } from "./ObjectField";
-
-export abstract class PresField extends ObjectField {
-
-}
\ No newline at end of file
diff --git a/src/fields/RichTextField.ts b/src/fields/RichTextField.ts
index f5801de73..d0a149506 100644
--- a/src/fields/RichTextField.ts
+++ b/src/fields/RichTextField.ts
@@ -36,11 +36,4 @@ export class RichTextField extends ObjectField {
[ToString]() {
return this.Text;
}
-
- public static DashField(fieldKey: string) {
- return new RichTextField(
- `{"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":null,"color":null,"id":null,"indent":null,"inset":null,"lineSpacing":null,"paddingBottom":null,"paddingTop":null},"content":[{"type":"dashField","attrs":{"fieldKey":"${fieldKey}","docId":""}}]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}`,
- ''
- );
- }
}
--
cgit v1.2.3-70-g09d2
From 52bd492747cf169df7bcdecdbdbb353d45b19734 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Thu, 28 Mar 2024 00:05:05 -0400
Subject: fixed tabbing between items in nested dashFieldViews
---
src/client/views/EditableView.tsx | 1 +
.../views/collections/collectionSchema/CollectionSchemaView.scss | 9 +++++++++
.../views/collections/collectionSchema/SchemaTableCell.tsx | 8 ++++----
src/fields/Doc.ts | 3 +++
src/fields/RichTextField.ts | 7 +++++++
5 files changed, 24 insertions(+), 4 deletions(-)
(limited to 'src/client/views/collections/collectionSchema')
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 44c8e4e1f..85e893e19 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -121,6 +121,7 @@ export class EditableView extends ObservableReactComponent {
@action
onKeyDown = (e: React.KeyboardEvent) => {
+ if (e.nativeEvent.defaultPrevented) return; // hack .. DashFieldView grabs native events, but react ignores stoppedPropagation and preventDefault, so we need to check it here
switch (e.key) {
case 'Tab':
e.stopPropagation();
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
index ac0bd2378..9768877ff 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
@@ -226,6 +226,15 @@
align-items: center;
}
+.schemaRTFCell {
+ display: flex;
+ width: 100%;
+ height: 100%;
+ position: relative;
+ min-width: 10px;
+ min-height: 10px;
+}
+
.schema-row {
cursor: grab;
justify-content: flex-end;
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index bda8afa41..ab05a62d3 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -17,6 +17,7 @@ import { FInfo, FInfoFieldType } from '../../../documents/Documents';
import { DocFocusOrOpen } from '../../../util/DocumentManager';
import { dropActionType } from '../../../util/DragManager';
import { SettingsManager } from '../../../util/SettingsManager';
+import { SnappingManager } from '../../../util/SnappingManager';
import { Transform } from '../../../util/Transform';
import { undoBatch, undoable } from '../../../util/UndoManager';
import { EditableView } from '../../EditableView';
@@ -29,7 +30,6 @@ import { KeyValueBox } from '../../nodes/KeyValueBox';
import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
import { ColumnType, FInfotoColType } from './CollectionSchemaView';
import './CollectionSchemaView.scss';
-import { SnappingManager } from '../../../util/SnappingManager';
export interface SchemaTableCellProps {
Document: Doc;
@@ -128,7 +128,7 @@ export class SchemaTableCell extends ObservableReactComponent
this._props.autoFocus && r?.setIsFocused(true)}
+ ref={r => this.selected && this._props.autoFocus && r?.setIsFocused(true)}
oneLine={this._props.oneLine}
allowCRs={this._props.allowCRs}
contents={undefined}
@@ -141,7 +141,7 @@ export class SchemaTableCell extends ObservableReactComponent
+
{this.selected ? this._props.finishEdit?.()} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
);
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 1bd49cf3f..bdf600475 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1713,3 +1713,6 @@ ScriptingGlobals.add(function setDocRangeFilter(container: Doc, key: string, ran
ScriptingGlobals.add(function toJavascriptString(str: string) {
return Field.toJavascriptString(str as Field);
});
+ScriptingGlobals.add(function RtfField() {
+ return RichTextField.RTFfield();
+});
diff --git a/src/fields/RichTextField.ts b/src/fields/RichTextField.ts
index d0a149506..3f13f7e6d 100644
--- a/src/fields/RichTextField.ts
+++ b/src/fields/RichTextField.ts
@@ -36,4 +36,11 @@ export class RichTextField extends ObjectField {
[ToString]() {
return this.Text;
}
+
+ public static RTFfield() {
+ return new RichTextField(
+ `{"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":null,"color":null,"id":null,"indent":null,"inset":null,"lineSpacing":null,"paddingBottom":null,"paddingTop":null},"content":[]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}`,
+ ''
+ );
+ }
}
--
cgit v1.2.3-70-g09d2
From a9baa52c557faaa82fd3f696f0d603dd10b982a8 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Sat, 30 Mar 2024 02:18:07 -0400
Subject: updated mermaids template. updated paintFunc to also render the
underlying code text so that the paintFunc will update if dashFields in the
code change. fixed schema views to render templates properly in preview.
fixed text to only modify the data doc. changed setPixels in imageBox to not
consider scaling of outer containers.
---
src/client/util/CurrentUserUtils.ts | 4 ++--
src/client/views/StyleProvider.tsx | 2 +-
.../collectionFreeForm/CollectionFreeFormView.tsx | 6 ++++--
.../views/collections/collectionSchema/SchemaTableCell.tsx | 6 +++---
src/client/views/nodes/ImageBox.tsx | 3 +--
src/client/views/nodes/formattedText/FormattedTextBox.tsx | 12 ++++++++----
6 files changed, 19 insertions(+), 14 deletions(-)
(limited to 'src/client/views/collections/collectionSchema')
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 3855bdeb6..dbf9641b6 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -321,9 +321,9 @@ export class CurrentUserUtils {
{type:"text",text:" "},
{type:"text",text:"Minerals in my tap water"},
{type:"text",text:"\n \"Calcium\" : "},
- {type:"dashField",attrs:{fieldKey:"calcium",docId:"",hideKey:false,hideValue:false,editable:true}},
+ {type:"dashField",attrs:{fieldKey:"calcium",docId:"",hideKey:true,hideValue:false,editable:true}},
{type:"text",text:"\n \"Potassium\" : "},
- {type:"dashField",attrs:{fieldKey:"pot",docId:"",hideKey:false,hideValue:false,editable:true}},
+ {type:"dashField",attrs:{fieldKey:"pot",docId:"",hideKey:true,hideValue:false,editable:true}},
{type:"text",text:"\n \"Magnesium\" : 10.01"}
]}
]},
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 8073d0842..c8b0c0560 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -139,7 +139,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt
- {this.paintFunc ? null : this._lightboxDoc ? (
+ {this.paintFunc ? (
+ // need this so that any live dashfieldviews will update the underlying text that the code eval reads
+ ) : this._lightboxDoc ? (
Field.toKeyValueString(this._props.Document, this._props.fieldKey, SnappingManager.MetaKey)}
+ GetValue={() => Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey)}
SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => {
if (shiftDown && enterKey) {
this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value);
this._props.finishEdit?.();
return true;
}
- const ret = KeyValueBox.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(this._props.Document) ? true : undefined);
+ const ret = KeyValueBox.SetField(fieldProps.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(fieldProps.Document) ? true : undefined);
this._props.finishEdit?.();
return ret;
}, 'edit schema cell')}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 86e8ed60a..469869e21 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -165,8 +165,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() impl
@undoBatch
setNativeSize = action(() => {
- const scaling = (this.DocumentView?.().screenToViewTransform().Scale || 1) / NumCast(this.layoutDoc._freeform_scale, 1);
- const nscale = NumCast(this._props.PanelWidth()) / scaling;
+ const nscale = NumCast(this._props.PanelWidth()) * NumCast(this.layoutDoc._freeform_scale, 1);
const nw = nscale / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']);
this.dataDoc[this.fieldKey + '_nativeHeight'] = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']) * nw;
this.dataDoc[this.fieldKey + '_nativeWidth'] = NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']) * nw;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 3b583771a..b815342e3 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -326,10 +326,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent {
if (node.type === this._editorView?.state.schema.nodes.dashField) {
- const refDoc = !node.attrs.docId ? this.Document : (DocServer.GetCachedRefField(node.attrs.docId as string) as Doc);
+ const refDoc = !node.attrs.docId ? DocCast(this.Document.rootDocument, this.Document) : (DocServer.GetCachedRefField(node.attrs.docId as string) as Doc);
const fieldKey = StrCast(node.attrs.fieldKey);
return (
- (node.attrs.hideKey ? '' : '"' + fieldKey + '"' + ':') + //
+ (node.attrs.hideKey ? '' : fieldKey + ':') + //
(node.attrs.hideValue ? '' : Field.toJavascriptString(refDoc[fieldKey] as Field))
);
}
@@ -346,7 +346,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent {
if (this._editorView && (this._editorView as any).docView) {
const state = this._editorView.state;
- const dataDoc = Doc.IsDelegateField(DocCast(this.layoutDoc.proto), this.fieldKey) ? DocCast(this.layoutDoc.proto) : this.dataDoc;
+ const dataDoc = this.dataDoc;
const newText = state.doc.textBetween(0, state.doc.content.size, ' \n', this.leafText);
const newJson = JSON.stringify(state.toJSON());
const prevData = Cast(this.layoutDoc[this.fieldKey], RichTextField, null); // the actual text in the text box
@@ -1608,7 +1608,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent
Date: Sat, 30 Mar 2024 10:14:19 -0400
Subject: cleanup of import orderings.
---
src/client/util/CaptureManager.tsx | 2 +-
src/client/views/DocumentDecorations.tsx | 3 +-
src/client/views/GlobalKeyHandler.ts | 8 +-
src/client/views/LightboxView.tsx | 2 +-
src/client/views/PropertiesView.tsx | 3 +-
src/client/views/collections/CollectionMenu.tsx | 12 +-
.../views/collections/CollectionNoteTakingView.tsx | 7 +-
src/client/views/collections/TabDocView.tsx | 2 +-
.../collectionFreeForm/CollectionFreeFormView.tsx | 4 +-
.../collectionSchema/CollectionSchemaView.tsx | 14 +-
.../views/newlightbox/Header/LightboxHeader.tsx | 108 ++++----
.../RecommendationList/RecommendationList.tsx | 295 +++++++++++----------
src/client/views/nodes/DocumentView.tsx | 3 +-
src/client/views/nodes/EquationBox.tsx | 2 +-
src/client/views/nodes/LinkBox.tsx | 2 +-
src/client/views/nodes/WebBox.tsx | 4 +-
src/client/views/nodes/trails/PresBox.tsx | 4 +-
src/client/views/topbar/TopBar.tsx | 6 +-
18 files changed, 253 insertions(+), 228 deletions(-)
(limited to 'src/client/views/collections/collectionSchema')
diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx
index 2e13aff2f..8451357ef 100644
--- a/src/client/util/CaptureManager.tsx
+++ b/src/client/util/CaptureManager.tsx
@@ -2,9 +2,9 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { addStyleSheet } from '../../Utils';
import { Doc } from '../../fields/Doc';
import { DocCast, StrCast } from '../../fields/Types';
-import { addStyleSheet } from '../../Utils';
import { LightboxView } from '../views/LightboxView';
import { MainViewModal } from '../views/MainViewModal';
import './CaptureManager.scss';
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 4d9b93896..6698cd5bc 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -10,7 +10,6 @@ import { DateField } from '../../fields/DateField';
import { Doc, DocListCast, Field, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc';
import { AclAdmin, AclAugment, AclEdit, DocData } from '../../fields/DocSymbols';
import { InkField } from '../../fields/InkField';
-import { RichTextField } from '../../fields/RichTextField';
import { ScriptField } from '../../fields/ScriptField';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
import { GetEffectiveAcl } from '../../fields/util';
@@ -33,8 +32,8 @@ import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { Colors } from './global/globalEnums';
import { DocumentView, OpenWhereMod } from './nodes/DocumentView';
import { ImageBox } from './nodes/ImageBox';
-import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import { KeyValueBox } from './nodes/KeyValueBox';
+import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
interface DocumentDecorationsProps {
PanelWidth: number;
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 667d8dbb0..2f64ea28c 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -13,18 +13,18 @@ import { SettingsManager } from '../util/SettingsManager';
import { SharingManager } from '../util/SharingManager';
import { SnappingManager } from '../util/SnappingManager';
import { UndoManager } from '../util/UndoManager';
-import { CollectionDockingView } from './collections/CollectionDockingView';
-import { CollectionFreeFormView } from './collections/collectionFreeForm';
-import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
import { ContextMenu } from './ContextMenu';
import { DocumentDecorations } from './DocumentDecorations';
import { InkStrokeProperties } from './InkStrokeProperties';
import { LightboxView } from './LightboxView';
import { MainView } from './MainView';
+import { CollectionDockingView } from './collections/CollectionDockingView';
+import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
+import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { DocumentLinksButton } from './nodes/DocumentLinksButton';
import { OpenWhereMod } from './nodes/DocumentView';
-import { AnchorMenu } from './pdf/AnchorMenu';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
+import { AnchorMenu } from './pdf/AnchorMenu';
const modifiers = ['control', 'meta', 'shift', 'alt'];
type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo;
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 3d77ee901..ef4b5b4ca 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -19,9 +19,9 @@ import { Transform } from '../util/Transform';
import { GestureOverlay } from './GestureOverlay';
import './LightboxView.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
+import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionStackedTimeline } from './collections/CollectionStackedTimeline';
-import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider';
import { TabDocView } from './collections/TabDocView';
import { DocumentView, OpenWhere, OpenWhereMod } from './nodes/DocumentView';
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index dc814bb16..ae29382c1 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -10,7 +10,7 @@ import * as React from 'react';
import { ColorResult, SketchPicker } from 'react-color';
import * as Icons from 'react-icons/bs'; //{BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs"
import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils';
-import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc';
+import { Doc, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc';
import { AclAdmin, DocAcl, DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { InkField } from '../../fields/InkField';
@@ -41,7 +41,6 @@ import { DocumentView, OpenWhere } from './nodes/DocumentView';
import { StyleProviderFuncType } from './nodes/FieldView';
import { KeyValueBox } from './nodes/KeyValueBox';
import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails';
-import { LinkBox } from './nodes/LinkBox';
const _global = (window /* browser */ || global) /* node */ as any;
interface PropertiesViewProps {
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 8729ef549..4f25f69ef 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -1,15 +1,16 @@
-import * as React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { Toggle, ToggleType, Type } from 'browndash-components';
-import { action, computed, Lambda, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { Lambda, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
+import * as React from 'react';
+import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../../Utils';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { DocData } from '../../../fields/DocSymbols';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
import { RichTextField } from '../../../fields/RichTextField';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../../Utils';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
import { DragManager, dropActionType } from '../../util/DragManager';
import { SelectionManager } from '../../util/SelectionManager';
@@ -19,11 +20,10 @@ import { undoBatch } from '../../util/UndoManager';
import { AntimodeMenu } from '../AntimodeMenu';
import { EditableView } from '../EditableView';
import { MainView } from '../MainView';
-import { DocumentView, DocumentViewInternal, returnEmptyDocViewList } from '../nodes/DocumentView';
import { DefaultStyleProvider } from '../StyleProvider';
-import { CollectionLinearView } from './collectionLinear';
+import { DocumentView, DocumentViewInternal, returnEmptyDocViewList } from '../nodes/DocumentView';
import './CollectionMenu.scss';
-import { DocData } from '../../../fields/DocSymbols';
+import { CollectionLinearView } from './collectionLinear';
interface CollectionMenuProps {
panelHeight: () => number;
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 6318620e0..5b91216cb 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -1,4 +1,4 @@
-import { action, computed, IReactionDisposer, makeObservable, observable, observe, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, Field, Opt } from '../../../fields/Doc';
@@ -9,7 +9,7 @@ import { listSpec } from '../../../fields/Schema';
import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { DivHeight, emptyFunction, returnFalse, returnZero, smoothScroll, Utils } from '../../../Utils';
+import { DivHeight, emptyFunction, returnZero, smoothScroll, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DragManager, dropActionType } from '../../util/DragManager';
import { SnappingManager } from '../../util/SnappingManager';
@@ -19,14 +19,13 @@ import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { LightboxView } from '../LightboxView';
import { DocumentView } from '../nodes/DocumentView';
-import { FocusViewOptions, FieldViewProps } from '../nodes/FieldView';
+import { FieldViewProps, FocusViewOptions } from '../nodes/FieldView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { StyleProp } from '../StyleProvider';
import './CollectionNoteTakingView.scss';
import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn';
import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider';
import { CollectionSubView } from './CollectionSubView';
-import { JsxElement } from 'typescript';
const _global = (window /* browser */ || global) /* node */ as any;
/**
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 699ec3b95..3ff58c326 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -30,7 +30,7 @@ import { ObservableReactComponent } from '../ObservableReactComponent';
import { DefaultStyleProvider, StyleProp } from '../StyleProvider';
import { Colors } from '../global/globalEnums';
import { DocumentView, OpenWhere, OpenWhereMod, returnEmptyDocViewList } from '../nodes/DocumentView';
-import { FocusViewOptions, FieldViewProps } from '../nodes/FieldView';
+import { FieldViewProps, FocusViewOptions } from '../nodes/FieldView';
import { KeyValueBox } from '../nodes/KeyValueBox';
import { DashFieldView } from '../nodes/formattedText/DashFieldView';
import { PinProps, PresBox, PresMovement } from '../nodes/trails';
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 1b562939b..d435173f3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,6 +1,6 @@
import { Bezier } from 'bezier-js';
import { Colors } from 'browndash-components';
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction, trace } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
import * as React from 'react';
@@ -17,7 +17,7 @@ import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../
import { ImageField } from '../../../../fields/URLField';
import { TraceMobx } from '../../../../fields/util';
import { GestureUtils } from '../../../../pen-gestures/GestureUtils';
-import { aggregateBounds, DashColor, emptyFunction, intersectRect, lightOrDark, numberValue, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils';
+import { aggregateBounds, DashColor, emptyFunction, intersectRect, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils';
import { CognitiveServices } from '../../../cognitive_services/CognitiveServices';
import { Docs, DocUtils } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 5f4948808..df023b00f 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -1,33 +1,33 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Popup, PopupTrigger, Type } from 'browndash-components';
-import { action, computed, makeObservable, observable, ObservableMap, observe } from 'mobx';
+import { ObservableMap, action, computed, makeObservable, observable, observe } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { emptyFunction, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils';
import { Doc, DocListCast, Field, NumListCast, Opt, StrListCast } from '../../../../fields/Doc';
+import { DocData } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { List } from '../../../../fields/List';
import { listSpec } from '../../../../fields/Schema';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../Utils';
-import { Docs, DocumentOptions, DocUtils, FInfo } from '../../../documents/Documents';
+import { DocUtils, Docs, DocumentOptions, FInfo } from '../../../documents/Documents';
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager, dropActionType } from '../../../util/DragManager';
import { SelectionManager } from '../../../util/SelectionManager';
import { SettingsManager } from '../../../util/SettingsManager';
-import { undoable, undoBatch } from '../../../util/UndoManager';
+import { undoBatch, undoable } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
import { EditableView } from '../../EditableView';
+import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { DefaultStyleProvider, StyleProp } from '../../StyleProvider';
import { Colors } from '../../global/globalEnums';
import { DocumentView } from '../../nodes/DocumentView';
import { FieldViewProps, FocusViewOptions } from '../../nodes/FieldView';
import { KeyValueBox } from '../../nodes/KeyValueBox';
-import { ObservableReactComponent } from '../../ObservableReactComponent';
-import { DefaultStyleProvider, StyleProp } from '../../StyleProvider';
import { CollectionSubView } from '../CollectionSubView';
import './CollectionSchemaView.scss';
import { SchemaColumnHeader } from './SchemaColumnHeader';
import { SchemaRowBox } from './SchemaRowBox';
-import { DocData } from '../../../../fields/DocSymbols';
const { default: { SCHEMA_NEW_NODE_HEIGHT } } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore
export enum ColumnType {
diff --git a/src/client/views/newlightbox/Header/LightboxHeader.tsx b/src/client/views/newlightbox/Header/LightboxHeader.tsx
index a272ce294..76efe0185 100644
--- a/src/client/views/newlightbox/Header/LightboxHeader.tsx
+++ b/src/client/views/newlightbox/Header/LightboxHeader.tsx
@@ -1,62 +1,70 @@
-import './LightboxHeader.scss';
-import * as React from 'react';
-import { INewLightboxHeader } from "./utils";
-import { NewLightboxView } from '../NewLightboxView';
-import { StrCast } from '../../../../fields/Types';
-import { EditableText } from '../components/EditableText';
-import { getType } from '../utils';
import { Button, IconButton, Size, Type } from 'browndash-components';
-import { MdExplore, MdTravelExplore } from 'react-icons/md'
-import { BsBookmark, BsBookmarkFill } from 'react-icons/bs'
+import * as React from 'react';
+import { BsBookmark, BsBookmarkFill } from 'react-icons/bs';
+import { MdTravelExplore } from 'react-icons/md';
import { Doc } from '../../../../fields/Doc';
+import { StrCast } from '../../../../fields/Types';
import { LightboxView } from '../../LightboxView';
import { Colors } from '../../global/globalEnums';
-
+import { NewLightboxView } from '../NewLightboxView';
+import { EditableText } from '../components/EditableText';
+import { getType } from '../utils';
+import './LightboxHeader.scss';
+import { INewLightboxHeader } from './utils';
export const NewLightboxHeader = (props: INewLightboxHeader) => {
- const {height = 100, width} = props;
- const [doc, setDoc] = React.useState(LightboxView.LightboxDoc)
- const [editing, setEditing] = React.useState(false)
- const [title, setTitle] = React.useState(
- (null)
- )
+ const { height = 100, width } = props;
+ const [doc, setDoc] = React.useState(LightboxView.LightboxDoc);
+ const [editing, setEditing] = React.useState(false);
+ const [title, setTitle] = React.useState(null);
React.useEffect(() => {
- let lbDoc = LightboxView.LightboxDoc
- setDoc(lbDoc)
+ let lbDoc = LightboxView.LightboxDoc;
+ setDoc(lbDoc);
if (lbDoc) {
setTitle(
- {
- if(lbDoc) lbDoc.title = newText;
- }}
- setEditing={setEditing}
- />)
+ {
+ if (lbDoc) lbDoc.title = newText;
+ }}
+ setEditing={setEditing}
+ />
+ );
}
- }, [LightboxView.LightboxDoc])
+ }, [LightboxView.LightboxDoc]);
- const [saved, setSaved] = React.useState(false)
+ const [saved, setSaved] = React.useState(false);
- if (!doc) return null
- else return e.stopPropagation()} style={{ minHeight: height, height: height, width: width }}>
-
-
-
Type
-
{getType(StrCast(doc.type))}
-
-
- setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? : }/>
- setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? : }/>
-
-
- {
- console.log(NewLightboxView.ExploreMode)
- NewLightboxView.SetExploreMode(!NewLightboxView.ExploreMode)
- }} size={Size.XSMALL} color={Colors.DARK_GRAY} type={Type.SEC} text={"t-SNE 2D Embeddings"} icon={ }/>
-
-
-}
\ No newline at end of file
+ if (!doc) return null;
+ else
+ return (
+ e.stopPropagation()} style={{ minHeight: height, height: height, width: width }}>
+
+
+
Type
+
{getType(StrCast(doc.type))}
+
+
+ setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? : } />
+ setSaved(!saved)} color={Colors.DARK_GRAY} icon={saved ? : } />
+
+
+ {
+ console.log(NewLightboxView.ExploreMode);
+ NewLightboxView.SetExploreMode(!NewLightboxView.ExploreMode);
+ }}
+ size={Size.XSMALL}
+ color={Colors.DARK_GRAY}
+ type={Type.SEC}
+ text={'t-SNE 2D Embeddings'}
+ icon={ }
+ />
+
+
+ );
+};
diff --git a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx
index 9f3c32e4e..1d502b73f 100644
--- a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx
+++ b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx
@@ -1,74 +1,67 @@
-import { GrClose } from 'react-icons/gr';
-import { IRecommendation, Recommendation } from "../components";
-import './RecommendationList.scss';
+import { IconButton, Size, Type } from 'browndash-components';
import * as React from 'react';
-import { IRecommendationList } from "./utils";
-import { NewLightboxView } from '../NewLightboxView';
-import { DocCast, StrCast } from '../../../../fields/Types';
import { FaCaretDown, FaCaretUp } from 'react-icons/fa';
-import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc';
-import { IDocRequest, fetchKeywords, fetchRecommendations } from '../utils';
-import { IBounds } from '../ExploreView/utils';
+import { GrClose } from 'react-icons/gr';
+import { DocListCast, StrListCast } from '../../../../fields/Doc';
import { List } from '../../../../fields/List';
-import { Id } from '../../../../fields/FieldSymbols';
+import { StrCast } from '../../../../fields/Types';
import { LightboxView } from '../../LightboxView';
-import { IconButton, Size, Type } from 'browndash-components';
import { Colors } from '../../global/globalEnums';
+import { IBounds } from '../ExploreView/utils';
+import { NewLightboxView } from '../NewLightboxView';
+import { IRecommendation, Recommendation } from '../components';
+import { IDocRequest, fetchKeywords, fetchRecommendations } from '../utils';
+import './RecommendationList.scss';
+import { IRecommendationList } from './utils';
export const RecommendationList = (props: IRecommendationList) => {
- const {loading, keywords} = props
- const [loadingKeywords, setLoadingKeywords] = React.useState(true)
- const [showMore, setShowMore] = React.useState(false)
- const [keywordsLoc, setKeywordsLoc] = React.useState([])
- const [update, setUpdate] = React.useState(true)
- const initialRecs: IRecommendation[] = [
- {loading: true},
- {loading: true},
- {loading: true},
- {loading: true},
- {loading: true}
- ];
- const [recs, setRecs] = React.useState(initialRecs)
+ const { loading, keywords } = props;
+ const [loadingKeywords, setLoadingKeywords] = React.useState(true);
+ const [showMore, setShowMore] = React.useState(false);
+ const [keywordsLoc, setKeywordsLoc] = React.useState([]);
+ const [update, setUpdate] = React.useState(true);
+ const initialRecs: IRecommendation[] = [{ loading: true }, { loading: true }, { loading: true }, { loading: true }, { loading: true }];
+ const [recs, setRecs] = React.useState(initialRecs);
React.useEffect(() => {
const getKeywords = async () => {
- let text = StrCast(LightboxView.LightboxDoc?.text)
- console.log('[1] fetching keywords')
- const response = await fetchKeywords(text, 5, true)
- console.log('[2] response:', response)
+ let text = StrCast(LightboxView.LightboxDoc?.text);
+ console.log('[1] fetching keywords');
+ const response = await fetchKeywords(text, 5, true);
+ console.log('[2] response:', response);
const kw = response.keywords;
console.log(kw);
NewLightboxView.SetKeywords(kw);
if (LightboxView.LightboxDoc) {
- console.log('setting keywords on doc')
+ console.log('setting keywords on doc');
LightboxView.LightboxDoc.keywords = new List(kw);
setKeywordsLoc(NewLightboxView.Keywords);
}
- setLoadingKeywords(false)
- }
- let keywordsList = StrListCast(LightboxView.LightboxDoc!.keywords)
+ setLoadingKeywords(false);
+ };
+ let keywordsList = StrListCast(LightboxView.LightboxDoc!.keywords);
if (!keywordsList || keywordsList.length < 2) {
- setLoadingKeywords(true)
- getKeywords()
- setUpdate(!update)
+ setLoadingKeywords(true);
+ getKeywords();
+ setUpdate(!update);
} else {
- setKeywordsLoc(keywordsList)
- setLoadingKeywords(false)
- setUpdate(!update)
+ setKeywordsLoc(keywordsList);
+ setLoadingKeywords(false);
+ setUpdate(!update);
}
- }, [NewLightboxView.LightboxDoc])
+ }, [NewLightboxView.LightboxDoc]);
- // terms: vannevar bush, information spaces,
+ // terms: vannevar bush, information spaces,
React.useEffect(() => {
const getRecommendations = async () => {
- console.log('fetching recommendations')
- let query = 'undefined'
- if (keywordsLoc) query = keywordsLoc.join(',')
- let src = StrCast(NewLightboxView.LightboxDoc?.text)
- let dashDocs:IDocRequest[] = [];
+ console.log('fetching recommendations');
+ let query = 'undefined';
+ if (keywordsLoc) query = keywordsLoc.join(',');
+ let src = StrCast(NewLightboxView.LightboxDoc?.text);
+ let dashDocs: IDocRequest[] = [];
// get linked docs
- let linkedDocs = DocListCast(NewLightboxView.LightboxDoc?.links)
- console.log("linked docs", linkedDocs)
+ let linkedDocs = DocListCast(NewLightboxView.LightboxDoc?.links);
+ console.log('linked docs', linkedDocs);
// get context docs (docs that are also in the collection)
// let contextDocs: Doc[] = DocListCast(DocCast(LightboxView.LightboxDoc?.context).data)
// let docId = LightboxView.LightboxDoc && LightboxView.LightboxDoc[Id]
@@ -83,114 +76,142 @@ export const RecommendationList = (props: IRecommendationList) => {
// })
// }
// })
- console.log("dash docs", dashDocs)
+ console.log('dash docs', dashDocs);
if (query !== undefined) {
- const response = await fetchRecommendations(src, query, [], true)
- const num_recs = response.num_recommendations
- const recs = response.recommendations
- const keywords = response.keywords
+ const response = await fetchRecommendations(src, query, [], true);
+ const num_recs = response.num_recommendations;
+ const recs = response.recommendations;
+ const keywords = response.keywords;
const response_bounds: IBounds = {
- max_x: response.max_x,
- max_y: response.max_y,
- min_x: response.min_x,
- min_y: response.min_y
- }
+ max_x: response.max_x,
+ max_y: response.max_y,
+ min_x: response.min_x,
+ min_y: response.min_y,
+ };
// if (NewLightboxView.NewLightboxDoc) {
// NewLightboxView.NewLightboxDoc.keywords = new List(keywords);
// setKeywordsLoc(NewLightboxView.Keywords);
// }
// console.log(response_bounds)
- NewLightboxView.SetBounds(response_bounds)
+ NewLightboxView.SetBounds(response_bounds);
const recommendations: IRecommendation[] = [];
for (const key in recs) {
- console.log(key)
+ console.log(key);
const title = recs[key].title;
- const url = recs[key].url
- const type = recs[key].type
- const text = recs[key].text
- const transcript = recs[key].transcript
- const previewUrl = recs[key].previewUrl
- const embedding = recs[key].embedding
- const distance = recs[key].distance
- const source = recs[key].source
- const related_concepts = recs[key].related_concepts
- const docId = recs[key].doc_id
- related_concepts.length >= 1 && recommendations.push({
- title: title,
- data: url,
- type: type,
- text: text,
- transcript: transcript,
- previewUrl: previewUrl,
- embedding: embedding,
- distance: Math.round(distance * 100) / 100,
- source: source,
- related_concepts: related_concepts,
- docId: docId
- })
+ const url = recs[key].url;
+ const type = recs[key].type;
+ const text = recs[key].text;
+ const transcript = recs[key].transcript;
+ const previewUrl = recs[key].previewUrl;
+ const embedding = recs[key].embedding;
+ const distance = recs[key].distance;
+ const source = recs[key].source;
+ const related_concepts = recs[key].related_concepts;
+ const docId = recs[key].doc_id;
+ related_concepts.length >= 1 &&
+ recommendations.push({
+ title: title,
+ data: url,
+ type: type,
+ text: text,
+ transcript: transcript,
+ previewUrl: previewUrl,
+ embedding: embedding,
+ distance: Math.round(distance * 100) / 100,
+ source: source,
+ related_concepts: related_concepts,
+ docId: docId,
+ });
}
recommendations.sort((a, b) => {
if (a.distance && b.distance) {
- return a.distance - b.distance
- } else return 0
- })
- console.log("[rec]: ", recommendations)
- NewLightboxView.SetRecs(recommendations)
- setRecs(recommendations)
+ return a.distance - b.distance;
+ } else return 0;
+ });
+ console.log('[rec]: ', recommendations);
+ NewLightboxView.SetRecs(recommendations);
+ setRecs(recommendations);
}
- }
+ };
getRecommendations();
- }, [update])
-
-
+ }, [update]);
- return {e.stopPropagation()}}>
-
-
- Recommendations
-
- {NewLightboxView.LightboxDoc &&
- The recommendations are produced based on the text in the document {StrCast(NewLightboxView.LightboxDoc.title)} . The following keywords are used to fetch the recommendations.
-
}
-
Keywords
- {loadingKeywords ?
-
-
-
-
+ return (
+
{
+ e.stopPropagation();
+ }}>
+
+
Recommendations
+ {NewLightboxView.LightboxDoc && (
+
+ The recommendations are produced based on the text in the document{' '}
+
+ {StrCast(NewLightboxView.LightboxDoc.title)}
+
+ . The following keywords are used to fetch the recommendations.
- :
-
- {keywordsLoc && keywordsLoc.map((word, ind) => {
- return
- {word}
-
} onClick={() => {
- let kw = keywordsLoc
- kw.splice(ind)
- NewLightboxView.SetKeywords(kw)
- }}/>
+ )}
+ Keywords
+ {loadingKeywords ? (
+
- })}
-
- }
- {!showMore ?
-
{setShowMore(true)}}>
- More
+ ) : (
+
+ {keywordsLoc &&
+ keywordsLoc.map((word, ind) => {
+ return (
+
+ {word}
+ }
+ onClick={() => {
+ let kw = keywordsLoc;
+ kw.splice(ind);
+ NewLightboxView.SetKeywords(kw);
+ }}
+ />
+
+ );
+ })}
+
+ )}
+ {!showMore ? (
+
{
+ setShowMore(true);
+ }}>
+ More
+
+ ) : (
+
+
{
+ setShowMore(false);
+ }}>
+ Less
+
+
Type
+
Sources
+
+ )}
- :
-
-
{setShowMore(false)}}>
- Less
-
-
Type
-
Sources
+
+ {recs &&
+ recs.map((rec: IRecommendation) => {
+ return ;
+ })}
- }
-
-
- {recs && recs.map((rec: IRecommendation) => {
- return
- })}
-
-}
\ No newline at end of file
+ );
+};
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 58820a498..a04030a5f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,6 +1,6 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { Howl } from 'howler';
-import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction, trace } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Bounce, Fade, Flip, JackInTheBox, Roll, Rotate, Zoom } from 'react-awesome-reveal';
@@ -50,7 +50,6 @@ import { KeyValueBox } from './KeyValueBox';
import { LinkAnchorBox } from './LinkAnchorBox';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
import { PresEffect, PresEffectDirection } from './trails';
-import { InkingStroke } from '../InkingStroke';
interface Window {
MediaRecorder: MediaRecorder;
}
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index c43f89be1..a557cff4f 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -1,6 +1,7 @@
import { action, makeObservable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { DivHeight, DivWidth } from '../../../Utils';
import { Id } from '../../../fields/FieldSymbols';
import { NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
@@ -11,7 +12,6 @@ import { LightboxView } from '../LightboxView';
import './EquationBox.scss';
import { FieldView, FieldViewProps } from './FieldView';
import EquationEditor from './formattedText/EquationEditor';
-import { DivHeight, DivWidth } from '../../../Utils';
@observer
export class EquationBox extends ViewBoxBaseComponent
() {
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 7ad250714..36bd037ca 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -15,9 +15,9 @@ import { EditableView } from '../EditableView';
import { LightboxView } from '../LightboxView';
import { StyleProp } from '../StyleProvider';
import { ComparisonBox } from './ComparisonBox';
+import { DocumentView } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import './LinkBox.scss';
-import { DocumentView } from './DocumentView';
@observer
export class LinkBox extends ViewBoxBaseComponent() {
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index f4d5eef05..434415b96 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,6 +1,6 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { htmlToText } from 'html-to-text';
-import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction, trace } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import * as WebRequest from 'web-request';
@@ -34,7 +34,7 @@ import { GPTPopup } from '../pdf/GPTPopup/GPTPopup';
import { SidebarAnnos } from '../SidebarAnnos';
import { StyleProp } from '../StyleProvider';
import { DocumentView, OpenWhere } from './DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from './FieldView';
+import { FieldView, FieldViewProps, FocusViewOptions } from './FieldView';
import { LinkInfo } from './LinkDocPreview';
import { PinProps, PresBox } from './trails';
import './WebBox.scss';
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index ae6da8fb0..cd9fec839 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -18,6 +18,7 @@ import { DocServer } from '../../../DocServer';
import { Docs } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
import { DocumentManager } from '../../../util/DocumentManager';
+import { dropActionType } from '../../../util/DragManager';
import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
import { SelectionManager } from '../../../util/SelectionManager';
import { SerializationHelper } from '../../../util/SerializationHelper';
@@ -32,11 +33,10 @@ import { ViewBoxBaseComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
import { LightboxView } from '../../LightboxView';
import { DocumentView, OpenWhere, OpenWhereMod } from '../DocumentView';
-import { FocusViewOptions, FieldView, FieldViewProps } from '../FieldView';
+import { FieldView, FieldViewProps, FocusViewOptions } from '../FieldView';
import { ScriptingBox } from '../ScriptingBox';
import './PresBox.scss';
import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums';
-import { dropActionType } from '../../../util/DragManager';
export interface pinDataTypes {
scrollable?: boolean;
dataviz?: number[];
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index addad2bbc..eab33114e 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -3,6 +3,7 @@ import { Button, IconButton, isDark, Size, Type } from 'browndash-components';
import { action, computed, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { Flip } from 'react-awesome-reveal';
import { FaBug } from 'react-icons/fa';
import { Doc, DocListCast } from '../../../fields/Doc';
import { AclAdmin, DashVersion } from '../../../fields/DocSymbols';
@@ -11,6 +12,7 @@ import { GetEffectiveAcl } from '../../../fields/util';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils';
import { CurrentUserUtils } from '../../util/CurrentUserUtils';
import { DocumentManager } from '../../util/DocumentManager';
+import { dropActionType } from '../../util/DragManager';
import { PingManager } from '../../util/PingManager';
import { ReportManager } from '../../util/reportManager/ReportManager';
import { ServerStats } from '../../util/ServerStats';
@@ -23,11 +25,9 @@ import { CollectionLinearView } from '../collections/collectionLinear';
import { DashboardView } from '../DashboardView';
import { Colors } from '../global/globalEnums';
import { DocumentViewInternal, returnEmptyDocViewList } from '../nodes/DocumentView';
+import { ObservableReactComponent } from '../ObservableReactComponent';
import { DefaultStyleProvider } from '../StyleProvider';
import './TopBar.scss';
-import { dropActionType } from '../../util/DragManager';
-import { Flip } from 'react-awesome-reveal';
-import { ObservableReactComponent } from '../ObservableReactComponent';
/**
* ABOUT: This is the topbar in Dash, which included the current Dashboard as well as access to information on the user
--
cgit v1.2.3-70-g09d2