diff options
Diffstat (limited to 'src/client')
27 files changed, 304 insertions, 264 deletions
diff --git a/src/client/documents/DocFromField.ts b/src/client/documents/DocFromField.ts index b65bbbdf5..9acb9c225 100644 --- a/src/client/documents/DocFromField.ts +++ b/src/client/documents/DocFromField.ts @@ -1,5 +1,4 @@ import { Doc, DocListCast } from '../../fields/Doc'; -import { InkField } from '../../fields/InkField'; import { List } from '../../fields/List'; import { StrCast } from '../../fields/Types'; import { AudioField, ImageField, PdfField, VideoField } from '../../fields/URLField'; @@ -12,7 +11,17 @@ export function ResetLayoutFieldKey(doc: Doc, fieldKey: string) { doc.layout = StrCast(doc.layout).replace(/={'.*'}/, `={'${fieldKey}'}`); return doc; } -export function DocumentFromField(target: Doc, fieldKey: string, proto?: Doc, options?: DocumentOptions): Doc | undefined { +/** + * Creates a new document based on the type of (and containing the) data in the specified field of an existing document. + * If the field contains a list, then it may be useful to specify a classProto to indicate the type of + * collection Doc that gets created. + * @param target document to retrive field from + * @param fieldKey field key to retrieve + * @param classProto optionally a class proto to set on the new document + * @param options metadata configuration for new document + * @returns + */ +export function DocumentFromField(target: Doc, fieldKey: string, classProto?: Doc, options?: DocumentOptions): Doc | undefined { const field = target[fieldKey]; const resolved = options ?? {}; const nonDocFieldToDoc = () => { @@ -20,12 +29,11 @@ export function DocumentFromField(target: Doc, fieldKey: string, proto?: Doc, op if (field instanceof VideoField) return Docs.Create.VideoDocument(field.url.href, resolved); if (field instanceof PdfField) return Docs.Create.PdfDocument(field.url.href, resolved); if (field instanceof AudioField) return Docs.Create.AudioDocument(field.url.href, resolved); - if (field instanceof InkField) return Docs.Create.InkDocument(field.inkData, resolved); if (field instanceof List && field[0] instanceof Doc) return Docs.Create.StackingDocument(DocListCast(field), resolved); return Docs.Create.TextDocument('', { ...{ _width: 200, _height: 25, _layout_autoHeight: true }, ...resolved }); }; const created = field instanceof Doc ? field : ResetLayoutFieldKey(nonDocFieldToDoc(), fieldKey); created.title = fieldKey; - proto && created.proto && (created.proto = Doc.GetProto(proto)); + classProto && created.proto && (created.proto = classProto); return created; } diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ea5eca804..fb5cb27b2 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -5,7 +5,7 @@ import { reaction } from 'mobx'; import { basename } from 'path'; import { ClientUtils, OmitKeys } from '../../ClientUtils'; import { DateField } from '../../fields/DateField'; -import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, CreateLinkToActiveAudio, Doc, FieldType, Opt, updateCachedAcls } from '../../fields/Doc'; +import { CreateLinkToActiveAudio, Doc, FieldType, Opt, updateCachedAcls } from '../../fields/Doc'; import { Initializing } from '../../fields/DocSymbols'; import { HtmlField } from '../../fields/HtmlField'; import { InkField } from '../../fields/InkField'; @@ -838,18 +838,7 @@ export namespace Docs { return linkDoc; } - export function InkDocument( - points: PointData[], - options: DocumentOptions = {}, - strokeWidth = ActiveInkWidth(), - color = ActiveInkColor(), - strokeBezier = ActiveInkBezierApprox(), - fillColor = ActiveFillColor(), - arrowStart = ActiveArrowStart(), - arrowEnd = ActiveArrowEnd(), - dash = ActiveDash(), - isInkMask = ActiveIsInkMask() - ) { + export function InkDocument(points: PointData[], options: DocumentOptions = {}, strokeWidth: number, color: string, strokeBezier: string, fillColor: string, arrowStart: string, arrowEnd: string, dash: string, isInkMask: boolean) { const ink = InstanceFromProto(Prototypes.get(DocumentType.INK), '', { title: 'ink', ...options }); const I = Doc.GetProto(ink); // I.layout_hideOpenButton = true; // don't show open full screen button when selected @@ -865,6 +854,7 @@ export namespace Docs { I.text_align = 'center'; I.rotation = 0; I.defaultDoubleClick = 'ignore'; + I.keepZWhenDragged = true; I.author_date = new DateField(); I.acl_Guest = Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View; // I.acl_Override = SharingPermissions.Unset; diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index d3c10f9f4..278931cdd 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -29,7 +29,7 @@ export enum ColorScheme { } @observer -export class SettingsManager extends React.Component<{}> { +export class SettingsManager extends React.Component<object> { // eslint-disable-next-line no-use-before-define public static Instance: SettingsManager; static _settingsStyle = addStyleSheet(); @@ -123,7 +123,7 @@ export class SettingsManager extends React.Component<{}> { 'change color scheme' ); - constructor(props: {}) { + constructor(props: object) { super(props); makeObservable(this); SettingsManager.Instance = this; diff --git a/src/client/util/SnappingManager.ts b/src/client/util/SnappingManager.ts index 1337d271f..cc0366c5b 100644 --- a/src/client/util/SnappingManager.ts +++ b/src/client/util/SnappingManager.ts @@ -11,6 +11,7 @@ export class SnappingManager { return SnappingManager._manager ?? new SnappingManager(); } + @observable _longPress = false; @observable _shiftKey = false; @observable _ctrlKey = false; @observable _metaKey = false; @@ -43,6 +44,7 @@ export class SnappingManager { public static get HorizSnapLines() { return this.Instance._horizSnapLines; } // prettier-ignore public static get VertSnapLines() { return this.Instance._vertSnapLines; } // prettier-ignore + public static get LongPress() { return this.Instance._longPress; } // prettier-ignore public static get ShiftKey() { return this.Instance._shiftKey; } // prettier-ignore public static get CtrlKey() { return this.Instance._ctrlKey; } // prettier-ignore public static get MetaKey() { return this.Instance._metaKey; } // prettier-ignore @@ -58,6 +60,7 @@ export class SnappingManager { public static get PropertiesWidth(){ return this.Instance._propertyWid; } // prettier-ignore public static get PrintToConsole() { return this.Instance._printToConsole; } // prettier-ignore + public static SetLongPress = (press: boolean) => runInAction(() => {this.Instance._longPress = press}); // prettier-ignore public static SetShiftKey = (down: boolean) => runInAction(() => {this.Instance._shiftKey = down}); // prettier-ignore public static SetCtrlKey = (down: boolean) => runInAction(() => {this.Instance._ctrlKey = down}); // prettier-ignore public static SetMetaKey = (down: boolean) => runInAction(() => {this.Instance._metaKey = down}); // prettier-ignore diff --git a/src/client/util/request-image-size.ts b/src/client/util/request-image-size.ts index 0f98a2710..48cb6e3a5 100644 --- a/src/client/util/request-image-size.ts +++ b/src/client/util/request-image-size.ts @@ -54,6 +54,7 @@ module.exports = function requestImageSize(options: any) { } } catch (err) { /* empty */ + console.log("Error: ", err) } }); diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 2f26bdaef..e3e252593 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -4,25 +4,23 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../ClientUtils'; import { emptyFunction } from '../../Utils'; +import { Doc, Opt } from '../../fields/Doc'; +import { InkData, InkField, InkTool } from '../../fields/InkField'; +import { NumCast } from '../../fields/Types'; import { ActiveArrowEnd, ActiveArrowScale, ActiveArrowStart, ActiveDash, - ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, - Doc, - Opt, SetActiveArrowStart, SetActiveDash, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth, -} from '../../fields/Doc'; -import { InkData, InkField, InkTool } from '../../fields/InkField'; -import { NumCast } from '../../fields/Types'; +} from './nodes/DocumentView'; // import MobileInkOverlay from '../../mobile/MobileInkOverlay'; import { Gestures } from '../../pen-gestures/GestureTypes'; import { GestureUtils } from '../../pen-gestures/GestureUtils'; @@ -32,7 +30,7 @@ import { ScriptingGlobals } from '../util/ScriptingGlobals'; import { Transform } from '../util/Transform'; import './GestureOverlay.scss'; import { ObservableReactComponent } from './ObservableReactComponent'; -import { DocumentView } from './nodes/DocumentView'; +import { ActiveFillColor, DocumentView } from './nodes/DocumentView'; export enum ToolglassTools { InkToText = 'inktotext', diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 31d88fb87..ef1bcfb64 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -555,16 +555,16 @@ export class MainView extends ObservableReactComponent<{}> { private longPressTimer: NodeJS.Timeout | undefined; globalPointerClick = action(() => { this.longPressTimer && clearTimeout(this.longPressTimer); - DocumentView.LongPress = false; + SnappingManager.SetLongPress(false); }); globalPointerMove = action((e: PointerEvent) => { if (e.movementX > 3 || e.movementY > 3) this.longPressTimer && clearTimeout(this.longPressTimer); }); globalPointerDown = action((e: PointerEvent) => { - DocumentView.LongPress = false; + SnappingManager.SetLongPress(false); this.longPressTimer = setTimeout( action(() => { - DocumentView.LongPress = true; + SnappingManager.SetLongPress(true); }), 1000 ); diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index b7f8a3170..8c100f238 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -152,7 +152,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & case StyleProp.DocContents: return undefined; case StyleProp.WidgetColor: return isAnnotated ? Colors.LIGHT_BLUE : 'dimgrey'; case StyleProp.Opacity: return componentView?.isUnstyledView?.() ? 1 : Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null)); - case StyleProp.FontColor: return StrCast(doc?.[fieldKey + 'fontColor'], StrCast(Doc.UserDoc().fontColor, color())); + case StyleProp.FontColor: return StrCast(doc?.[fieldKey + 'fontColor'], isCaption ? lightOrDark(backgroundCol()) : StrCast(Doc.UserDoc().fontColor, color())); case StyleProp.FontSize: return StrCast(doc?.[fieldKey + 'fontSize'], StrCast(Doc.UserDoc().fontSize)); case StyleProp.FontFamily: return StrCast(doc?.[fieldKey + 'fontFamily'], StrCast(Doc.UserDoc().fontFamily)); case StyleProp.FontWeight: return StrCast(doc?.[fieldKey + 'fontWeight'], StrCast(Doc.UserDoc().fontWeight)); diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index 27c85533f..38f681e87 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -17,6 +17,7 @@ import { FocusViewOptions } from '../nodes/FocusViewOptions'; import './CollectionCarousel3DView.scss'; import { CollectionSubView } from './CollectionSubView'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } = require('../global/globalCssVariables.module.scss'); @observer diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 73179a266..2a36e96bf 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -58,7 +58,7 @@ export class CollectionDockingView extends CollectionSubView() { return this._goldenLayout._maximisedItem !== null; } private _goldenLayout: any = null; - static _highlightStyleSheet: any = addStyleSheet(); + static _highlightStyleSheet = addStyleSheet(); constructor(props: any) { super(props); diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 3eb3008c4..b2f0280a5 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -17,7 +17,7 @@ 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 { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; import { DragManager } from '../../util/DragManager'; import { dropActionType } from '../../util/DropActionTypes'; @@ -47,7 +47,7 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> { private _docBtnRef = React.createRef<HTMLDivElement>(); - constructor(props: any) { + constructor(props: CollectionMenuProps) { super(props); makeObservable(this); CollectionMenu.Instance = this; @@ -279,8 +279,8 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu initialize: (button: Doc) => { const activeDash = Doc.ActiveDashboard; if (activeDash) { - button.target_childFilters = (Doc.MySearcher._childFilters || activeDash._childFilters) instanceof ObjectField ? ObjectField.MakeCopy((Doc.MySearcher._childFilters || activeDash._childFilters) as any as ObjectField) : undefined; - button.target_searchFilterDocs = activeDash._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(activeDash._searchFilterDocs as any as ObjectField) : undefined; + button.target_childFilters = (Doc.MySearcher._childFilters || activeDash._childFilters) instanceof ObjectField ? ObjectField.MakeCopy((Doc.MySearcher._childFilters || activeDash._childFilters) as ObjectField) : undefined; + button.target_searchFilterDocs = activeDash._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(activeDash._searchFilterDocs) : undefined; } }, }; @@ -338,15 +338,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu this._currentKey = this._currentKey || (this._buttonizableCommands?.length ? this._buttonizableCommands[0]?.title : ''); }); - @undoBatch - viewChanged = (e: React.ChangeEvent) => { - const target = this.document !== Doc.MyLeftSidebarPanel ? this.document : DocCast(this.document.proto); - target._type_collection = (e.target as any).selectedOptions[0].value; - }; - - commandChanged = (e: React.ChangeEvent) => { + commandChanged = (e: React.ChangeEvent<HTMLSelectElement>) => { runInAction(() => { - this._currentKey = (e.target as any).selectedOptions[0].value; + this._currentKey = e.target.selectedOptions[0].value; }); }; @@ -485,7 +479,7 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi }; @action - onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => { + onKeyChange = (e: React.FormEvent<Element>, { newValue }: { newValue: string }) => { this._currentKey = newValue; }; @@ -538,7 +532,6 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi autosuggestProps: { inputProps: { value: this._currentKey, - // @ts-ignore onChange: this.onKeyChange, }, getSuggestionValue: this.getSuggestionValue, @@ -733,7 +726,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu onChange={this.changeCompactType} value={StrCast(this.document.gridStartCompaction, StrCast(this.document.gridCompaction))}> {['vertical', 'horizontal', 'none'].map(type => ( - <option className="collectionGridViewChrome-viewOption" onPointerDown={stopPropagation} value={type}> + <option key={type} className="collectionGridViewChrome-viewOption" onPointerDown={stopPropagation} value={type}> {this.resize ? type[0].toUpperCase() + type.substring(1) : 'Compact: ' + type} </option> ))} diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index c39df2c76..285598600 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -52,7 +52,6 @@ export type collectionTreeViewProps = { export class CollectionTreeView extends CollectionSubView<Partial<collectionTreeViewProps>>() { public static AddTreeFunc = 'addTreeFolder(this.embedContainer)'; private _treedropDisposer?: DragManager.DragDropDisposer; - private _mainEle?: HTMLDivElement; private _titleRef?: HTMLDivElement | HTMLInputElement | null; private _disposers: { [name: string]: IReactionDisposer } = {}; private _isDisposing = false; // notes that instance is in process of being disposed @@ -83,8 +82,6 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree @observable _titleHeight = 0; // height of the title bar - MainEle = () => this._mainEle; - // these should stay in synch with counterparts in DocComponent.ts ViewBoxAnnotatableComponent @observable _isAnyChildContentActive = false; whenChildContentsActiveChanged = action((isActive: boolean) => { @@ -134,7 +131,6 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree }; protected createTreeDropTarget = (ele: HTMLDivElement) => { this._treedropDisposer?.(); - this._mainEle = ele; if (ele) this._treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.Document, this.onInternalPreDrop.bind(this)); }; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index b82421e6b..f69aea2a7 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -469,14 +469,12 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> { return false; } - refTransform = (ref: HTMLDivElement | undefined | null) => { + refTransform = (ref: HTMLElement | undefined | null) => { if (!ref) return this.ScreenToLocalTransform(); - const { translateX, translateY } = ClientUtils.GetScreenTransform(ref); - const outerXf = ClientUtils.GetScreenTransform(this.treeView.MainEle()); - const offset = this.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY); - return this.ScreenToLocalTransform().translate(offset[0], offset[1]); + const { translateX, translateY, scale } = ClientUtils.GetScreenTransform(ref); + return new Transform(-translateX, -translateY, 1).scale(1/scale); }; - docTransform = () => this.refTransform(this._dref?.ContentRef?.current); + docTransform = () => this.refTransform(this._dref?.ContentDiv); getTransform = () => this.refTransform(this._tref.current); embeddedPanelWidth = () => this._props.panelWidth() / (this.treeView._props.NativeDimScaling?.() || 1); embeddedPanelHeight = () => { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index b6e1fca77..5b7f09be3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -9,7 +9,8 @@ import { computedFn } from 'mobx-utils'; import * as React from 'react'; import { ClientUtils, DashColor, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../../ClientUtils'; import { DateField } from '../../../../fields/DateField'; -import { ActiveEraserWidth, ActiveInkWidth, Doc, DocListCast, Field, FieldType, Opt, SetActiveInkColor, SetActiveInkWidth } from '../../../../fields/Doc'; +import { Doc, DocListCast, Field, FieldType, Opt } from '../../../../fields/Doc'; +import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveEraserWidth, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, SetActiveInkColor, SetActiveInkWidth } from '../../nodes/DocumentView'; import { DocData, Height, Width } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { InkData, InkField, InkTool, Segment } from '../../../../fields/InkField'; @@ -38,7 +39,7 @@ import { ContextMenu } from '../../ContextMenu'; import { InkingStroke } from '../../InkingStroke'; import { CollectionFreeFormDocumentView } from '../../nodes/CollectionFreeFormDocumentView'; import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp'; -import { DocumentView } from '../../nodes/DocumentView'; +import { ActiveFillColor, DocumentView } from '../../nodes/DocumentView'; import { FieldViewProps } from '../../nodes/FieldView'; import { FocusViewOptions } from '../../nodes/FocusViewOptions'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; @@ -87,8 +88,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection } private _clusters = new CollectionFreeFormClusters(this); - private _oldWheel: any; - private _panZoomTransitionTimer: any; + private _oldWheel: HTMLDivElement | null = null; + private _panZoomTransitionTimer: NodeJS.Timeout | undefined = undefined; + private _brushtimer: NodeJS.Timeout | undefined = undefined; + private _brushtimer1: NodeJS.Timeout | undefined = undefined; private _lastX: number = 0; private _lastY: number = 0; private _downX: number = 0; @@ -97,8 +100,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection private _disposers: { [name: string]: IReactionDisposer } = {}; private _renderCutoffData = observable.map<string, boolean>(); private _batch: UndoManager.Batch | undefined = undefined; - private _brushtimer: any; - private _brushtimer1: any; private _keyTimer: NodeJS.Timeout | undefined; // timer for turning off transition flag when key frame change has completed. Need to clear this if you do a second navigation before first finishes, or else first timer can go off during second naviation. private _presEaseFunc: string = 'ease'; @@ -129,7 +130,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection @observable _eraserX: number = 0; @observable _eraserY: number = 0; @observable _showEraserCircle: boolean = false; // to determine whether the radius eraser should show - constructor(props: any) { + constructor(props: collectionFreeformViewProps) { super(props); makeObservable(this); } @@ -550,7 +551,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection _width: B.width + inkWidth, _height: B.height + inkWidth, stroke_showLabel: BoolCast(Doc.UserDoc().activeInkHideTextLabels)}, // prettier-ignore - inkWidth + inkWidth, + ActiveInkColor(), + ActiveInkBezierApprox(), + ActiveFillColor(), + ActiveArrowStart(), + ActiveArrowEnd(), + ActiveDash(), + ActiveIsInkMask() ); if (Doc.ActiveTool === InkTool.Write) { this.unprocessedDocs.push(inkDoc); @@ -634,7 +642,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection _width: B.width + inkWidth, _height: B.height + inkWidth, stroke_showLabel: BoolCast(Doc.UserDoc().activeInkHideTextLabels)}, // prettier-ignore - inkWidth + inkWidth, + ActiveInkColor(), + ActiveInkBezierApprox(), + ActiveFillColor(), + ActiveArrowStart(), + ActiveArrowEnd(), + ActiveDash(), + ActiveIsInkMask() ); }); newStrokes && this.addDocument?.(newStrokes); @@ -684,8 +699,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection return false; }; - forceStrokeGesture = (e: PointerEvent, gesture: Gestures, points: InkData, text?: any) => { - this.onGesture(e, new GestureUtils.GestureEvent(gesture, points, InkField.getBounds(points), text)); + forceStrokeGesture = (e: PointerEvent, gesture: Gestures, points: InkData) => { + this.onGesture(e, new GestureUtils.GestureEvent(gesture, points, InkField.getBounds(points))); }; onPointerMove = (e: PointerEvent) => { @@ -1639,7 +1654,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection * since rendering a large collection of documents can be slow, at startup, docs are rendered in batches. * each doc's render() method will call the cutoff provider which will let the doc know if it should render itself yet, or wait */ - renderCutoffProvider = computedFn((doc: Doc) => (this.Document.isTemplateDoc ? false : !this._renderCutoffData.get(doc[Id] + ''))); + renderCutoffProvider = computedFn((doc: Doc) => (this.Document.isTemplateDoc || this.Document.isTemplateForField ? false : !this._renderCutoffData.get(doc[Id] + ''))); doEngineLayout( poolData: Map<string, PoolData>, @@ -1673,7 +1688,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection .forEach(entry => elements.push({ ele: this.getChildDocView(entry[1]), - bounds: (entry[1].opacity === 0 ? { ...entry[1], width: 0, height: 0 } : { ...entry[1] }) as any, + bounds: (entry[1].opacity === 0 ? { payload:undefined, type:"", ...entry[1], width: 0, height: 0 } : { payload:undefined, type:"",...entry[1] }), inkMask: BoolCast(entry[1].pair.layout.stroke_isInkMask) ? NumCast(entry[1].pair.layout.opacity, 1) : -1, }) ); @@ -1795,10 +1810,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection Object.values(this._disposers).forEach(disposer => disposer?.()); } - updateIcon = () => - UpdateIcon( + updateIcon = () => { + const contentDiv = this.DocumentView?.().ContentDiv; + contentDiv && UpdateIcon( this.layoutDoc[Id] + '-icon' + new Date().getTime(), - this.DocumentView?.().ContentDiv!, + contentDiv, NumCast(this.layoutDoc._width), NumCast(this.layoutDoc._height), this._props.PanelWidth(), @@ -1813,6 +1829,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection this.dataDoc.icon_nativeHeight = nativeHeight; } ); + } @action onCursorMove = (e: React.PointerEvent) => { @@ -1993,7 +2010,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection incrementalRender = action(() => { if (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.())) { const layoutUnrendered = this.childDocs.filter(doc => !this._renderCutoffData.get(doc[Id])); - const loadIncrement = this.Document.isTemplateDoc ? Number.MAX_VALUE : 5; + const loadIncrement = this.Document.isTemplateDoc || this.Document.isTemplateForField ? Number.MAX_VALUE : 5; for (let i = 0; i < Math.min(layoutUnrendered.length, loadIncrement); i++) { this._renderCutoffData.set(layoutUnrendered[i][Id] + '', true); } diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 7c2cfd15f..6bea53355 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -32,6 +32,7 @@ import './CollectionSchemaView.scss'; import { SchemaColumnHeader } from './SchemaColumnHeader'; import { SchemaRowBox } from './SchemaRowBox'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const { SCHEMA_NEW_NODE_HEIGHT } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore export const FInfotoColType: { [key: string]: ColumnType } = { diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 7730ed385..2b7de5082 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -1,25 +1,10 @@ import { Colors } from 'browndash-components'; import { action, runInAction } from 'mobx'; import { aggregateBounds } from '../../../Utils'; -import { - ActiveFillColor, - ActiveEraserWidth, - ActiveInkColor, - ActiveInkHideTextLabels, - ActiveInkWidth, - ActiveIsInkMask, - Doc, - DocListCast, - Opt, - SetActiveFillColor, - SetActiveInkColor, - SetActiveInkHideTextLabels, - SetActiveInkWidth, - SetActiveIsInkMask, - SetEraserWidth, -} from '../../../fields/Doc'; +import { Doc, DocListCast, NumListCast, Opt } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { InkTool } from '../../../fields/InkField'; +import { List } from '../../../fields/List'; import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types'; import { WebField } from '../../../fields/URLField'; import { Gestures } from '../../../pen-gestures/GestureTypes'; @@ -31,13 +16,25 @@ import { GestureOverlay } from '../GestureOverlay'; import { InkingStroke } from '../InkingStroke'; import { CollectionFreeFormView } from '../collections/collectionFreeForm'; import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView'; -import { DocumentView } from '../nodes/DocumentView'; +import { + ActiveEraserWidth, + ActiveFillColor, + ActiveInkColor, + ActiveInkHideTextLabels, + ActiveInkWidth, + ActiveIsInkMask, + DocumentView, + SetActiveFillColor, + SetActiveInkColor, + SetActiveInkHideTextLabels, + SetActiveInkWidth, + SetActiveIsInkMask, + SetEraserWidth, +} from '../nodes/DocumentView'; import { ImageBox } from '../nodes/ImageBox'; import { VideoBox } from '../nodes/VideoBox'; import { WebBox } from '../nodes/WebBox'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; -import { NumListCast } from '../../../fields/Doc'; -import { List } from '../../../fields/List'; // import { InkTranscription } from '../InkTranscription'; @@ -59,7 +56,7 @@ ScriptingGlobals.add(function setView(view: string, getSelected: boolean) { // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function setBackgroundColor(color?: string, checkResult?: boolean) { const selectedViews = DocumentView.Selected(); - if (Doc.ActiveTool !== InkTool.None) { + if (Doc.ActiveTool !== InkTool.None && !selectedViews.lastElement()?.Document._layout_isSvg) { if (checkResult) { return ActiveFillColor(); } @@ -450,15 +447,19 @@ function setActiveTool(tool: InkTool | Gestures, keepPrim: boolean, checkResult? GestureOverlay.Instance.InkShape = tool as Gestures; } } else if (tool) { - if ([InkTool.StrokeEraser, InkTool.RadiusEraser, InkTool.SegmentEraser].includes(tool as any)) { - Doc.UserDoc().activeEraserTool = tool; - } - // pen or eraser - if (Doc.ActiveTool === tool && !GestureOverlay.Instance.InkShape && !keepPrim) { + if (Doc.UserDoc().ActiveTool === tool) { Doc.ActiveTool = InkTool.None; } else { - Doc.ActiveTool = tool as any; - GestureOverlay.Instance.InkShape = undefined; + if ([InkTool.StrokeEraser, InkTool.RadiusEraser, InkTool.SegmentEraser].includes(tool as any)) { + Doc.UserDoc().activeEraserTool = tool; + } + // pen or eraser + if (Doc.ActiveTool === tool && !GestureOverlay.Instance.InkShape && !keepPrim) { + Doc.ActiveTool = InkTool.None; + } else { + Doc.ActiveTool = tool as any; + GestureOverlay.Instance.InkShape = undefined; + } } } else { Doc.ActiveTool = InkTool.None; diff --git a/src/client/views/nodes/ChatBox/MessageComponent.scss b/src/client/views/nodes/ChatBox/MessageComponent.scss new file mode 100644 index 000000000..6fcc0e5e7 --- /dev/null +++ b/src/client/views/nodes/ChatBox/MessageComponent.scss @@ -0,0 +1,10 @@ +MessageComponent-citation { + color: lightblue; + vertical-align: super; + font-size: smaller; +} +MessageComponent-file_path { + color: lightblue; + vertical-align: baseline; + font-size: inherit; +} diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 034a38e9c..ee67dd305 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -20,6 +20,11 @@ import { DocumentView, DocumentViewProps } from './DocumentView'; import { FieldViewProps } from './FieldView'; import { OpenWhere } from './OpenWhere'; +export enum GroupActive { // flags for whether a view is activate because of its relationship to a group + group = 'group', // this is a group that is activated because it's on an active canvas, but is not part of some other group + child = 'child', // this is a group child that is activated because its containing group is activated + inactive = 'inactive', // this is a group child but it is not active +} /// 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 const freeFormPropsKeys = ['x', 'y', 'z', 'zIndex', 'rotation', 'opacity', 'backgroundColor', 'color', 'highlight', 'width', 'height', 'autoDim', 'transition']; @@ -274,7 +279,9 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF if (this._props.isAnyChildContentActive()) return undefined; 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; + return isGroup ? (this._props.isDocumentActive?.() ? GroupActive.group : + this._props.isGroupActive?.() ? GroupActive.child : GroupActive.inactive) : + this._props.isGroupActive?.() ? GroupActive.child : undefined; // prettier-ignore }; localRotation = () => this._props.rotation; render() { @@ -313,6 +320,6 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF } } // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function gotoFrame(doc: any, newFrame: any) { +ScriptingGlobals.add(function gotoFrame(doc: Doc, newFrame: number) { CollectionFreeFormDocumentView.gotoKeyFrame(doc, newFrame); }); diff --git a/src/client/views/nodes/ComparisonBox.scss b/src/client/views/nodes/ComparisonBox.scss index 093b9c004..08d9e6010 100644 --- a/src/client/views/nodes/ComparisonBox.scss +++ b/src/client/views/nodes/ComparisonBox.scss @@ -49,7 +49,6 @@ left: 0; height: 100%; overflow: hidden; - transition: 200ms; .beforeBox-cont { height: 100%; @@ -63,7 +62,6 @@ width: 3px; display: inline-block; background: white; - transition: 200ms; .slide-handle { position: absolute; diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index adb380f12..efaf6807a 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -30,41 +30,23 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() return FieldView.LayoutString(ComparisonBox, fieldKey); } private _disposers: (DragManager.DragDropDisposer | undefined)[] = [undefined, undefined]; + private _closeRef = React.createRef<HTMLDivElement>(); + @observable _inputValue = ''; + @observable _outputValue = ''; + @observable _loading = false; + @observable _errorMessage = ''; + @observable _outputMessage = ''; + @observable _animating = ''; + constructor(props: FieldViewProps) { super(props); makeObservable(this); } - @observable inputValue = ''; - @observable outputValue = ''; - @observable loading = false; - @observable errorMessage = ''; - @observable outputMessage = ''; - - @action handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { - this.inputValue = e.target.value; - console.log(this.inputValue); - }; - - @observable _animating = ''; - - @computed get clipWidth() { - return NumCast(this.layoutDoc[this.clipWidthKey], 50); - } - get clipWidthKey() { - return '_' + this._props.fieldKey + '_clipWidth'; - } - - @computed get clipHeight() { - return NumCast(this.layoutDoc[this.clipHeightKey], 200); - } - get clipHeightKey() { - return '_' + this._props.fieldKey + '_clipHeight'; - } - componentDidMount() { this._props.setContentViewBox?.(this); } + protected createDropTarget = (ele: HTMLDivElement | null, fieldKey: string, disposerId: number) => { this._disposers[disposerId]?.(); if (ele) { @@ -72,7 +54,19 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() } }; - private internalDrop = undoable((e: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => { + @computed get revealOp() { return this.layoutDoc[`_${this.fieldKey}_revealOp`] as ('flip'|'hover'|undefined); } // prettier-ignore + @computed get clipWidth() { return NumCast(this.layoutDoc[`_${this.fieldKey}_clipWidth`], 50); } // prettier-ignore + set clipWidth(width: number) { this.layoutDoc[`_${this.fieldKey}_clipWidth`] = width; } // prettier-ignore + @computed get useAlternate() { return this.layoutDoc[`_${this.fieldKey}_usePath`] === 'alternate'; } // prettier-ignore + set useAlternate(alt: boolean) { this.layoutDoc[`_${this.fieldKey}_usePath`] = alt ? 'alternate' : undefined; } // prettier-ignore + + animateClipWidth = action((clipWidth: number, duration = 200 /* ms */) => { + this._animating = `all ${duration}ms`; // turn on clip animation transition, then turn it off at end of animation + setTimeout(action(() => { this._animating = ''; }), duration); // prettier-ignore + this.clipWidth = clipWidth; + }); + + internalDrop = undoable((e: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => { if (dropEvent.complete.docDragData) { const { droppedDocuments } = dropEvent.complete.docDragData; const added = dropEvent.complete.docDragData.moveDocument?.(droppedDocuments, this.Document, (doc: Doc | Doc[]) => this.addDoc(toList(doc).lastElement(), fieldKey)); @@ -84,45 +78,34 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() return undefined; }, 'internal drop'); - private registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => { + registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => { if (e.button !== 2) { setupMoveUpEvents( this, e, this.onPointerMove, emptyFunction, - action((moveEv, doubleTap) => { + action((clickEv, doubleTap) => { if (doubleTap) { this._isAnyChildContentActive = true; if (!this.dataDoc[this.fieldKey + '_1'] && !this.dataDoc[this.fieldKey]) this.dataDoc[this.fieldKey + '_1'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc); if (!this.dataDoc[this.fieldKey + '_2'] && !this.dataDoc[this.fieldKey + '_alternate']) this.dataDoc[this.fieldKey + '_2'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc); + // DocumentView.addViewRenderedCb(DocCast(this.dataDoc[this.fieldKey + '_1']), dv => { + // dv?.select(false); + // }); } }), - false, + true, undefined, - action(() => { - if (this._isAnyChildContentActive) return; - this._animating = 'all 200ms'; - // on click, animate slider movement to the targetWidth - this.layoutDoc[this.clipWidthKey] = (targetWidth * 100) / this._props.PanelWidth(); - // this.layoutDoc[this.clipHeightKey] = (targetWidth * 100) / this._props.PanelHeight(); - - setTimeout( - action(() => { - this._animating = ''; - }), - 200 - ); - }) + () => !this._isAnyChildContentActive && this.animateClipWidth((targetWidth * 100) / this._props.PanelWidth()) ); } }; - @action - private onPointerMove = ({ movementX }: PointerEvent) => { + onPointerMove = ({ movementX }: PointerEvent) => { const width = movementX * this.ScreenToLocalBoxXf().Scale + (this.clipWidth / 100) * this._props.PanelWidth(); - if (width && width > 5 && width < this._props.PanelWidth()) { - this.layoutDoc[this.clipWidthKey] = (width * 100) / this._props.PanelWidth(); + if (width > 5 && width < this._props.PanelWidth()) { + this.clipWidth = (width * 100) / this._props.PanelWidth(); } return false; }; @@ -180,8 +163,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() ); }; docStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => { - if (property === StyleProp.PointerEvents) return 'none'; - return this._props.styleProvider?.(doc, props, property); + switch (property) { + case StyleProp.PointerEvents: return 'none'; + default: return this._props.styleProvider?.(doc, props, property); + } // prettier-ignore }; moveDoc1 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true); moveDoc2 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true); @@ -220,36 +205,31 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() return layoutTemplateString; }; - _closeRef = React.createRef<HTMLDivElement>(); - /** * Flips a flashcard to the alternate side for the user to view. */ flipFlashcard = () => { - const usePath = this.layoutDoc[`_${this._props.fieldKey}_usePath`]; - this.layoutDoc[`_${this._props.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : undefined; + this.useAlternate = !this.useAlternate; }; /** * Changes the view option to hover for a flashcard. */ - hoverFlip = (side: string | undefined) => { - if (this.layoutDoc[`_${this._props.fieldKey}_revealOp`] === 'hover') this.layoutDoc[`_${this._props.fieldKey}_usePath`] = side; + hoverFlip = (alternate: boolean) => { + if (this.revealOp === 'hover') this.useAlternate = alternate; }; /** * Creates the button used to flip the flashcards. */ @computed get overlayAlternateIcon() { - const usepath = this.layoutDoc[`_${this._props.fieldKey}_usePath`]; return ( <Tooltip title={<div className="dash-tooltip">flip</div>}> <div className="formattedTextBox-alternateButton" onPointerDown={e => setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, () => { - console.log(this.layoutDoc[`_${this._props.fieldKey}_revealOp`]); - if (!this.layoutDoc[`_${this._props.fieldKey}_revealOp`] || this.layoutDoc[`_${this._props.fieldKey}_revealOp`] === 'flip') { + if (!this.revealOp || this.revealOp === 'flip') { this.flipFlashcard(); console.log('Print Front of cards: ' + (RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text ?? '')); console.log('Print Back of cards: ' + (RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text ?? '')); @@ -257,8 +237,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() }) } style={{ - background: usepath === 'alternate' ? 'white' : 'black', - color: usepath === 'alternate' ? 'black' : 'white', + background: this.useAlternate ? 'white' : 'black', + color: this.useAlternate ? 'black' : 'white', }}> <FontAwesomeIcon icon="turn-up" size="sm" /> </div> @@ -268,14 +248,14 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() @action handleRenderGPTClick = () => { // Call the GPT model and get the output - this.layoutDoc[`_${this._props.fieldKey}_usePath`] = 'alternate'; - this.outputValue = ''; - if (this.inputValue) this.askGPT(); + this.useAlternate = true; + this._outputValue = ''; + if (this._inputValue) this.askGPT(); }; @action handleRenderClick = () => { // Call the GPT model and get the output - this.layoutDoc[`_${this._props.fieldKey}_usePath`] = undefined; + this.useAlternate = false; }; /** @@ -285,7 +265,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() askGPT = async (): Promise<string | undefined> => { const questionText = 'Question: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text); const rubricText = ' Rubric: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text); - const queryText = questionText + ' UserAnswer: ' + this.inputValue + '. ' + rubricText; + const queryText = questionText + ' UserAnswer: ' + this._inputValue + '. ' + rubricText; try { const res = await gptAPICall(queryText, GPTCallType.QUIZ); @@ -293,8 +273,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() console.error('GPT call failed'); return; } - this.outputValue = res; - console.log(res); + this._outputValue = res; } catch (err) { console.error('GPT call failed'); } @@ -355,7 +334,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() ); if (this.Document._layout_isFlashcard) { - const side = this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 1 : 0; + const side = this.useAlternate ? 1 : 0; // add text box to each side when comparison box is first created if (!(this.dataDoc[this.fieldKey + '_0'] || this.dataDoc[this.fieldKey + '_0'] === 'empty')) { @@ -383,17 +362,19 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {/* {StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text)} */} <div className="input-box"> <textarea - value={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? this.outputValue : this.inputValue} - onChange={this.handleInputChange} - readOnly={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate'} + value={this.useAlternate ? this._outputValue : this._inputValue} + onChange={action(e => { + this._inputValue = e.target.value; + })} + readOnly={this.useAlternate} /> </div> - <div className="submit-button" style={{ display: this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 'none' : 'flex' }}> + <div className="submit-button" style={{ display: this.useAlternate ? 'none' : 'flex' }}> <button type="button" onClick={this.handleRenderGPTClick}> Submit </button> </div> - <div className="submit-button" style={{ display: this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 'flex' : 'none' }}> + <div className="submit-button" style={{ display: this.useAlternate ? 'flex' : 'none' }}> <button type="button" onClick={this.handleRenderClick}> Edit Your Response </button> @@ -407,12 +388,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() <div className={`comparisonBox${this._props.isContentActive() ? '-interactive' : ''}`} /* change className to easily disable/enable pointer events in CSS */ style={{ display: 'flex', flexDirection: 'column' }} - onMouseEnter={() => { - this.hoverFlip('alternate'); - }} - onMouseLeave={() => { - this.hoverFlip(undefined); - }}> + onMouseEnter={() => this.hoverFlip(true)} + onMouseLeave={() => this.hoverFlip(false)}> {displayBox(`${this.fieldKey}_${side === 0 ? 1 : 0}`, side, this._props.PanelWidth() - 3)} {this.overlayAlternateIcon} </div> @@ -430,9 +407,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() className="slide-bar" style={{ left: `calc(${this.clipWidth + '%'} - 0.5px)`, + transition: this._animating, cursor: this.clipWidth < 5 ? 'e-resize' : this.clipWidth / 100 > (this._props.PanelWidth() - 5) / this._props.PanelWidth() ? 'w-resize' : undefined, }} - onPointerDown={e => !this._isAnyChildContentActive && this.registerSliding(e, this._props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */ + onPointerDown={e => this.registerSliding(e, this._props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */ > <div className="slide-handle" /> </div> diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index a1deb1625..d2e82284e 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -18,6 +18,7 @@ import { DocumentView } from '../../DocumentView'; import { DataVizView } from '../DataVizBox'; import './Chart.scss'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const { DATA_VIZ_TABLE_ROW_HEIGHT } = require('../../../global/globalCssVariables.module.scss'); // prettier-ignore interface TableBoxProps { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7a1f94948..ce7cfa5f4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -43,6 +43,7 @@ import { ObserverJsxParser } from '../ObservableReactComponent'; import { PinProps } from '../PinFuncs'; import { StyleProp } from '../StyleProp'; import { ViewBoxInterface } from '../ViewBoxInterface'; +import { GroupActive } from './CollectionFreeFormDocumentView'; import { DocumentContentsView } from './DocumentContentsView'; import { DocumentLinksButton } from './DocumentLinksButton'; import './DocumentView.scss'; @@ -52,7 +53,7 @@ import { OpenWhere, OpenWhereMod } from './OpenWhere'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; import { PresEffect, PresEffectDirection } from './trails/PresEnums'; import SpringAnimation from './trails/SlideEffect'; -import { SpringSettings, SpringType, springMappings } from './trails/SpringUtils'; +import { SpringType, springMappings } from './trails/SpringUtils'; interface Window { MediaRecorder: MediaRecorder; @@ -153,7 +154,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document @computed get disableClickScriptFunc() { const onScriptDisable = this._props.onClickScriptDisable ?? this._componentView?.onClickScriptDisable?.() ?? this.layoutDoc.onClickScriptDisable; - return (DocumentView.LongPress || + return (SnappingManager.LongPress || onScriptDisable === 'always' || (onScriptDisable !== 'never' && (this.rootSelected() || this._componentView?.isAnyChildContentActive?.()))); // prettier-ignore } @@ -297,17 +298,15 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document e.stopPropagation(); }; onClick = action((e: React.MouseEvent | React.PointerEvent) => { - if (this._props.isGroupActive?.() === 'child' && !this._props.isDocumentActive?.()) return; - const documentView = this._docView; - if (documentView && !this.Document.ignoreClick && this._props.renderDepth >= 0 && ClientUtils.isClick(e.clientX, e.clientY, this._downX, this._downY, this._downTime)) { + if (this._props.isGroupActive?.() === GroupActive.child && !this._props.isDocumentActive?.()) return; + if (this._docView && !this.Document.ignoreClick && this._props.renderDepth >= 0 && ClientUtils.isClick(e.clientX, e.clientY, this._downX, this._downY, this._downTime)) { let stopPropagate = true; let preventDefault = true; - !this.layoutDoc._keepZWhenDragged && this._props.bringToFront?.(this.Document); const scriptProps = { this: this.Document, _readOnly_: false, scriptContext: this._props.scriptContext, - documentView, + documentView: this._docView, clientX: e.clientX, clientY: e.clientY, shiftKey: e.shiftKey, @@ -317,44 +316,39 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document }; if (this._doubleTap) { const defaultDblclick = this._props.defaultDoubleClick?.() || this.Document.defaultDoubleClick; - if (this.onDoubleClickHdlr?.script) { - UndoManager.RunInBatch(() => this.onDoubleClickHdlr.script.run(scriptProps, console.log).result?.select && this._props.select(false), 'on double click: ' + this.Document.title); - } else if (!Doc.IsSystem(this.Document) && defaultDblclick !== 'ignore') { - UndoManager.RunInBatch(() => this._props.addDocTab(this.Document, OpenWhere.lightboxAlways), 'double tap'); - DocumentView.DeselectAll(); - Doc.UnBrushDoc(this.Document); - } else { - this._singleClickFunc?.(); - } + undoable(() => { + if (this.onDoubleClickHdlr?.script) { + this.onDoubleClickHdlr.script.run(scriptProps, console.log).result?.select && this._props.select(false); + } else if (!Doc.IsSystem(this.Document) && defaultDblclick !== 'ignore') { + this._props.addDocTab(this.Document, OpenWhere.lightboxAlways); + DocumentView.DeselectAll(); + Doc.UnBrushDoc(this.Document); + } else this._singleClickFunc?.(); + }, 'on double click: ' + this.Document.title)(); this._doubleClickTimeout && clearTimeout(this._doubleClickTimeout); this._doubleClickTimeout = undefined; this._singleClickFunc = undefined; } else { - let clickFunc: undefined | (() => any); - if (!this.disableClickScriptFunc && this.onClickHdlr?.script) { - clickFunc = undoable(() => { - this.onClickHdlr?.script.run(scriptProps, console.log).result?.select && this._props.select(false); - }, 'click ' + this.Document.title); - } else { - // onDragStart implies a button doc that we don't want to select when clicking. RootDocument & isTemplateForField implies we're clicking on part of a template instance and we want to select the whole template, not the part - if (this.layoutDoc.onDragStart && !(e.ctrlKey || e.button > 0)) { - stopPropagate = false; - } - preventDefault = false; - } - const sendToBack = e.altKey ? () => documentView._props.bringToFront?.(this.Document, true) : undefined; + const sendToBack = e.altKey ? () => this._props.bringToFront?.(this.Document, true) : undefined; const selectFunc = () => { + !this.layoutDoc._keepZWhenDragged && this._props.bringToFront?.(this.Document); // selecting a view that is part of a template proxies the selection back to the root of the template const templateRoot = !(e.ctrlKey || e.button > 0) && this._props.docViewPath?.().reverse().find(dv => !dv._props.TemplateDataDocument); // prettier-ignore (templateRoot || this._docView)?.select(e.ctrlKey || e.shiftKey, e.metaKey); }; - this._singleClickFunc = clickFunc ?? sendToBack ?? selectFunc; - const waitFordblclick = this._props.waitForDoubleClickToClick?.() ?? this.Document.waitForDoubleClickToClick; - if ((clickFunc && waitFordblclick !== 'never') || waitFordblclick === 'always') { + const clickFunc = this.onClickFunc?.()?.script ? () => (this.onClickFunc?.()?.script.run(scriptProps, console.log).result as Opt<{ select: boolean }>)?.select && this._props.select(false) : undefined; + if (!clickFunc) { + // onDragStart implies a button doc that we don't want to select when clicking. RootDocument & isTemplateForField implies we're clicking on part of a template instance and we want to select the whole template, not the part + if (this.layoutDoc.onDragStart && !(e.ctrlKey || e.button > 0)) stopPropagate = false; + preventDefault = false; + } + this._singleClickFunc = undoable(clickFunc ?? sendToBack ?? selectFunc, 'click: ' + this.Document.title); + const waitForDblClick = this._props.waitForDoubleClickToClick?.() ?? this.Document.waitForDoubleClickToClick; + if ((clickFunc && waitForDblClick !== 'never') || waitForDblClick === 'always') { this._doubleClickTimeout && clearTimeout(this._doubleClickTimeout); this._doubleClickTimeout = setTimeout(this._singleClickFunc, 300); // eslint-disable-next-line no-use-before-define - } else if (!DocumentView.LongPress) { + } else if (!SnappingManager.LongPress) { this._singleClickFunc(); this._singleClickFunc = undefined; } @@ -365,9 +359,9 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document }); onPointerDown = (e: React.PointerEvent): void => { - if (this._props.isGroupActive?.() === 'child' && !this._props.isDocumentActive?.()) return; + if (this._props.isGroupActive?.() === GroupActive.child && !this._props.isDocumentActive?.()) return; // eslint-disable-next-line no-use-before-define - this._longPressSelector = setTimeout(() => DocumentView.LongPress && this._props.select(false), 1000); + this._longPressSelector = setTimeout(() => SnappingManager.LongPress && this._props.select(false), 1000); if (!DocumentView.DownDocView) DocumentView.DownDocView = this._docView; this._downX = e.clientX; @@ -418,7 +412,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document if (!this.isContentActive()) this._lastTap = Date.now(); // don't want to process the start of a double tap if the doucment is selected } // eslint-disable-next-line no-use-before-define - if (DocumentView.LongPress) e.preventDefault(); + if (SnappingManager.LongPress) e.preventDefault(); }; toggleFollowLink = undoable((): void => { @@ -975,8 +969,8 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document * @returns a function that will wrap a JSX animation element wrapping any JSX element */ public static AnimationEffect(renderDoc: JSX.Element, presEffectDoc: Opt<Doc>, root: Doc) { - let dir = (presEffectDoc?.presentation_effectDirection ?? presEffectDoc?.followLinkAnimDirection) as PresEffectDirection; - const transitionTime = presEffectDoc?.presentation_transition ? NumCast(presEffectDoc?.presentation_transition) : 500; + const dir = ((presEffectDoc?.presentation_effectDirection ?? presEffectDoc?.followLinkAnimDirection) || PresEffectDirection.Center) as PresEffectDirection; + const duration = Cast(presEffectDoc?.presentation_transition, 'number', Cast(presEffectDoc?.followLinkTransitionTime, 'number', null)); const effectProps = { left: dir === PresEffectDirection.Left, right: dir === PresEffectDirection.Right, @@ -984,26 +978,14 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document bottom: dir === PresEffectDirection.Bottom, opposite: true, delay: 0, - duration: Cast(presEffectDoc?.presentation_transition, 'number', Cast(presEffectDoc?.followLinkTransitionTime, 'number', null)), + duration, }; const timing = StrCast(presEffectDoc?.presentation_effectTiming); - let timingConfig: SpringSettings | undefined; - if (timing) { - timingConfig = JSON.parse(timing); - } - - if (!timingConfig) { - timingConfig = { - type: SpringType.GENTLE, - ...springMappings.gentle, - }; - } - - if (!dir) { - dir = PresEffectDirection.Center; - } - + const timingConfig = (timing ? JSON.parse(timing) : undefined) ?? { + type: SpringType.GENTLE, + ...springMappings.gentle, + }; switch (StrCast(presEffectDoc?.presentation_effect, StrCast(presEffectDoc?.followLinkAnimEffect))) { case PresEffect.Expand: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Expand} springSettings={timingConfig}>{renderDoc}</SpringAnimation> case PresEffect.Flip: return <SpringAnimation doc={root} startOpacity={0} dir={dir} presEffect={PresEffect.Flip} springSettings={timingConfig}>{renderDoc}</SpringAnimation> @@ -1085,15 +1067,16 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { finished?: (changed: boolean) => void // func called after focusing on target with flag indicating whether anything needed to be done. ) => Promise<void>; public static linkCommonAncestor: (link: Doc) => DocumentView | undefined; - // pin func + /** + * Pins a Doc to the current presentation trail. (see TabDocView for implementation) + */ public static PinDoc: (docIn: Doc | Doc[], pinProps: PinProps) => void; - // gesture - public static DownDocView: DocumentView | undefined; // the first DocView that receives a pointerdown event. used by GestureOverlay to determine the doc a gesture should apply to. - // media playing - @observable public static CurrentlyPlaying: DocumentView[] = []; + /** + * The DocumentView below the cursor at the start of a gesture (that receives the pointerDown event). Used by GestureOverlay to determine the doc a gesture should apply to. + */ + public static DownDocView: DocumentView | undefined; public get displayName() { return 'DocumentView(' + (this.Document?.title??"") + ')'; } // prettier-ignore - public ContentRef = React.createRef<HTMLDivElement>(); private _htmlOverlayEffect: Opt<Doc>; private _disposers: { [name: string]: IReactionDisposer } = {}; private _viewTimer: NodeJS.Timeout | undefined; @@ -1124,7 +1107,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { @observable private _htmlOverlayText: Opt<string> = undefined; @observable private _isHovering = false; @observable private _selected = false; - @observable public static LongPress = false; + @observable public static CurrentlyPlaying: DocumentView[] = []; // audio or video media views that are currently playing @computed private get shouldNotScale() { return (this.layout_fitWidth && !this.nativeWidth) || this.ComponentView?.isUnstyledView?.(); @@ -1471,7 +1454,6 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { {!this.Document || !this._props.PanelWidth() ? null : ( <div className="contentFittingDocumentView-previewDoc" - ref={this.ContentRef} style={{ transform: `translate(${this.centeringX}px, ${this.centeringY}px)`, width: xshift ?? `${this._props.PanelWidth() - this.Xshift * 2}px`, @@ -1568,6 +1550,56 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { } } +export function ActiveFillColor(): string { + const dv = DocumentView.Selected().lastElement() ?.Document._layout_isSvg ? DocumentView.Selected().lastElement() : undefined; + return StrCast(dv?.Document.fillColor, StrCast(ActiveInkPen()?.activeFillColor, "")); +} // prettier-ignore +export function ActiveInkPen(): Doc { return Doc.UserDoc(); } // prettier-ignore +export function ActiveInkColor(): string { return StrCast(ActiveInkPen()?.activeInkColor, 'black'); } // prettier-ignore +export function ActiveIsInkMask(): boolean { return BoolCast(ActiveInkPen()?.activeIsInkMask, false); } // prettier-ignore +export function ActiveInkHideTextLabels(): boolean { return BoolCast(ActiveInkPen().activeInkHideTextLabels, false); } // prettier-ignore +export function ActiveArrowStart(): string { return StrCast(ActiveInkPen()?.activeArrowStart, ''); } // prettier-ignore +export function ActiveArrowEnd(): string { return StrCast(ActiveInkPen()?.activeArrowEnd, ''); } // prettier-ignore +export function ActiveArrowScale(): number { return NumCast(ActiveInkPen()?.activeArrowScale, 1); } // prettier-ignore +export function ActiveDash(): string { return StrCast(ActiveInkPen()?.activeDash, '0'); } // prettier-ignore +export function ActiveInkWidth(): number { return Number(ActiveInkPen()?.activeInkWidth); } // prettier-ignore +export function ActiveInkBezierApprox(): string { return StrCast(ActiveInkPen()?.activeInkBezier); } // prettier-ignore +export function ActiveEraserWidth(): number { return Number(ActiveInkPen()?.eraserWidth); } // prettier-ignore + +export function SetActiveInkWidth(width: string): void { + !isNaN(parseInt(width)) && ActiveInkPen() && (ActiveInkPen().activeInkWidth = width); +} +export function SetActiveBezierApprox(bezier: string): void { + ActiveInkPen() && (ActiveInkPen().activeInkBezier = isNaN(parseInt(bezier)) ? '' : bezier); +} +export function SetActiveInkColor(value: string) { + ActiveInkPen() && (ActiveInkPen().activeInkColor = value); +} +export function SetActiveIsInkMask(value: boolean) { + ActiveInkPen() && (ActiveInkPen().activeIsInkMask = value); +} +export function SetActiveInkHideTextLabels(value: boolean) { + ActiveInkPen() && (ActiveInkPen().activeInkHideTextLabels = value); +} +export function SetActiveFillColor(value: string) { + ActiveInkPen() && (ActiveInkPen().activeFillColor = value); +} +export function SetActiveArrowStart(value: string) { + ActiveInkPen() && (ActiveInkPen().activeArrowStart = value); +} +export function SetActiveArrowEnd(value: string) { + ActiveInkPen() && (ActiveInkPen().activeArrowEnd = value); +} +export function SetActiveArrowScale(value: number) { + ActiveInkPen() && (ActiveInkPen().activeArrowScale = value); +} +export function SetActiveDash(dash: string): void { + !isNaN(parseInt(dash)) && ActiveInkPen() && (ActiveInkPen().activeDash = dash); +} +export function SetEraserWidth(width: number): void { + ActiveInkPen() && (ActiveInkPen().eraserWidth = width); +} + // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function DocFocusOrOpen(docIn: Doc, optionsIn?: FocusViewOptions, containingDoc?: Doc) { return DocumentView.FocusOrOpen(docIn, optionsIn, containingDoc); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index e4b3a1b9b..68c313480 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -448,6 +448,11 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }; focus = (anchor: Doc, options: FocusViewOptions) => (anchor.type === DocumentType.CONFIG ? undefined : this._ffref.current?.focus(anchor, options)); + renderedPixelDimensions = async () => { + const { nativeWidth: width, nativeHeight: height } = await Networking.PostToServer('/inspectImage', { source: this.paths[0] }); + return { width, height }; + }; + savedAnnotations = () => this._savedAnnotations; render() { TraceMobx(); diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 7a89b143b..8db68ddfe 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -655,9 +655,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { ); else { if (!PDFBox.pdfpromise.get(href)) PDFBox.pdfpromise.set(href, Pdfjs.getDocument(href).promise); - PDFBox.pdfpromise.get(href)?.then((pdf: any) => { - PDFBox.pdfcache.set(href, (this._pdf = pdf)); - }); + PDFBox.pdfpromise.get(href)?.then( + action((pdf: any) => { + PDFBox.pdfcache.set(href, (this._pdf = pdf)); + }) + ); } } return pdfView ?? this.renderTitleBox; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 8835ea5e7..da947face 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -45,6 +45,7 @@ import { LinkInfo } from './LinkDocPreview'; import { OpenWhere } from './OpenWhere'; import './WebBox.scss'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const { CreateImage } = require('./WebBoxRenderer'); @observer diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 9f2a9b8e1..5b435e44a 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -87,9 +87,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB public static LiveTextUndo: UndoManager.Batch | undefined; // undo batch when typing a new text note into a collection static _globalHighlightsCache: string = ''; static _globalHighlights = new ObservableSet<string>(['Audio Tags', 'Text from Others', 'Todo Items', 'Important Items', 'Disagree Items', 'Ignore Items']); - static _highlightStyleSheet: any = addStyleSheet(); - static _bulletStyleSheet: any = addStyleSheet(); - static _userStyleSheet: any = addStyleSheet(); + static _highlightStyleSheet = addStyleSheet(); + static _bulletStyleSheet = addStyleSheet(); + static _userStyleSheet = addStyleSheet(); static _hadSelection: boolean = false; private _selectionHTML: string | undefined; private _sidebarRef = React.createRef<SidebarAnnos>(); @@ -384,7 +384,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB } } } else { - const jsonstring = Cast(dataDoc[this.fieldKey], RichTextField)?.Data!; + const jsonstring = Cast(dataDoc[this.fieldKey], RichTextField)?.Data; if (jsonstring) { const json = JSON.parse(jsonstring); json.selection = state.toJSON().selection; @@ -1925,11 +1925,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB setHeight={this.setSidebarHeight} /> ) : ( - <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => DocumentView.SelectView(this.DocumentView?.()!, false), true)}> + <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => DocumentView.SelectView(this.DocumentView?.(), false), true)}> <ComponentTag // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} - ref={this._sidebarTagRef as any} + ref={this._sidebarTagRef} setContentView={emptyFunction} NativeWidth={returnZero} NativeHeight={returnZero} diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 2d6ed57d5..e8bcca638 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -24,18 +24,16 @@ import { FieldViewProps } from '../nodes/FieldView'; import { FocusViewOptions } from '../nodes/FocusViewOptions'; import { LinkInfo } from '../nodes/LinkDocPreview'; import { PDFBox } from '../nodes/PDFBox'; -import { ComparisonBox } from '../nodes/ComparisonBox'; import { ObservableReactComponent } from '../ObservableReactComponent'; import { StyleProp } from '../StyleProp'; import { AnchorMenu } from './AnchorMenu'; import { Annotation } from './Annotation'; import { GPTPopup } from './GPTPopup/GPTPopup'; -import { Docs } from '../../documents/Documents'; import './PDFViewer.scss'; // pdfjsLib.GlobalWorkerOptions.workerSrc = `/assets/pdf.worker.js`; // The workerSrc property shall be specified. -Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.2.67/build/pdf.worker.mjs'; +Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.4.168/build/pdf.worker.mjs'; interface IViewerProps extends FieldViewProps { pdfBox: PDFBox; @@ -58,7 +56,7 @@ interface IViewerProps extends FieldViewProps { */ @observer export class PDFViewer extends ObservableReactComponent<IViewerProps> { - static _annotationStyle: any = addStyleSheet(); + static _annotationStyle = addStyleSheet(); constructor(props: IViewerProps) { super(props); @@ -550,7 +548,8 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { if (doc instanceof Doc && property === StyleProp.PointerEvents) { if (this.inlineTextAnnotations.includes(doc) || this._props.isContentActive() === false) return 'none'; const isInk = doc.layout_isSvg && !props?.LayoutTemplateString; - return isInk ? 'visiblePainted' : 'all'; + if (isInk) return 'visiblePainted'; + //return isInk ? 'visiblePainted' : 'all'; } return this._props.styleProvider?.(doc, props, property); }; |
