From 2a313f28fcb8675223708b0657de7517a3281095 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 17 Apr 2024 12:27:21 -0400 Subject: restoring eslint - updates not complete yet --- src/client/views/ScriptBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/ScriptBox.tsx') diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx index 623201ed1..365980f33 100644 --- a/src/client/views/ScriptBox.tsx +++ b/src/client/views/ScriptBox.tsx @@ -4,7 +4,7 @@ import * as React from 'react'; import { Doc, Opt } from '../../fields/Doc'; import { ScriptField } from '../../fields/ScriptField'; import { ScriptCast } from '../../fields/Types'; -import { emptyFunction } from '../../Utils'; +import { emptyFunction } from '../../ClientUtils'; import { DragManager } from '../util/DragManager'; import { CompileScript } from '../util/Scripting'; import { EditableView } from './EditableView'; -- cgit v1.2.3-70-g09d2 From 9d69ab27de83ead3e499edc9028ba85749407a1e Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 23 Apr 2024 18:35:59 -0400 Subject: more lint cleanup --- src/client/goldenLayout.d.ts | 3 +- src/client/views/AntimodeMenu.tsx | 18 +- src/client/views/ComponentDecorations.tsx | 3 +- src/client/views/ContextMenu.tsx | 19 +- src/client/views/DocComponent.tsx | 28 +-- src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/DocumentDecorations.tsx | 24 +-- src/client/views/FilterPanel.tsx | 2 +- src/client/views/InkControlPtHandles.tsx | 33 +-- src/client/views/InkStrokeProperties.ts | 77 ++++--- src/client/views/InkTangentHandles.tsx | 13 +- src/client/views/InkingStroke.tsx | 6 +- src/client/views/KeyphraseQueryView.tsx | 26 +-- src/client/views/LightboxView.tsx | 82 ++++--- src/client/views/Main.tsx | 4 +- src/client/views/MainView.tsx | 5 +- src/client/views/MainViewModal.tsx | 5 +- src/client/views/MarqueeAnnotator.tsx | 32 +-- src/client/views/PreviewCursor.tsx | 16 +- .../views/PropertiesDocBacklinksSelector.tsx | 1 + src/client/views/PropertiesDocContextSelector.tsx | 11 +- src/client/views/PropertiesSection.tsx | 59 +++-- src/client/views/ScriptBox.tsx | 39 +++- src/debug/Repl.tsx | 18 +- src/debug/Test.tsx | 3 +- src/debug/Viewer.tsx | 40 ++-- src/extensions/ArrayExtensions.ts | 37 ---- src/extensions/Extensions.ts | 9 + src/extensions/ExtensionsTypings.ts | 9 + src/extensions/Extensions_Array.ts | 37 ++++ src/extensions/Extensions_String.ts | 16 ++ src/extensions/General/Extensions.ts | 9 - src/extensions/General/ExtensionsTypings.ts | 8 - src/extensions/StringExtensions.ts | 17 -- src/fields/DateField.ts | 4 +- src/fields/HtmlField.ts | 4 +- src/fields/IconField.ts | 2 +- src/fields/List.ts | 4 +- src/fields/Schema.ts | 17 +- src/fields/URLField.ts | 18 +- src/mobile/MobileMain.tsx | 2 +- src/pen-gestures/ndollar.ts | 238 +++++++++++---------- 42 files changed, 547 insertions(+), 453 deletions(-) delete mode 100644 src/extensions/ArrayExtensions.ts create mode 100644 src/extensions/Extensions.ts create mode 100644 src/extensions/ExtensionsTypings.ts create mode 100644 src/extensions/Extensions_Array.ts create mode 100644 src/extensions/Extensions_String.ts delete mode 100644 src/extensions/General/Extensions.ts delete mode 100644 src/extensions/General/ExtensionsTypings.ts delete mode 100644 src/extensions/StringExtensions.ts (limited to 'src/client/views/ScriptBox.tsx') diff --git a/src/client/goldenLayout.d.ts b/src/client/goldenLayout.d.ts index b50240563..26e8ba356 100644 --- a/src/client/goldenLayout.d.ts +++ b/src/client/goldenLayout.d.ts @@ -1,3 +1,2 @@ - declare const GoldenLayout: any; -export = GoldenLayout; \ No newline at end of file +export = GoldenLayout; diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index db7e64deb..b1eb730fa 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -3,6 +3,7 @@ import * as React from 'react'; import { SettingsManager } from '../util/SettingsManager'; import './AntimodeMenu.scss'; import { ObservableReactComponent } from './ObservableReactComponent'; + export interface AntimodeMenuProps {} /** @@ -76,7 +77,7 @@ export abstract class AntimodeMenu extends Observab }; @action - protected pointerLeave = (e: React.PointerEvent) => { + protected pointerLeave = () => { if (!this.Pinned && this._canFade) { this._transitionProperty = 'opacity'; this._transitionDuration = '0.5s'; @@ -87,7 +88,7 @@ export abstract class AntimodeMenu extends Observab }; @action - protected pointerEntered = (e: React.PointerEvent) => { + protected pointerEntered = () => { this._transitionProperty = 'opacity'; this._transitionDuration = '0.1s'; this._transitionDelay = ''; @@ -95,8 +96,10 @@ export abstract class AntimodeMenu extends Observab }; @action - protected togglePin = (e: React.MouseEvent) => { - runInAction(() => (this.Pinned = !this.Pinned)); + protected togglePin = () => { + runInAction(() => { + this.Pinned = !this.Pinned; + }); }; protected dragStart = (e: React.PointerEvent) => { @@ -114,8 +117,7 @@ export abstract class AntimodeMenu extends Observab @action protected dragging = (e: PointerEvent) => { - const width = this._mainCont.current!.getBoundingClientRect().width; - const height = this._mainCont.current!.getBoundingClientRect().height; + const { width, height } = this._mainCont.current!.getBoundingClientRect(); const left = e.pageX - this._offsetX; const top = e.pageY - this._offsetY; @@ -139,9 +141,7 @@ export abstract class AntimodeMenu extends Observab e.preventDefault(); }; - protected getDragger = () => { - return
; - }; + protected getDragger = () =>
; protected getElement(buttons: JSX.Element, expanded: boolean = false) { const containerClass = expanded ? 'antimodeMenu-cont expanded' : 'antimodeMenu-cont'; diff --git a/src/client/views/ComponentDecorations.tsx b/src/client/views/ComponentDecorations.tsx index ca4e5f2bc..64b8a8446 100644 --- a/src/client/views/ComponentDecorations.tsx +++ b/src/client/views/ComponentDecorations.tsx @@ -1,10 +1,11 @@ import { observer } from 'mobx-react'; +import * as React from 'react'; import { SelectionManager } from '../util/SelectionManager'; import './ComponentDecorations.scss'; -import * as React from 'react'; @observer export class ComponentDecorations extends React.Component<{ boundsTop: number; boundsLeft: number }, { value: string }> { + // eslint-disable-next-line no-use-before-define static Instance: ComponentDecorations; render() { diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 18b433a77..d784a14b8 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -1,3 +1,6 @@ +/* eslint-disable react/no-array-index-key */ +/* eslint-disable react/jsx-props-no-spreading */ +/* eslint-disable default-param-last */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, IReactionDisposer, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; @@ -147,15 +150,13 @@ export class ContextMenu extends ObservableReactComponent<{}> { @computed get filteredItems(): (OriginalMenuProps | string[])[] { const searchString = this._searchString.toLowerCase().split(' '); - const matches = (descriptions: string[]): boolean => { - return searchString.every(s => descriptions.some(desc => desc.toLowerCase().includes(s))); - }; + const matches = (descriptions: string[]) => searchString.every(s => descriptions.some(desc => desc.toLowerCase().includes(s))); const flattenItems = (items: ContextMenuProps[], groupFunc: (groupName: any) => string[]) => { let eles: (OriginalMenuProps | string[])[] = []; const leaves: OriginalMenuProps[] = []; - for (const item of items) { - const description = item.description; + items.forEach(item => { + const { description } = item; const path = groupFunc(description); if ('subitems' in item) { const children = flattenItems(item.subitems, name => [...groupFunc(description), name]); @@ -163,13 +164,10 @@ export class ContextMenu extends ObservableReactComponent<{}> { eles.push(path); eles = eles.concat(children); } - } else { - if (!matches(path)) { - continue; - } + } else if (matches(path)) { leaves.push(item); } - } + }); eles = [...leaves, ...eles]; @@ -241,6 +239,7 @@ export class ContextMenu extends ObservableReactComponent<{}> { value={this._searchString} onKeyDown={this.onKeyDown} onChange={this.onChange} + // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus /> diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index fae3610ca..fd29b1ca4 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -249,7 +249,7 @@ export function ViewBoxAnnotatableComponent

() { removeDocument(doc: Doc | Doc[], annotationKey?: string, leavePushpin?: boolean, dontAddToRemoved?: boolean): boolean { const effectiveAcl = GetEffectiveAcl(this.dataDoc); const indocs = doc instanceof Doc ? [doc] : doc; - const docs = indocs.filter(doc => [AclEdit, AclAdmin].includes(effectiveAcl) || GetEffectiveAcl(doc) === AclAdmin); + const docs = indocs.filter(fdoc => [AclEdit, AclAdmin].includes(effectiveAcl) || GetEffectiveAcl(fdoc) === AclAdmin); // docs.forEach(doc => doc.annotationOn === this.Document && Doc.SetInPlace(doc, 'annotationOn', undefined, true)); const targetDataDoc = this.Document[DocData]; // this.dataDoc; // we want to write to the template, not the actual data doc @@ -258,13 +258,13 @@ export function ViewBoxAnnotatableComponent

() { if (toRemove.length !== 0) { const recentlyClosed = this.Document !== Doc.MyRecentlyClosed ? Doc.MyRecentlyClosed : undefined; - toRemove.forEach(doc => { + toRemove.forEach(rdoc => { // leavePushpin && DocUtils.LeavePushpin(doc, annotationKey ?? this.annotationKey); - Doc.RemoveDocFromList(targetDataDoc, annotationKey ?? this.annotationKey, doc, true); - doc.embedContainer = undefined; - if (recentlyClosed && !dontAddToRemoved && doc.type !== DocumentType.LOADING) { - Doc.AddDocToList(recentlyClosed, 'data', doc, undefined, true, true); - Doc.RemoveEmbedding(doc, doc); + Doc.RemoveDocFromList(targetDataDoc, annotationKey ?? this.annotationKey, rdoc, true); + rdoc.embedContainer = undefined; + if (recentlyClosed && !dontAddToRemoved && rdoc.type !== DocumentType.LOADING) { + Doc.AddDocToList(recentlyClosed, 'data', rdoc, undefined, true, true); + Doc.RemoveEmbedding(rdoc, rdoc); } }); if (targetDataDoc.isGroup && DocListCast(targetDataDoc[annotationKey ?? this.annotationKey]).length < 2) { @@ -295,7 +295,7 @@ export function ViewBoxAnnotatableComponent

() { @action.bound addDocument = (doc: Doc | Doc[], annotationKey?: string): boolean => { const docs = doc instanceof Doc ? [doc] : doc; - if (this._props.filterAddDocument?.(docs) === false || docs.find(doc => Doc.AreProtosEqual(doc, this.Document) && Doc.LayoutField(doc) === Doc.LayoutField(this.Document))) { + if (this._props.filterAddDocument?.(docs) === false || docs.find(fdoc => Doc.AreProtosEqual(fdoc, this.Document) && Doc.LayoutField(fdoc) === Doc.LayoutField(this.Document))) { return false; } const targetDataDoc = this.Document[DocData]; // this.dataDoc; // we want to write to the template, not the actual data doc @@ -307,12 +307,12 @@ export function ViewBoxAnnotatableComponent

() { const added = docs; if (added.length) { if ([AclAugment, AclEdit, AclAdmin].includes(effectiveAcl)) { - added.forEach(doc => { - doc._dragOnlyWithinContainer = undefined; - if (annotationKey ?? this._annotationKeySuffix()) doc[DocData].annotationOn = this.Document; - else doc[DocData].annotationOn = undefined; - Doc.SetContainer(doc, this.Document); - inheritParentAcls(targetDataDoc, doc, true); + added.forEach(adoc => { + adoc._dragOnlyWithinContainer = undefined; + if (annotationKey ?? this._annotationKeySuffix()) adoc[DocData].annotationOn = this.Document; + else adoc[DocData].annotationOn = undefined; + Doc.SetContainer(adoc, this.Document); + inheritParentAcls(targetDataDoc, adoc, true); }); const annoDocs = Doc.Get(targetDataDoc, annotationKey ?? this.annotationKey, true) as List; // get the dataDoc directly ... when using templates there may be some default items already there, but we can't change them, so we copy them below (should really be some kind of inheritance since the template contents could change) diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 63b485a43..c007af6fa 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -260,7 +260,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( const targetDoc = this.view0?.Document; return !targetDoc ? null : ( Open Context Menu

}> -
setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => this.openContextMenu(e))}> +
setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => this.openContextMenu(clickEv))}>
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 009097b3b..3083b9be0 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -154,7 +154,7 @@ export class DocumentDecorations extends ObservableReactComponent { const effectiveLayoutAcl = GetEffectiveAcl(SelectionManager.Views[0].Document); if (effectiveLayoutAcl === AclAdmin || effectiveLayoutAcl === AclEdit || effectiveLayoutAcl === AclAugment) { - setupMoveUpEvents(this, e, e => this.onBackgroundMove(true, e), emptyFunction, emptyFunction); + setupMoveUpEvents(this, e, moveEv => this.onBackgroundMove(true, moveEv), emptyFunction, emptyFunction); e.stopPropagation(); } }; @@ -165,7 +165,7 @@ export class DocumentDecorations extends ObservableReactComponent this.onBackgroundMove(true, e), + moveEv => this.onBackgroundMove(true, moveEv), emptyFunction, action(() => { const selected = SelectionManager.Views.length === 1 ? SelectionManager.Docs[0] : undefined; @@ -179,7 +179,7 @@ export class DocumentDecorations extends ObservableReactComponent { - setupMoveUpEvents(this, e, e => this.onBackgroundMove(false, e), emptyFunction, emptyFunction); + setupMoveUpEvents(this, e, moveEv => this.onBackgroundMove(false, moveEv), emptyFunction, emptyFunction); e.stopPropagation(); }; @action @@ -308,10 +308,10 @@ export class DocumentDecorations extends ObservableReactComponent { + moveEv => { const [x, y] = [this.Bounds.x + 3, this.Bounds.y + 3]; const maxDist = Math.min((this.Bounds.r - this.Bounds.x) / 2, (this.Bounds.b - this.Bounds.y) / 2); - const dist = e.clientX < x && e.clientY < y ? 0 : Math.sqrt((e.clientX - x) * (e.clientX - x) + (e.clientY - y) * (e.clientY - y)); + const dist = moveEv.clientX < x && moveEv.clientY < y ? 0 : Math.sqrt((moveEv.clientX - x) * (moveEv.clientX - x) + (moveEv.clientY - y) * (moveEv.clientY - y)); SelectionManager.Docs.forEach(doc => { const docMax = Math.min(NumCast(doc.width) / 2, NumCast(doc.height) / 2); const radius = Math.min(1, dist / maxDist) * docMax; // set radius based on ratio of drag distance to half diagonal distance of bounding box @@ -358,7 +358,7 @@ export class DocumentDecorations extends ObservableReactComponent // return false to keep getting events + (moveEv: PointerEvent, down: number[], delta: number[]) => // return false to keep getting events this.setRotateCenter(seldocview, [this.rotCenter[0] + delta[0], this.rotCenter[1] + delta[1]]) as any as boolean, action(() => { this._isRotating = false; }), // upEvent action(() => { seldocview.Document._rotation_centerX = seldocview.Document._rotation_centerY = 0; }), @@ -399,9 +399,9 @@ export class DocumentDecorations extends ObservableReactComponent { - const previousPoint = { X: e.clientX, Y: e.clientY }; - const movedPoint = { X: e.clientX - delta[0], Y: e.clientY - delta[1] }; + (moveEv: PointerEvent, down: number[], delta: number[]) => { + const previousPoint = { X: moveEv.clientX, Y: moveEv.clientY }; + const movedPoint = { X: moveEv.clientX - delta[0], Y: moveEv.clientY - delta[1] }; const deltaAng = InkStrokeProperties.angleChange(movedPoint, previousPoint, rcScreen); if (selectedInk.length) { deltaAng && InkStrokeProperties.Instance.rotateInk(selectedInk, deltaAng, rcScreen); @@ -483,8 +483,8 @@ export class DocumentDecorations extends ObservableReactComponent !Doc.NativeHeight(docView.Document) && docView.toggleNativeDimensions())); - const fixedAspect = SelectionManager.Docs.some(this.hasFixedAspect); - const scaleAspect = {x:scale.x === 1 && fixedAspect ? scale.y : scale.x, y: scale.x !== 1 && fixedAspect ? scale.x : scale.y}; + const hasFixedAspect = SelectionManager.Docs.some(this.hasFixedAspect); + const scaleAspect = {x:scale.x === 1 && hasFixedAspect ? scale.y : scale.x, y: scale.x !== 1 && hasFixedAspect ? scale.x : scale.y}; SelectionManager.Views.forEach(docView => this.resizeView(docView, refPt, scaleAspect, { dragHdl, ctrlKey:e.ctrlKey })); // prettier-ignore await new Promise(res => { setTimeout(() => { res(this._interactionLock = undefined)})}); @@ -692,7 +692,7 @@ export class DocumentDecorations extends ObservableReactComponent void), click: undefined | ((e: any) => void), title: string) => ( {title}
} placement="top"> -
e.preventDefault()} onPointerDown={pointerDown ?? (e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => click!(e)))}> +
e.preventDefault()} onPointerDown={pointerDown ?? (e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => click!(clickEv)))}>
diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index be307600c..994107c01 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -301,7 +301,7 @@ export class FilterPanel extends ObservableReactComponent { } style={{ color: SettingsManager.userColor, background: SettingsManager.userBackgroundColor }} onBlur={undoable(e => Doc.setDocFilter(this.Document, facetHeader, e.currentTarget.value, !e.currentTarget.value ? 'remove' : 'match'), 'set text filter')} - onKeyDown={e => e.key === 'Enter' && undoable(e => Doc.setDocFilter(this.Document, facetHeader, e.currentTarget.value, !e.currentTarget.value ? 'remove' : 'match'), 'set text filter')(e)} + onKeyDown={e => e.key === 'Enter' && undoable(() => Doc.setDocFilter(this.Document, facetHeader, e.currentTarget.value, !e.currentTarget.value ? 'remove' : 'match'), 'set text filter')()} /> ); case 'checkbox': diff --git a/src/client/views/InkControlPtHandles.tsx b/src/client/views/InkControlPtHandles.tsx index 0358344b9..b4fe44733 100644 --- a/src/client/views/InkControlPtHandles.tsx +++ b/src/client/views/InkControlPtHandles.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import { Doc } from '../../fields/Doc'; -import { ControlPoint, InkData, PointData } from '../../fields/InkField'; +import { ControlPoint, InkData } from '../../fields/InkField'; import { List } from '../../fields/List'; import { listSpec } from '../../fields/Schema'; import { Cast } from '../../fields/Types'; @@ -14,6 +14,7 @@ import { InkingStroke } from './InkingStroke'; import { InkStrokeProperties } from './InkStrokeProperties'; import { SnappingManager } from '../util/SnappingManager'; import { ObservableReactComponent } from './ObservableReactComponent'; +import { PointData } from '../../pen-gestures/GestureTypes'; export interface InkControlProps { inkDoc: Doc; @@ -48,7 +49,7 @@ export class InkControlPtHandles extends ObservableReactComponent { - const ptFromScreen = this._props.inkView.ptFromScreen; + const { ptFromScreen } = this._props.inkView; if (ptFromScreen) { const order = controlIndex % 4; const handleIndexA = ((order === 3 ? controlIndex - 1 : controlIndex - 2) + this._props.inkCtrlPoints.length) % this._props.inkCtrlPoints.length; @@ -60,7 +61,7 @@ export class InkControlPtHandles extends ObservableReactComponent { + action((moveEv: PointerEvent, down: number[], delta: number[]) => { if (!this._props.inkView.controlUndo) this._props.inkView.controlUndo = UndoManager.StartBatch('drag ink ctrl pt'); const inkMoveEnd = ptFromScreen({ X: delta[0], Y: delta[1] }); const inkMoveStart = ptFromScreen({ X: 0, Y: 0 }); @@ -75,9 +76,9 @@ export class InkControlPtHandles extends ObservableReactComponent { + action((moveEv: PointerEvent, doubleTap: boolean | undefined) => { const equivIndex = controlIndex === 0 ? this._props.inkCtrlPoints.length - 1 : controlIndex === this._props.inkCtrlPoints.length - 1 ? 0 : controlIndex; - if (doubleTap || e.button === 2) { + if (doubleTap || moveEv.button === 2) { if (!brokenIndices?.includes(equivIndex) && !brokenIndices?.includes(controlIndex)) { if (brokenIndices) brokenIndices.push(controlIndex); else this._props.inkDoc.brokenInkIndices = new List([controlIndex]); @@ -128,7 +129,9 @@ export class InkControlPtHandles extends ObservableReactComponent (InkStrokeProperties.Instance._currentPoint = i); + changeCurrPoint = (i: number) => { + InkStrokeProperties.Instance._currentPoint = i; + }; render() { // Accessing the current ink's data and extracting all control points. @@ -176,7 +179,7 @@ export class InkControlPtHandles extends ObservableReactComponent - {!nearestScreenPt ? null : } + {!nearestScreenPt ? null : } {sreenCtrlPoints.map(control => hdl(control, this._overControl !== control.I ? 1 : 3 / 2, Colors.WHITE))} ); @@ -207,21 +210,21 @@ export class InkEndPtHandles extends ObservableReactComponent { setupMoveUpEvents( this, e, - action(e => { + action(moveEv => { if (this._throttle++ % 2 !== 0) return false; if (!this._props.inkView.controlUndo) this._props.inkView.controlUndo = UndoManager.StartBatch('stretch ink'); // compute stretch factor by finding scaling along axis between start and end points const p1 = pt1(); const p2 = pt2(); const v1 = { X: p1.X - p2.X, Y: p1.Y - p2.Y }; - const v2 = { X: e.clientX - p2.X, Y: e.clientY - p2.Y }; + const v2 = { X: moveEv.clientX - p2.X, Y: moveEv.clientY - p2.Y }; const v1len = Math.sqrt(v1.X * v1.X + v1.Y * v1.Y); const v2len = Math.sqrt(v2.X * v2.X + v2.Y * v2.Y); const scaling = v2len / v1len; const v1n = { X: v1.X / v1len, Y: v1.Y / v1len }; const v2n = { X: v2.X / v2len, Y: v2.Y / v2len }; const angle = Math.acos(v1n.X * v2n.X + v1n.Y * v2n.Y) * Math.sign(v1.X * v2.Y - v2.X * v1.Y); - InkStrokeProperties.Instance.stretchInk(SelectionManager.Views, scaling, p2, v1n, e.shiftKey); + InkStrokeProperties.Instance.stretchInk(SelectionManager.Views, scaling, p2, v1n, moveEv.shiftKey); InkStrokeProperties.Instance.rotateInk(SelectionManager.Views, angle, pt2()); // bcz: call pt2() func here because pt2 will have changed from previous stretchInk call return false; }), @@ -243,10 +246,14 @@ export class InkEndPtHandles extends ObservableReactComponent { cy={pt?.Y} r={this._props.screenSpaceLineWidth * 2} fill={this._overStart ? '#aaaaaa' : '#99999977'} - stroke={'#00007777'} + stroke="#00007777" strokeWidth={0} - onPointerLeave={action(() => (this._overStart = false))} - onPointerEnter={action(() => (this._overStart = true))} + onPointerLeave={action(() => { + this._overStart = false; + })} + onPointerEnter={action(() => { + this._overStart = true; + })} onPointerDown={dragFunc} pointerEvents="all" /> diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index 52ea89cde..b3f9f9ea7 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -1,20 +1,22 @@ import { Bezier } from 'bezier-js'; +import * as _ from 'lodash'; import { action, makeObservable, observable, reaction, runInAction } from 'mobx'; import { Doc, NumListCast, Opt } from '../../fields/Doc'; -import { InkData, InkField, InkTool, PointData } from '../../fields/InkField'; +import { InkData, InkField, InkTool } from '../../fields/InkField'; import { List } from '../../fields/List'; import { listSpec } from '../../fields/Schema'; import { Cast, NumCast } from '../../fields/Types'; +import { PointData } from '../../pen-gestures/GestureTypes'; import { Point } from '../../pen-gestures/ndollar'; import { DocumentType } from '../documents/DocumentTypes'; -import { FitOneCurve } from '../util/bezierFit'; import { DocumentManager } from '../util/DocumentManager'; import { undoBatch } from '../util/UndoManager'; +import { FitOneCurve } from '../util/bezierFit'; import { InkingStroke } from './InkingStroke'; import { DocumentView } from './nodes/DocumentView'; -import * as _ from 'lodash'; export class InkStrokeProperties { + // eslint-disable-next-line no-use-before-define static _Instance: InkStrokeProperties | undefined; public static get Instance() { return this._Instance || new InkStrokeProperties(); @@ -28,11 +30,15 @@ export class InkStrokeProperties { makeObservable(this); reaction( () => this._controlButton, - button => button && (Doc.ActiveTool = InkTool.None) + button => { + button && (Doc.ActiveTool = InkTool.None); + } ); reaction( () => Doc.ActiveTool, - tool => tool !== InkTool.None && (this._controlButton = false) + tool => { + tool !== InkTool.None && (this._controlButton = false); + } ); } @@ -46,7 +52,7 @@ export class InkStrokeProperties { func: (view: DocumentView, ink: InkData, ptsXscale: number, ptsYscale: number, inkStrokeWidth: number) => { X: number; Y: number }[] | undefined, requireCurrPoint: boolean = false ) => { - var appliedFunc = false; + let appliedFunc = false; (strokes instanceof DocumentView ? [strokes] : strokes)?.forEach( action(inkView => { if (!requireCurrPoint || this._currentPoint !== -1) { @@ -85,7 +91,7 @@ export class InkStrokeProperties { */ @undoBatch addPoints = (inkView: DocumentView, t: number, i: number, controls: { X: number; Y: number }[]) => { - this.applyFunction(inkView, (view: DocumentView, ink: InkData) => { + this.applyFunction(inkView, (view: DocumentView /* , ink: InkData */) => { const doc = view.Document; const array = [controls[i], controls[i + 1], controls[i + 2], controls[i + 3]]; const newsegs = new Bezier(array.map(p => ({ x: p.X, y: p.Y }))).split(t); @@ -94,7 +100,9 @@ export class InkStrokeProperties { // Updating the indices of the control points whose handle tangency has been broken. doc.brokenInkIndices = new List(Cast(doc.brokenInkIndices, listSpec('number'), []).map(control => (control > i ? control + 4 : control))); - runInAction(() => (this._currentPoint = -1)); + runInAction(() => { + this._currentPoint = -1; + }); return controls; }); @@ -126,8 +134,8 @@ export class InkStrokeProperties { */ getNewHandlePoints = (C: PointData[], D: PointData[], newControl: PointData) => { const [m, n] = [C.length, D.length]; - let handleSizeA = Math.sqrt(Math.pow(newControl.X - C[0].X, 2) + Math.pow(newControl.Y - C[0].Y, 2)); - let handleSizeB = Math.sqrt(Math.pow(D[n - 1].X - newControl.X, 2) + Math.pow(D[n - 1].Y - newControl.Y, 2)); + let handleSizeA = Math.sqrt((newControl.X - C[0].X) ** 2 + (newControl.Y - C[0].Y) ** 2); + let handleSizeB = Math.sqrt((D[n - 1].X - newControl.X) ** 2 + (D[n - 1].Y - newControl.Y) ** 2); // Scaling adjustments to improve the ratio between the magnitudes of the two handle lines. // (Ensures that the new point added doesn't augment the inital shape of the curve much). if (handleSizeA < 75 && handleSizeB < 75) { @@ -167,13 +175,13 @@ export class InkStrokeProperties { const start = this._currentPoint === 0 ? 0 : this._currentPoint - 4; const splicedPoints = ink.slice(start, start + (this._currentPoint === 0 || this._currentPoint === ink.length - 1 ? 4 : 8)); const samples: Point[] = []; - var startDir = { x: 0, y: 0 }; - var endDir = { x: 0, y: 0 }; - for (var i = 0; i < splicedPoints.length / 4; i++) { + let startDir = { x: 0, y: 0 }; + let endDir = { x: 0, y: 0 }; + for (let i = 0; i < splicedPoints.length / 4; i++) { const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y }))); if (i === 0) startDir = bez.derivative(0); if (i === splicedPoints.length / 4 - 1) endDir = bez.derivative(1); - for (var t = 0; t < (i === splicedPoints.length / 4 - 1 ? 1 + 1e-7 : 1); t += 0.05) { + for (let t = 0; t < (i === splicedPoints.length / 4 - 1 ? 1 + 1e-7 : 1); t += 0.05) { const pt = bez.compute(t); samples.push(new Point(pt.x, pt.y)); } @@ -186,7 +194,9 @@ export class InkStrokeProperties { } } doc.brokenInkIndices = new List(brokenIndices.map(control => (control >= this._currentPoint ? control - 4 : control))); - runInAction(() => (this._currentPoint = -1)); + runInAction(() => { + this._currentPoint = -1; + }); return newPoints.length < 4 ? undefined : newPoints; }, true @@ -200,7 +210,7 @@ export class InkStrokeProperties { */ @undoBatch rotateInk = (inkStrokes: DocumentView[], angle: number, scrpt: PointData) => { - this.applyFunction(inkStrokes, (view: DocumentView, ink: InkData, xScale: number, yScale: number, inkStrokeWidth: number) => { + this.applyFunction(inkStrokes, (view: DocumentView, ink: InkData, xScale: number, yScale: number /* , inkStrokeWidth: number */) => { const inkCenterPt = view.ComponentView?.ptFromScreen?.(scrpt); return !inkCenterPt ? ink @@ -247,8 +257,8 @@ export class InkStrokeProperties { const closed = InkingStroke.IsClosed(ink); const brokenIndices = Cast(inkView.Document.brokenInkIndices, listSpec('number'), []); if (origInk && this._currentPoint > 0 && this._currentPoint < ink.length - 1 && brokenIndices.findIndex(value => value === controlIndex) === -1) { - const cpt_before = ink[controlIndex]; - const cpt = { X: cpt_before.X + deltaX, Y: cpt_before.Y + deltaY }; + const cptBefore = ink[controlIndex]; + const cpt = { X: cptBefore.X + deltaX, Y: cptBefore.Y + deltaY }; const newink = origInk.slice(); const start = this._currentPoint === 0 ? 0 : this._currentPoint - 4; const splicedPoints = origInk.slice(start, start + (this._currentPoint === 0 || this._currentPoint === ink.length - 1 ? 4 : 8)); @@ -256,28 +266,28 @@ export class InkStrokeProperties { if ((nearestSeg === 0 && nearestT < 1e-1) || (nearestSeg === 4 && 1 - nearestT < 1e-1)) return ink.slice(); const samplesLeft: Point[] = []; const samplesRight: Point[] = []; - var startDir = { x: 0, y: 0 }; - var endDir = { x: 0, y: 0 }; - for (var i = 0; i < nearestSeg / 4 + 1; i++) { + let startDir = { x: 0, y: 0 }; + let endDir = { x: 0, y: 0 }; + for (let i = 0; i < nearestSeg / 4 + 1; i++) { const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y }))); if (i === 0) startDir = bez.derivative(_.isEqual(bez.derivative(0), { x: 0, y: 0, t: 0 }) ? 1e-8 : 0); if (i === nearestSeg / 4) endDir = bez.derivative(nearestT); - for (var t = 0; t < (i === nearestSeg / 4 ? nearestT + 0.05 : 1); t += 0.05) { + for (let t = 0; t < (i === nearestSeg / 4 ? nearestT + 0.05 : 1); t += 0.05) { const pt = bez.compute(i !== nearestSeg / 4 ? t : Math.min(nearestT, t)); samplesLeft.push(new Point(pt.x, pt.y)); } } - var { finalCtrls } = FitOneCurve(samplesLeft, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y }); - for (var i = nearestSeg / 4; i < splicedPoints.length / 4; i++) { + let { finalCtrls } = FitOneCurve(samplesLeft, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y }); + for (let i = nearestSeg / 4; i < splicedPoints.length / 4; i++) { const bez = new Bezier(splicedPoints.slice(i * 4, i * 4 + 4).map(p => ({ x: p.X, y: p.Y }))); if (i === nearestSeg / 4) startDir = bez.derivative(nearestT); if (i === splicedPoints.length / 4 - 1) endDir = bez.derivative(_.isEqual(bez.derivative(1), { x: 0, y: 0, t: 1 }) ? 1 - 1e-8 : 1); - for (var t = i === nearestSeg / 4 ? nearestT : 0; t < (i === nearestSeg / 4 ? 1 + 0.05 + 1e-7 : 1 + 1e-7); t += 0.05) { + for (let t = i === nearestSeg / 4 ? nearestT : 0; t < (i === nearestSeg / 4 ? 1 + 0.05 + 1e-7 : 1 + 1e-7); t += 0.05) { const pt = bez.compute(Math.min(1, t)); samplesRight.push(new Point(pt.x, pt.y)); } } - const { finalCtrls: rightCtrls, error: errorRight } = FitOneCurve(samplesRight, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y }); + const { finalCtrls: rightCtrls /* , error: errorRight */ } = FitOneCurve(samplesRight, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y }); finalCtrls = finalCtrls.concat(rightCtrls); newink.splice(this._currentPoint - 4, 8, ...finalCtrls); return newink; @@ -307,11 +317,12 @@ export class InkStrokeProperties { }); public static nearestPtToStroke(ctrlPoints: { X: number; Y: number }[], refInkSpacePt: { X: number; Y: number }, excludeSegs?: number[]) { - var distance = Number.MAX_SAFE_INTEGER; - var nearestT = -1; - var nearestSeg = -1; - var nearestPt = { X: 0, Y: 0 }; - for (var i = 0; i < ctrlPoints.length - 3; i += 4) { + let distance = Number.MAX_SAFE_INTEGER; + let nearestT = -1; + let nearestSeg = -1; + let nearestPt = { X: 0, Y: 0 }; + for (let i = 0; i < ctrlPoints.length - 3; i += 4) { + // eslint-disable-next-line no-continue if (excludeSegs?.includes(i)) continue; const array = [ctrlPoints[i], ctrlPoints[i + 1], ctrlPoints[i + 2], ctrlPoints[i + 3]]; const point = new Bezier(array.map(p => ({ x: p.X, y: p.Y }))).project({ x: refInkSpacePt.X, y: refInkSpacePt.Y }); @@ -380,6 +391,7 @@ export class InkStrokeProperties { const snappedInkPt = doc === inkView.Document ? snapped.nearestPt : inkView.ComponentView?.ptFromScreen?.(testInkView?.ComponentView?.ptToScreen?.(snapped.nearestPt) ?? { X: 0, Y: 0 }); // convert from snapped ink coordinate system to dragged ink coordinate system by converting to/from screen space if (snappedInkPt) { + // eslint-disable-next-line no-param-reassign snapData = { nearestPt: snappedInkPt, distance: snapped.distance }; } } @@ -406,6 +418,7 @@ export class InkStrokeProperties { inkCopy[handleIndexB] = this.rotatePoint(handleB, controlPoint, angleDifference); return inkCopy; } + return undefined; }); }; @@ -430,7 +443,9 @@ export class InkStrokeProperties { const magnitudeB = Math.sqrt(vectorB.X * vectorB.X + vectorB.Y * vectorB.Y); if (magnitudeA === 0 || magnitudeB === 0) return 0; // Normalizing the vectors. + // eslint-disable-next-line no-param-reassign vectorA = { X: vectorA.X / magnitudeA, Y: vectorA.Y / magnitudeA }; + // eslint-disable-next-line no-param-reassign vectorB = { X: vectorB.X / magnitudeB, Y: vectorB.Y / magnitudeB }; return Math.acos(vectorB.X * vectorA.X + vectorB.Y * vectorA.Y); } diff --git a/src/client/views/InkTangentHandles.tsx b/src/client/views/InkTangentHandles.tsx index f3a757f19..577acc4d1 100644 --- a/src/client/views/InkTangentHandles.tsx +++ b/src/client/views/InkTangentHandles.tsx @@ -8,17 +8,16 @@ import { listSpec } from '../../fields/Schema'; import { Cast } from '../../fields/Types'; import { emptyFunction } from '../../Utils'; import { setupMoveUpEvents } from '../../ClientUtils'; -import { Transform } from '../util/Transform'; import { UndoManager } from '../util/UndoManager'; import { Colors } from './global/globalEnums'; import { InkingStroke } from './InkingStroke'; import { InkStrokeProperties } from './InkStrokeProperties'; + export interface InkHandlesProps { inkDoc: Doc; inkView: InkingStroke; screenCtrlPoints: InkData; screenSpaceLineWidth: number; - ScreenToLocalTransform: () => Transform; } @observer @@ -38,9 +37,9 @@ export class InkTangentHandles extends React.Component { setupMoveUpEvents( this, e, - action((e: PointerEvent, down: number[], delta: number[]) => { + action((moveEv: PointerEvent, down: number[], delta: number[]) => { if (!this.props.inkView.controlUndo) this.props.inkView.controlUndo = UndoManager.StartBatch('DocDecs move tangent'); - if (e.altKey) this.onBreakTangent(controlIndex); + if (moveEv.altKey) this.onBreakTangent(controlIndex); const inkMoveEnd = this.props.inkView.ptFromScreen({ X: delta[0], Y: delta[1] }); const inkMoveStart = this.props.inkView.ptFromScreen({ X: 0, Y: 0 }); this.docView && InkStrokeProperties.Instance.moveTangentHandle(this.docView, -(inkMoveEnd.X - inkMoveStart.X), -(inkMoveEnd.Y - inkMoveStart.Y), handleIndex, oppositeHandleIndex, controlIndex); @@ -101,11 +100,12 @@ export class InkTangentHandles extends React.Component { tangentLines.push({ X1: data[i].X, Y1: data[i].Y, X2: data[i + 1].X, Y2: data[i + 1].Y, X3: data[i + 3].X, Y3: data[i + 3].Y, dot1: i + 1, dot2: i + 2 }); } } - const screenSpaceLineWidth = this.props.screenSpaceLineWidth; + const { screenSpaceLineWidth } = this.props; return ( <> {tangentHandles.map((pts, i) => ( + // eslint-disable-next-line react/no-array-index-key { x2={x2} y2={y2} stroke={Colors.MEDIUM_BLUE} - strokeDasharray={'1 1'} + strokeDasharray="1 1" strokeWidth={1} display={pts.dot1 === InkStrokeProperties.Instance._currentPoint || pts.dot2 === InkStrokeProperties.Instance._currentPoint ? 'inherit' : 'none'} /> ); return ( + // eslint-disable-next-line react/no-array-index-key {tangentLine(pts.X1, pts.Y1, pts.X2, pts.Y2)} {tangentLine(pts.X2, pts.Y2, pts.X3, pts.Y3)} diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index e04daec3b..35067047b 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -144,7 +144,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() e, !isEditing ? returnFalse - : action((e: PointerEvent, down: number[], delta: number[]) => { + : action((moveEv: PointerEvent, down: number[], delta: number[]) => { if (!this.controlUndo) this.controlUndo = UndoManager.StartBatch('drag ink ctrl pt'); const inkMoveEnd = this.ptFromScreen({ X: delta[0], Y: delta[1] }); const inkMoveStart = this.ptFromScreen({ X: 0, Y: 0 }); @@ -159,7 +159,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() this.controlUndo = undefined; UndoManager.FilterBatches(['data', 'x', 'y', 'width', 'height']); }), - action((e: PointerEvent, doubleTap: boolean | undefined) => { + action((moveEv: PointerEvent, doubleTap: boolean | undefined) => { if (doubleTap) { InkStrokeProperties.Instance._controlButton = true; InkStrokeProperties.Instance._currentPoint = -1; @@ -331,7 +331,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() false )} - +
); }; diff --git a/src/client/views/KeyphraseQueryView.tsx b/src/client/views/KeyphraseQueryView.tsx index e996fc946..81f004010 100644 --- a/src/client/views/KeyphraseQueryView.tsx +++ b/src/client/views/KeyphraseQueryView.tsx @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/label-has-associated-control */ import { observer } from 'mobx-react'; import * as React from 'react'; import './KeyphraseQueryView.scss'; @@ -9,28 +10,21 @@ export interface KP_Props { @observer export class KeyphraseQueryView extends React.Component { - constructor(props: KP_Props) { - super(props); - } - render() { - const kps = this.props.keyphrases.toString(); const keyterms = this.props.keyphrases.split(','); return (
Select queries to send:
- {keyterms.map((kp: string) => { - //return (

{"-" + kp}

); - return ( -

- -

- ); - })} + {keyterms.map((kp: string) => ( + // return (

{"-" + kp}

); +

+ +

+ ))}
); diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index c34554b56..24433cd01 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -1,3 +1,6 @@ +/* eslint-disable no-use-before-define */ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Toggle, ToggleType, Type } from 'browndash-components'; @@ -43,6 +46,7 @@ export class LightboxView extends ObservableReactComponent { */ public static Contains(view?:DocumentView) { return view && LightboxView.Instance?._docView && (view.containerViewPath?.() ?? []).concat(view).includes(LightboxView.Instance?._docView); } // prettier-ignore public static get LightboxDoc() { return LightboxView.Instance?._doc; } // prettier-ignore + // eslint-disable-next-line no-use-before-define static Instance: LightboxView; private _path: { doc: Opt; // @@ -72,11 +76,18 @@ export class LightboxView extends ObservableReactComponent { @action public SetLightboxDoc(doc: Opt, target?: Doc, future?: Doc[], layoutTemplate?: Doc | string) { const lightDoc = this._doc; - lightDoc && lightDoc !== doc && savedKeys.forEach(key => (lightDoc[key] = this._savedState[key])); + lightDoc && + lightDoc !== doc && + savedKeys.forEach(key => { + lightDoc[key] = this._savedState[key]; + }); this._savedState = {}; if (doc) { - lightDoc !== doc && savedKeys.map(key => (this._savedState[key] = Doc.Get(doc, key, true))); + lightDoc !== doc && + savedKeys.forEach(key => { + this._savedState[key] = Doc.Get(doc, key, true); + }); const l = DocUtils.MakeLinkToActiveAudio(() => doc).lastElement(); l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen'); CollectionStackedTimeline.CurrentlyPlaying?.forEach(dv => dv.ComponentView?.Pause?.()); @@ -107,8 +118,9 @@ export class LightboxView extends ObservableReactComponent { return true; } - public AddDocTab = (doc: Doc, location: OpenWhere, layoutTemplate?: Doc | string) => - this.SetLightboxDoc( + public AddDocTab = (docs: Doc | Doc[], location: OpenWhere, layoutTemplate?: Doc | string) => { + const doc = (docs instanceof Doc ? [docs] : docs).lastElement(); + return this.SetLightboxDoc( doc, undefined, [...DocListCast(doc[Doc.LayoutFieldKey(doc)]), ...DocListCast(doc[Doc.LayoutFieldKey(doc) + '_annotations']).filter(anno => anno.annotationOn !== doc), ...this._future].sort( @@ -116,6 +128,7 @@ export class LightboxView extends ObservableReactComponent { ), layoutTemplate ); + }; @action next = () => { const lightDoc = this._doc; @@ -180,8 +193,12 @@ export class LightboxView extends ObservableReactComponent { this.SetLightboxDoc(undefined); } }; - toggleFitWidth = () => this._doc && (this._doc._layout_fitWidth = !this._doc._layout_fitWidth); - togglePen = () => (Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen); + toggleFitWidth = () => { + this._doc && (this._doc._layout_fitWidth = !this._doc._layout_fitWidth); + }; + togglePen = () => { + Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen; + }; toggleExplore = () => SnappingManager.SetExploreMode(!SnappingManager.ExploreMode); lightboxDoc = () => this._doc; @@ -191,33 +208,31 @@ export class LightboxView extends ObservableReactComponent { lightboxDocTemplate = () => this._layoutTemplate; future = () => this._future; - renderNavBtn = (left: Opt, bottom: Opt, top: number, icon: IconProp, display: any, click: () => void, color?: string) => { - return ( + renderNavBtn = (left: Opt, bottom: Opt, top: number, icon: IconProp, display: any, click: () => void, color?: string) => ( +
{ + e.stopPropagation(); + click(); }}> -
{ - e.stopPropagation(); - click(); - }}> -
{color}
- -
+
{color}
+
- ); - }; +
+ ); render() { - let downx = 0, - downy = 0; + let downx = 0; + let downy = 0; const toggleBtn = (classname: string, tooltip: string, toggleBackground: any, icon: IconProp, icon2: IconProp | string, onClick: () => void) => (
{ clipPath: `path('${Doc.UserDoc().renderStyle === 'comic' ? wavyBorderPath(this.lightboxWidth(), this.lightboxHeight()) : undefined}')`, background: SettingsManager.userBackgroundColor, }}> - + (this._docView = r !== null ? r : undefined))} + ref={action((r: DocumentView | null) => { + this._docView = r !== null ? r : undefined; + })} Document={this._doc} PanelWidth={this.lightboxWidth} PanelHeight={this.lightboxHeight} @@ -266,7 +283,7 @@ export class LightboxView extends ObservableReactComponent { styleProvider={DefaultStyleProvider} ScreenToLocalTransform={this.lightboxScreenToLocal} renderDepth={0} - suppressSetHeight={this._doc._layout_fitWidth ? true : false} + suppressSetHeight={!!this._doc._layout_fitWidth} containerViewPath={returnEmptyDoclist} childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} @@ -303,6 +320,7 @@ export class LightboxView extends ObservableReactComponent { } interface LightboxTourBtnProps { navBtn: (left: Opt, bottom: Opt, top: number, icon: IconProp, display: any, click: () => void, color?: string) => JSX.Element; + // eslint-disable-next-line react/no-unused-prop-types future: () => Opt; stepInto: () => void; lightboxDoc: () => Opt; diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 17c21326d..01f3b032e 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -1,3 +1,4 @@ +/* eslint-disable no-new */ // if ((module as any).hot) { // (module as any).hot.accept(); // } @@ -5,7 +6,7 @@ import * as dotenv from 'dotenv'; // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; -import { AssignAllExtensions } from '../../extensions/General/Extensions'; +import { AssignAllExtensions } from '../../extensions/Extensions'; import { FieldLoader } from '../../fields/FieldLoader'; import { CurrentUserUtils } from '../util/CurrentUserUtils'; import { PingManager } from '../util/PingManager'; @@ -15,6 +16,7 @@ import { CollectionView } from './collections/CollectionView'; import './global/globalScripts'; import { MainView } from './MainView'; import { BranchingTrailManager } from '../util/BranchingTrailManager'; + dotenv.config(); AssignAllExtensions(); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index a13fe1cb7..10d423c05 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -747,7 +747,8 @@ export class MainView extends ObservableReactComponent<{}> { sidebarScreenToLocal = () => new Transform(0, -this.topOfSidebarDoc, 1); mainContainerXf = () => this.sidebarScreenToLocal().translate(-this.leftScreenOffsetOfMainDocView, 0); - static addDocTabFunc_impl = (doc: Doc, location: OpenWhere): boolean => { + static addDocTabFunc_impl = (docs: Doc | Doc[], location: OpenWhere): boolean => { + const doc = (docs instanceof Doc ? [docs] : docs).lastElement(); const whereFields = location.split(':'); const keyValue = whereFields.includes(OpenWhereMod.keyvalue); const whereMods = whereFields.length > 1 ? (whereFields[1] as OpenWhereMod) : OpenWhereMod.none; @@ -957,7 +958,7 @@ export class MainView extends ObservableReactComponent<{}> { childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} /> - {['watching', 'recording'].includes(StrCast(this.userDoc?.presentationMode)) ?
{StrCast(this.userDoc?.presentationMode)}
: <>} + {['watching', 'recording'].includes(StrCast(this.userDoc?.presentationMode)) ?
{StrCast(this.userDoc?.presentationMode)}
: null}
); } diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx index e52562625..a6dc5c62b 100644 --- a/src/client/views/MainViewModal.tsx +++ b/src/client/views/MainViewModal.tsx @@ -1,3 +1,6 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +/* eslint-disable react/require-default-props */ import { isDark } from 'browndash-components'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -11,7 +14,6 @@ export interface MainViewOverlayProps { dialogueBoxStyle?: React.CSSProperties; overlayStyle?: React.CSSProperties; dialogueBoxDisplayedOpacity?: number; - overlayDisplayedOpacity?: number; closeOnExternalClick?: () => void; // the close method of a MainViewModal, triggered if there is a click on the overlay (closing the modal) } @@ -20,7 +22,6 @@ export class MainViewModal extends React.Component { render() { const p = this.props; const dialogueOpacity = p.dialogueBoxDisplayedOpacity || 1; - const overlayOpacity = p.overlayDisplayedOpacity || 0.4; return !p.isDisplayed ? null : (
- value.map(anno => { + savedAnnoMap.forEach((value: HTMLDivElement[]) => + value.forEach(anno => { const textRegion = new Doc(); textRegion.x = parseInt(anno.style.left ?? '0'); textRegion.y = parseInt(anno.style.top ?? '0'); @@ -131,7 +130,7 @@ export class MarqueeAnnotator extends ObservableReactComponent, addAsAnnotation?: boolean, summarize?: boolean) => { + highlight = (color: string, isLinkButton: boolean, savedAnnotations?: ObservableMap, addAsAnnotation?: boolean) => { // creates annotation documents for current highlights const effectiveAcl = GetEffectiveAcl(this.props.Document[DocData]); const annotationDoc = [AclAugment, AclSelfEdit, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color, isLinkButton, savedAnnotations); @@ -157,7 +156,7 @@ export class MarqueeAnnotator extends ObservableReactComponent { - const marqueeContainer = this.props.marqueeContainer; + const { marqueeContainer } = this.props; const containerXf = this.props.isNativeScaled ? this.props.docView().screenToContentsTransform() : this.props.docView().screenToViewTransform(); const boundingRect = marqueeContainer.getBoundingClientRect(); const center = { x: boundingRect.x + boundingRect.width / 2, y: boundingRect.y + boundingRect.height / 2 }; @@ -177,15 +176,15 @@ export class MarqueeAnnotator extends ObservableReactComponent { + AnchorMenu.Instance.OnCrop = () => { if (this.props.anchorMenuCrop) { UndoManager.RunInBatch(() => this.props.anchorMenuCrop?.(this.highlight('', true, undefined, false), true), 'cropping'); } }; - AnchorMenu.Instance.OnClick = undoable((e: PointerEvent) => this.props.anchorMenuClick?.()?.(this.highlight(this.props.highlightDragSrcColor ?? 'rgba(173, 216, 230, 0.75)', true, undefined, true)), 'make sidebar annotation'); + AnchorMenu.Instance.OnClick = undoable(() => this.props.anchorMenuClick?.()?.(this.highlight(this.props.highlightDragSrcColor ?? 'rgba(173, 216, 230, 0.75)', true, undefined, true)), 'make sidebar annotation'); AnchorMenu.Instance.OnAudio = unimplementedFunction; AnchorMenu.Instance.Highlight = (color: string) => this.highlight(color, false, undefined, true); - AnchorMenu.Instance.GetAnchor = (savedAnnotations?: ObservableMap, addAsAnnotation?: boolean) => this.highlight('rgba(173, 216, 230, 0.75)', true, savedAnnotations, true); + AnchorMenu.Instance.GetAnchor = (savedAnnotations?: ObservableMap /* , addAsAnnotation?: boolean */) => this.highlight('rgba(173, 216, 230, 0.75)', true, savedAnnotations, true); AnchorMenu.Instance.onMakeAnchor = () => AnchorMenu.Instance.GetAnchor(undefined, true); /** @@ -220,13 +219,14 @@ export class MarqueeAnnotator extends ObservableReactComponent { e.preventDefault(); e.stopPropagation(); - var cropRegion: Doc | undefined; + let cropRegion: Doc | undefined; + // eslint-disable-next-line no-return-assign const sourceAnchorCreator = () => (cropRegion = this.highlight('', true, undefined, true)); // hyperlink color - const targetCreator = (annotationOn: Doc | undefined) => this.props.anchorMenuCrop!(cropRegion, false)!; + const targetCreator = (/* annotationOn: Doc | undefined */) => this.props.anchorMenuCrop!(cropRegion, false)!; DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.docView(), sourceAnchorCreator, targetCreator), e.pageX, e.pageY, { - dragComplete: e => { - if (!e.aborted && e.linkDocument) { - const linkDocData = e.linkDocument[DocData]; + dragComplete: dragEx => { + if (!dragEx.aborted && dragEx.linkDocument) { + const linkDocData = dragEx.linkDocument[DocData]; linkDocData.link_relationship = 'cropped image'; linkDocData.title = 'crop: ' + this.props.Document.title; linkDocData.link_displayLine = false; @@ -252,7 +252,7 @@ export class MarqueeAnnotator extends ObservableReactComponent { @@ -268,7 +268,9 @@ export class MarqueeAnnotator extends ObservableReactComponent (copy.style[prop as any] = marqueeStyle[prop as any])); + ['border', 'opacity', 'top', 'left', 'width', 'height'].forEach(prop => { + copy.style[prop as any] = marqueeStyle[prop as any]; + }); copy.className = 'marqueeAnnotator-annotationBox'; copy.style.top = parseInt(marqueeStyle.top.toString().replace('px', '')) / scale + this.props.scrollTop + 'px'; copy.style.left = parseInt(marqueeStyle.left.toString().replace('px', '')) / scale + 'px'; diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 6d03034ec..fddb40624 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -13,6 +13,7 @@ import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; @observer export class PreviewCursor extends ObservableReactComponent<{}> { + // eslint-disable-next-line no-use-before-define static _instance: PreviewCursor; public static get Instance() { return PreviewCursor._instance; @@ -39,7 +40,9 @@ export class PreviewCursor extends ObservableReactComponent<{}> { paste = async (e: ClipboardEvent) => { if (this.Visible && e.clipboardData) { const newPoint = this._getTransform?.().transformPoint(this._clickPoint[0], this._clickPoint[1]); - runInAction(() => (this.Visible = false)); + runInAction(() => { + this.Visible = false; + }); // tests for URL and makes web document const re: any = /^https?:\/\//g; @@ -88,10 +91,10 @@ export class PreviewCursor extends ObservableReactComponent<{}> { UndoManager.RunInBatch(() => this._addLiveTextDoc?.(DocUtils.GetNewTextDoc('', newPoint[0], newPoint[1], 500, undefined, undefined)), 'paste'); } } - //pasting in images + // pasting in images else if (e.clipboardData.getData('text/html') !== '' && e.clipboardData.getData('text/html').includes(' { @@ -122,7 +125,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> { @action onKeyDown = (e: KeyboardEvent) => { // Mixing events between React and Native is finicky. - //if not these keys, make a textbox if preview cursor is active! + // if not these keys, make a textbox if preview cursor is active! if ( e.key !== 'Escape' && e.key !== 'Backspace' && @@ -162,7 +165,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> { } }; - //when focus is lost, this will remove the preview cursor + // when focus is lost, this will remove the preview cursor @action onBlur = (): void => { this.Visible = false; }; @@ -192,6 +195,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> { } render() { return !this._clickPoint || !this.Visible ? null : ( + // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
e?.focus()} style={{ color: lightOrDark(this.Doc?.backgroundColor ?? 'white'), transform: `translate(${this._clickPoint[0]}px, ${this._clickPoint[1]}px)` }}> I
diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx index cf5105efc..be5b7ec1f 100644 --- a/src/client/views/PropertiesDocBacklinksSelector.tsx +++ b/src/client/views/PropertiesDocBacklinksSelector.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/no-unused-prop-types */ import { action } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx index b8bbde9de..2d04f2fe3 100644 --- a/src/client/views/PropertiesDocContextSelector.tsx +++ b/src/client/views/PropertiesDocContextSelector.tsx @@ -1,7 +1,10 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +/* eslint-disable jsx-a11y/anchor-is-valid */ import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc, DocListCast } from '../../fields/Doc'; +import { Doc } from '../../fields/Doc'; import { Id } from '../../fields/FieldSymbols'; import { Cast, StrCast } from '../../fields/Types'; import { DocFocusOrOpen } from '../util/DocumentManager'; @@ -52,9 +55,9 @@ export class PropertiesDocContextSelector extends ObservableReactComponent ({ col: doc, target })); } - getOnClick = (col: Doc, target: Doc) => { + getOnClick = (clickCol: Doc) => { if (!this._props.DocView) return; - col = Doc.IsDataProto(col) ? Doc.MakeDelegate(col) : col; + const col = Doc.IsDataProto(clickCol) ? Doc.MakeDelegate(clickCol) : clickCol; DocFocusOrOpen(Doc.GetProto(this._props.DocView.Document), undefined, col); }; @@ -65,7 +68,7 @@ export class PropertiesDocContextSelector extends ObservableReactComponentContexts:

} {this._docs.map(doc => (

- this.getOnClick(doc.col, doc.target)}>{StrCast(doc.col.title)} + this.getOnClick(doc.col)}>{StrCast(doc.col.title)}

))}
diff --git a/src/client/views/PropertiesSection.tsx b/src/client/views/PropertiesSection.tsx index 3c9fa1123..f083f03b9 100644 --- a/src/client/views/PropertiesSection.tsx +++ b/src/client/views/PropertiesSection.tsx @@ -1,5 +1,8 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +/* eslint-disable react/require-default-props */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable } from 'mobx'; +import { action, computed } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { SettingsManager } from '../util/SettingsManager'; @@ -10,7 +13,6 @@ export interface PropertiesSectionProps { children?: JSX.Element | string | null; isOpen: boolean; setIsOpen: (bool: boolean) => any; - inSection?: boolean; setInSection?: (bool: boolean) => any; onDoubleClick?: () => void; } @@ -21,44 +23,35 @@ export class PropertiesSection extends React.Component { return SettingsManager.userColor; } - @computed get backgroundColor() { - return SettingsManager.userBackgroundColor; - } - @computed get variantColor() { return SettingsManager.userVariantColor; } - @observable isDouble: boolean = false; - render() { if (this.props.children === undefined || this.props.children === null) return null; - else - return ( -
this.props.setInSection && this.props.setInSection(true))} onPointerLeave={action(() => this.props.setInSection && this.props.setInSection(false))}> -
{ - this.isDouble = true; - this.props.onDoubleClick && this.props.onDoubleClick(); - this.props.setIsOpen(true); - setTimeout(() => (this.isDouble = false), 300); - })} - onClick={action(e => { - this.props.setIsOpen(!this.props.isOpen); - })} - style={{ - background: this.variantColor, - // this.props.isOpen ? this.variantColor : this.backgroundColor, - color: this.color, - }}> - {this.props.title} -
- -
+ return ( +
this.props.setInSection && this.props.setInSection(true))} onPointerLeave={action(() => this.props.setInSection && this.props.setInSection(false))}> +
{ + this.props.onDoubleClick && this.props.onDoubleClick(); + this.props.setIsOpen(true); + })} + onClick={action(() => { + this.props.setIsOpen(!this.props.isOpen); + })} + style={{ + background: this.variantColor, + // this.props.isOpen ? this.variantColor : this.backgroundColor, + color: this.color, + }}> + {this.props.title} +
+
- {!this.props.isOpen ? null :
{this.props.children}
}
- ); + {!this.props.isOpen ? null :
{this.props.children}
} +
+ ); } } diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx index 365980f33..8de359e07 100644 --- a/src/client/views/ScriptBox.tsx +++ b/src/client/views/ScriptBox.tsx @@ -1,17 +1,18 @@ +/* eslint-disable react/require-default-props */ import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { emptyFunction } from '../../Utils'; import { Doc, Opt } from '../../fields/Doc'; +import { DocData } from '../../fields/DocSymbols'; import { ScriptField } from '../../fields/ScriptField'; import { ScriptCast } from '../../fields/Types'; -import { emptyFunction } from '../../ClientUtils'; import { DragManager } from '../util/DragManager'; import { CompileScript } from '../util/Scripting'; import { EditableView } from './EditableView'; -import { DocumentIconContainer } from './nodes/DocumentIcon'; import { OverlayView } from './OverlayView'; import './ScriptBox.scss'; -import { DocData } from '../../fields/DocSymbols'; +import { DocumentIconContainer } from './nodes/DocumentIcon'; export interface ScriptBoxProps { onSave: (text: string, onError: (error: string) => void) => void; @@ -25,6 +26,7 @@ export interface ScriptBoxProps { export class ScriptBox extends React.Component { @observable private _scriptText: string; + overlayDisposer?: () => void; constructor(props: ScriptBoxProps) { super(props); @@ -42,7 +44,6 @@ export class ScriptBox extends React.Component { console.log('ScriptBox: ' + error); }; - overlayDisposer?: () => void; onFocus = () => { this.overlayDisposer?.(); this.overlayDisposer = OverlayView.Instance.addElement(, { x: 0, y: 0 }); @@ -53,21 +54,35 @@ export class ScriptBox extends React.Component { }; render() { - let onFocus: Opt<() => void> = undefined, - onBlur: Opt<() => void> = undefined; + let onFocus: Opt<() => void>; + let onBlur: Opt<() => void>; if (this.props.showDocumentIcons) { onFocus = this.onFocus; onBlur = this.onBlur; } - const params = ''} SetValue={(value: string) => (this.props.setParams?.(value.split(' ').filter(s => s !== ' ')) ? true : true)} />; + const params = ( + ''} + SetValue={(value: string) => { + this.props.setParams?.(value.split(' ').filter(s => s !== ' ')); + return true; + }} + /> + ); return (
- +