aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eslint.config.mjs67
-rw-r--r--src/ClientUtils.ts9
-rw-r--r--src/client/cognitive_services/CognitiveServices.ts15
-rw-r--r--src/client/util/Scripting.ts4
-rw-r--r--src/client/util/SettingsManager.tsx6
-rw-r--r--src/client/util/bezierFit.ts18
-rw-r--r--src/client/views/DocumentButtonBar.tsx10
-rw-r--r--src/client/views/GestureOverlay.tsx10
-rw-r--r--src/client/views/InkStrokeProperties.ts268
-rw-r--r--src/client/views/PropertiesButtons.tsx4
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx2
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx4
-rw-r--r--src/client/views/collections/TreeView.tsx6
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx22
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx12
-rw-r--r--src/client/views/pdf/Annotation.tsx1
-rw-r--r--src/client/views/pdf/PDFViewer.tsx4
-rw-r--r--src/client/views/smartdraw/AnnotationPalette.tsx20
-rw-r--r--src/client/views/smartdraw/SmartDrawHandler.tsx2
20 files changed, 256 insertions, 230 deletions
diff --git a/eslint.config.mjs b/eslint.config.mjs
index 12ad3300a..619966f20 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -1,14 +1,57 @@
-import globals from "globals";
-import pluginJs from "@eslint/js";
-import tseslint from "typescript-eslint";
-import pluginReact from "eslint-plugin-react";
-
+import pluginJs from '@eslint/js';
+import pluginReactConfig from 'eslint-plugin-react/configs/recommended.js';
+import globals from 'globals';
+import tseslint from 'typescript-eslint';
export default [
- {files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"]},
- {files: ["**/*.js"], languageOptions: {sourceType: "commonjs"}},
- {languageOptions: { globals: globals.browser }},
- pluginJs.configs.recommended,
- ...tseslint.configs.recommended,
- pluginReact.configs.flat.recommended,
-]; \ No newline at end of file
+ {
+ languageOptions: { globals: { ...globals.browser, ...globals.node } },
+ },
+ pluginJs.configs.recommended,
+ ...tseslint.configs.recommended,
+ {
+ rules: {
+ 'node/no-missing-import': 0,
+ 'no-console': 'off',
+ 'func-names': 'off',
+ 'no-process-exit': 'off',
+ 'object-shorthand': 'off',
+ 'class-methods-use-this': 'off',
+ 'single-quote': 'off',
+ 'max-classes-per-file': 0,
+
+ 'react/jsx-filename-extension': [
+ 2,
+ {
+ extensions: ['.js', '.jsx', '.ts', '.tsx'],
+ },
+ ],
+
+ 'import/prefer-default-export': 'off',
+ 'no-unused-expressions': 'off',
+ '@typescript-eslint/no-unused-expressions': 'off',
+ 'prefer-template': 'off',
+ 'no-inner-declarations': 'off',
+ 'no-plusplus': 'off',
+ 'no-multi-assign': 'off',
+ 'no-underscore-dangle': 'off',
+ 'no-nested-ternary': 'off',
+ 'lines-between-class-members': 'off',
+ 'no-shadow': 'off',
+ '@typescript-eslint/no-shadow': 'warn',
+ 'no-unused-vars': 'off',
+ '@typescript-eslint/no-unused-vars': 'error',
+ '@typescript-eslint/no-namespace': 'off',
+ 'react/destructuring-assignment': 0,
+ 'prefer-arrow-callback': 'error',
+ 'no-return-assign': 'error',
+ 'no-await-in-loop': 'error',
+ 'no-loop-func': 'error',
+ 'no-cond-assign': 'error',
+ 'no-use-before-define': 'error',
+ 'no-explicit-any': 'error',
+ 'no-restricted-globals': ['error', 'event'],
+ },
+ },
+ pluginReactConfig,
+];
diff --git a/src/ClientUtils.ts b/src/ClientUtils.ts
index dc52218c5..55801df81 100644
--- a/src/ClientUtils.ts
+++ b/src/ClientUtils.ts
@@ -82,10 +82,6 @@ export function returnEmptyFilter() {
return [] as string[];
}
-export function returnEmptyDoclist() {
- return [] as any[];
-}
-
export namespace ClientUtils {
export const CLICK_TIME = 300;
export const DRAG_THRESHOLD = 4;
@@ -449,11 +445,10 @@ export function smoothScrollHorizontal(duration: number, element: HTMLElement |
animateScroll();
}
-export function addStyleSheet(styleType: string = 'text/css') {
+export function addStyleSheet() {
const style = document.createElement('style');
- style.type = styleType;
const sheets = document.head.appendChild(style);
- return (sheets as any).sheet;
+ return sheets.sheet;
}
export function addStyleSheetRule(sheet: CSSStyleSheet | null, selector: string, css: string | { [key: string]: string }, selectorPrefix = '.') {
const propText =
diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
index 9f7701c54..3ee61cbfb 100644
--- a/src/client/cognitive_services/CognitiveServices.ts
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -46,15 +46,14 @@ export enum Confidence {
export namespace CognitiveServices {
const ExecuteQuery = async <D>(service: Service, manager: APIManager<D>, data: D): Promise<any> => {
const apiKey = process.env[service.toUpperCase()];
- if (apiKey) {
- console.log(data);
+ if (!apiKey) {
console.log(`No API key found for ${service}: ensure youe root directory has .env file with _CLIENT_${service.toUpperCase()}.`);
return undefined;
}
let results: any;
try {
- results = await manager.requester('has', manager.converter(data), service).then(json => JSON.parse(json));
+ results = await manager.requester(apiKey, manager.converter(data), service).then(json => JSON.parse(json));
} catch (e) {
throw e;
}
@@ -138,14 +137,6 @@ export namespace CognitiveServices {
points: points.map(({ X: x, Y: y }) => `${x},${y}`).join(','),
language: 'en-US',
}));
- console.log(
- JSON.stringify({
- version: 1,
- language: 'en-US',
- unit: 'mm',
- strokes,
- })
- );
return JSON.stringify({
version: 1,
language: 'en-US',
@@ -345,7 +336,7 @@ export namespace CognitiveServices {
'Ocp-Apim-Subscription-Key': apiKey,
},
};
- return request.post(options);
+ return rp.post(options);
},
};
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index cb314e3f1..c63d3d7cb 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -1,7 +1,7 @@
// export const ts = (window as any).ts;
// import * as typescriptlib from '!!raw-loader!../../../node_modules/typescript/lib/lib.d.ts'
// import * as typescriptes5 from '!!raw-loader!../../../node_modules/typescript/lib/lib.es5.d.ts'
-// import typescriptlib from 'type_decls.d';
+import typescriptlib from 'type_decls.d';
import * as ts from 'typescript';
import { Doc, FieldType } from '../../fields/Doc';
import { RefField } from '../../fields/RefField';
@@ -248,7 +248,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
const funcScript = `(function(${paramString})${reqTypes} { ${body} })`;
host.writeFile('file.ts', funcScript);
- // if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib);
+ if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib);
const program = ts.createProgram(['file.ts'], {}, host);
const testResult = program.emit();
const outputText = host.readFile('file.js');
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 9e49117a7..9200d68db 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -27,7 +27,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();
@@ -85,7 +85,7 @@ export class SettingsManager extends React.Component<{}> {
if (this._playgroundMode) {
DocServer.Control.makeReadOnly();
addStyleSheetRule(SettingsManager._settingsStyle, 'topbar-inner-container', { background: 'red !important' });
- } else ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Control.makeEditable();
+ } else if (ClientUtils.CurrentUserEmail() !== 'guest') DocServer.Control.makeEditable();
}),
'set playgorund mode'
);
@@ -121,7 +121,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/bezierFit.ts b/src/client/util/bezierFit.ts
index 693676bc3..4c7f4a0ba 100644
--- a/src/client/util/bezierFit.ts
+++ b/src/client/util/bezierFit.ts
@@ -2,7 +2,6 @@
/* eslint-disable prefer-destructuring */
/* eslint-disable no-param-reassign */
/* eslint-disable camelcase */
-import e from 'cors';
import { Point } from '../../pen-gestures/ndollar';
export enum SVGType {
@@ -628,7 +627,7 @@ export function GenerateControlPoints(coordinates: Point[], alpha = 0.1) {
export function SVGToBezier(name: SVGType, attributes: any): Point[] {
switch (name) {
- case 'line':
+ case 'line': {
const x1 = parseInt(attributes.x1);
const x2 = parseInt(attributes.x2);
const y1 = parseInt(attributes.y1);
@@ -639,8 +638,9 @@ export function SVGToBezier(name: SVGType, attributes: any): Point[] {
{ X: x2, Y: y2 },
{ X: x2, Y: y2 },
];
+ }
case 'circle':
- case 'ellipse':
+ case 'ellipse': {
const c = 0.551915024494;
const centerX = parseInt(attributes.cx);
const centerY = parseInt(attributes.cy);
@@ -664,7 +664,8 @@ export function SVGToBezier(name: SVGType, attributes: any): Point[] {
{ X: centerX - c * radiusX, Y: centerY + radiusY },
{ X: centerX, Y: centerY + radiusY },
];
- case 'rect':
+ }
+ case 'rect': {
const x = parseInt(attributes.x);
const y = parseInt(attributes.y);
const width = parseInt(attributes.width);
@@ -687,14 +688,15 @@ export function SVGToBezier(name: SVGType, attributes: any): Point[] {
{ X: x, Y: y },
{ X: x, Y: y },
];
- case 'path':
+ }
+ case 'path': {
const coordList: Point[] = [];
const startPt = attributes.d.match(/M(-?\d+\.?\d*),(-?\d+\.?\d*)/);
coordList.push({ X: parseInt(startPt[1]), Y: parseInt(startPt[2]) });
const matches: RegExpMatchArray[] = Array.from(
attributes.d.matchAll(/Q(-?\d+\.?\d*),(-?\d+\.?\d*) (-?\d+\.?\d*),(-?\d+\.?\d*)|C(-?\d+\.?\d*),(-?\d+\.?\d*) (-?\d+\.?\d*),(-?\d+\.?\d*) (-?\d+\.?\d*),(-?\d+\.?\d*)|L(-?\d+\.?\d*),(-?\d+\.?\d*)/g)
);
- let lastPt: Point;
+ let lastPt: Point = { X: 0, Y: 0 };
matches.forEach(match => {
if (match[0].startsWith('Q')) {
coordList.push({ X: parseInt(match[1]), Y: parseInt(match[2]) });
@@ -725,7 +727,8 @@ export function SVGToBezier(name: SVGType, attributes: any): Point[] {
coordList.pop();
}
return coordList;
- case 'polygon':
+ }
+ case 'polygon': {
const coords: RegExpMatchArray[] = Array.from(attributes.points.matchAll(/(-?\d+\.?\d*),(-?\d+\.?\d*)/g));
let list: Point[] = [];
coords.forEach(coord => {
@@ -737,6 +740,7 @@ export function SVGToBezier(name: SVGType, attributes: any): Point[] {
const firstPts = list.splice(0, 2);
list = list.concat(firstPts);
return list;
+ }
default:
return [];
}
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 8aa4c2093..096f058ad 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -9,7 +9,7 @@ import * as React from 'react';
import { FaEdit } from 'react-icons/fa';
import { returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../ClientUtils';
import { emptyFunction } from '../../Utils';
-import { Doc, DocListCast } from '../../fields/Doc';
+import { Doc } from '../../fields/Doc';
import { Cast, DocCast } from '../../fields/Types';
import { DocUtils, IsFollowLinkScript } from '../documents/DocUtils';
import { CalendarManager } from '../util/CalendarManager';
@@ -17,7 +17,7 @@ import { DictationManager } from '../util/DictationManager';
import { DragManager } from '../util/DragManager';
import { dropActionType } from '../util/DropActionTypes';
import { SharingManager } from '../util/SharingManager';
-import { UndoManager, undoable, undoBatch } from '../util/UndoManager';
+import { UndoManager, undoable } from '../util/UndoManager';
import './DocumentButtonBar.scss';
import { ObservableReactComponent } from './ObservableReactComponent';
import { PinProps } from './PinFuncs';
@@ -29,7 +29,6 @@ import { DocumentView } from './nodes/DocumentView';
import { OpenWhere } from './nodes/OpenWhere';
import { DashFieldView } from './nodes/formattedText/DashFieldView';
import { AnnotationPalette } from './smartdraw/AnnotationPalette';
-import { DocData } from '../../fields/DocSymbols';
@observer
export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (DocumentView | undefined)[]; stack?: unknown }> {
@@ -240,10 +239,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
);
}
- @undoBatch
- saveAnno = action(async (targetDoc: Doc) => {
- await AnnotationPalette.addToPalette(targetDoc);
- });
+ saveAnno = undoable(async (targetDoc: Doc) => await AnnotationPalette.addToPalette(targetDoc), 'save to palette');
@computed
get saveAnnoButton() {
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 63b472faf..befd19f6e 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -129,7 +129,6 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
}
@action
onPointerUp = () => {
- console.log('pointer up');
DocumentView.DownDocView = undefined;
if (this._points.length > 1) {
const B = this.svgBounds;
@@ -145,9 +144,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
else {
// need to decide when to turn gestures back on
const result = points.length > 2 && GestureUtils.GestureRecognizer.Recognize([points]);
- console.log(points);
let actionPerformed = false;
- console.log(result);
if (Doc.UserDoc().recognizeGestures && result && result.Score > 0.7) {
switch (result.Name) {
case Gestures.Line:
@@ -156,15 +153,16 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
case Gestures.Circle:
GestureOverlay.makeBezierPolygon(this._points, result.Name, true);
actionPerformed = this.dispatchGesture(result.Name);
- console.log(result.Name);
- console.log();
break;
case Gestures.Scribble:
console.log('scribble');
break;
case Gestures.RightAngle:
console.log('RightAngle');
- default:
+ break;
+ default: {
+ /* empty */
+ }
}
}
diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts
index ffda126f4..b5cd72fa7 100644
--- a/src/client/views/InkStrokeProperties.ts
+++ b/src/client/views/InkStrokeProperties.ts
@@ -9,7 +9,7 @@ import { Cast, NumCast, toList } from '../../fields/Types';
import { Gestures, PointData } from '../../pen-gestures/GestureTypes';
import { Point } from '../../pen-gestures/ndollar';
import { DocumentType } from '../documents/DocumentTypes';
-import { undoBatch } from '../util/UndoManager';
+import { undoBatch, undoable } from '../util/UndoManager';
import { FitOneCurve } from '../util/bezierFit';
import { InkingStroke } from './InkingStroke';
import { CollectionFreeFormView } from './collections/collectionFreeForm';
@@ -92,8 +92,7 @@ export class InkStrokeProperties {
* @param i index of first control point of segment being split
* @param control The list of all control points of the ink.
*/
- @undoBatch
- addPoints = (inkView: DocumentView, t: number, i: number, controls: { X: number; Y: number }[]) => {
+ addPoints = undoable((inkView: DocumentView, t: number, i: number, controls: { X: number; Y: number }[]) => {
this.applyFunction(inkView, (view: DocumentView /* , ink: InkData */) => {
const doc = view.Document;
const array = [controls[i], controls[i + 1], controls[i + 2], controls[i + 3]];
@@ -109,7 +108,7 @@ export class InkStrokeProperties {
return controls;
});
- };
+ }, 'add ink points');
/**
* Scales a handle point of a control point that is adjacent to a newly added one.
@@ -164,46 +163,48 @@ export class InkStrokeProperties {
/**
* Deletes the current control point of the selected ink instance.
*/
- @undoBatch
- deletePoints = (inkView: DocumentView, preserve: boolean) =>
- this.applyFunction(
- inkView,
- (view: DocumentView, ink: InkData) => {
- const doc = view.Document;
- const newPoints = ink.slice();
- const brokenIndices = NumListCast(doc.brokenInkIndices);
- if (preserve || this._currentPoint === 0 || this._currentPoint === ink.length - 1 || brokenIndices.includes(this._currentPoint)) {
- newPoints.splice(this._currentPoint === 0 ? 0 : this._currentPoint === ink.length - 1 ? this._currentPoint - 3 : this._currentPoint - 2, 4);
- } else {
- 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[] = [];
- 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 (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));
- }
- }
- const { finalCtrls, error } = FitOneCurve(samples, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y });
- if (error < 100) {
- newPoints.splice(this._currentPoint - 4, 8, ...finalCtrls);
+ deletePoints = undoable(
+ (inkView: DocumentView, preserve: boolean) =>
+ this.applyFunction(
+ inkView,
+ (view: DocumentView, ink: InkData) => {
+ const doc = view.Document;
+ const newPoints = ink.slice();
+ const brokenIndices = NumListCast(doc.brokenInkIndices);
+ if (preserve || this._currentPoint === 0 || this._currentPoint === ink.length - 1 || brokenIndices.includes(this._currentPoint)) {
+ newPoints.splice(this._currentPoint === 0 ? 0 : this._currentPoint === ink.length - 1 ? this._currentPoint - 3 : this._currentPoint - 2, 4);
} else {
- newPoints.splice(this._currentPoint - 2, 4);
+ 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[] = [];
+ 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 (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));
+ }
+ }
+ const { finalCtrls, error } = FitOneCurve(samples, { X: startDir.x, Y: startDir.y }, { X: endDir.x, Y: endDir.y });
+ if (error < 100) {
+ newPoints.splice(this._currentPoint - 4, 8, ...finalCtrls);
+ } else {
+ newPoints.splice(this._currentPoint - 2, 4);
+ }
}
- }
- doc.brokenInkIndices = new List(brokenIndices.map(control => (control >= this._currentPoint ? control - 4 : control)));
- runInAction(() => {
- this._currentPoint = -1;
- });
- return newPoints.length < 4 ? undefined : newPoints;
- },
- true
- );
+ doc.brokenInkIndices = new List(brokenIndices.map(control => (control >= this._currentPoint ? control - 4 : control)));
+ runInAction(() => {
+ this._currentPoint = -1;
+ });
+ return newPoints.length < 4 ? undefined : newPoints;
+ },
+ true
+ ),
+ 'delete ink points'
+ );
/**
* Rotates ink stroke(s) about a point
@@ -211,8 +212,7 @@ export class InkStrokeProperties {
* @param angle The angle at which to rotate the ink in radians.
* @param scrpt The center point of the rotation in screen coordinates
*/
- @undoBatch
- rotateInk = (inkStrokes: DocumentView[], angle: number, scrpt: PointData) => {
+ rotateInk = undoable((inkStrokes: DocumentView[], angle: number, scrpt: PointData) => {
this.applyFunction(inkStrokes, (view: DocumentView, ink: InkData, xScale: number, yScale: number /* , inkStrokeWidth: number */) => {
const inkCenterPt = view.ComponentView?.ptFromScreen?.(scrpt);
return !inkCenterPt
@@ -224,7 +224,7 @@ export class InkStrokeProperties {
return { X: newX + inkCenterPt.X, Y: newY + inkCenterPt.Y };
});
});
- };
+ }, 'rotate ink');
/**
* Rotates ink stroke(s) about a point
@@ -232,8 +232,7 @@ export class InkStrokeProperties {
* @param angle The angle at which to rotate the ink in radians.
* @param scrpt The center point of the rotation in screen coordinates
*/
- @undoBatch
- stretchInk = (inkStrokes: DocumentView[], scaling: number, scrpt: PointData, scrVec: PointData, scaleUniformly: boolean) => {
+ stretchInk = undoable((inkStrokes: DocumentView[], scaling: number, scrpt: PointData, scrVec: PointData, scaleUniformly: boolean) => {
this.applyFunction(inkStrokes, (view: DocumentView, ink: InkData) => {
const ptFromScreen = view.ComponentView?.ptFromScreen;
const ptToScreen = view.ComponentView?.ptToScreen;
@@ -247,77 +246,79 @@ export class InkStrokeProperties {
return ptFromScreen(newscrpt);
});
});
- };
+ }, 'stretch ink');
/**
* Handles the movement/scaling of a control point.
*/
- @undoBatch
- moveControlPtHandle = (inkView: DocumentView, deltaX: number, deltaY: number, controlIndex: number, origInk?: InkData) =>
- inkView &&
- this.applyFunction(inkView, (view: DocumentView, ink: InkData) => {
- const order = controlIndex % 4;
- 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 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));
- const { nearestT, nearestSeg } = InkStrokeProperties.nearestPtToStroke(splicedPoints, cpt);
- if ((nearestSeg === 0 && nearestT < 1e-1) || (nearestSeg === 4 && 1 - nearestT < 1e-1) || nearestSeg < 0) return ink.slice();
- const samplesLeft: Point[] = [];
- const samplesRight: Point[] = [];
- 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 (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));
+ moveControlPtHandle = undoable(
+ (inkView: DocumentView, deltaX: number, deltaY: number, controlIndex: number, origInk?: InkData) =>
+ inkView &&
+ this.applyFunction(inkView, (view: DocumentView, ink: InkData) => {
+ const order = controlIndex % 4;
+ 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 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));
+ const { nearestT, nearestSeg } = InkStrokeProperties.nearestPtToStroke(splicedPoints, cpt);
+ if ((nearestSeg === 0 && nearestT < 1e-1) || (nearestSeg === 4 && 1 - nearestT < 1e-1) || nearestSeg < 0) return ink.slice();
+ const samplesLeft: Point[] = [];
+ const samplesRight: Point[] = [];
+ 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 (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));
+ }
}
- }
- 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 (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));
+ 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 (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 });
+ finalCtrls = finalCtrls.concat(rightCtrls);
+ newink.splice(this._currentPoint - 4, 8, ...finalCtrls);
+ return newink;
}
- 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;
- }
- return ink.map((pt, i) => {
- const leftHandlePoint = order === 0 && i === controlIndex + 1;
- const rightHandlePoint = order === 0 && controlIndex !== 0 && i === controlIndex - 2;
- if (controlIndex === i || (order === 0 && controlIndex !== 0 && i === controlIndex - 1) || (order === 3 && i === controlIndex - 1)) {
- return { X: pt.X + deltaX, Y: pt.Y + deltaY };
- }
- if (
- controlIndex === i ||
- leftHandlePoint ||
- rightHandlePoint ||
- (order === 0 && controlIndex !== 0 && i === controlIndex - 1) ||
- ((order === 0 || order === 3) && (controlIndex === 0 || controlIndex === ink.length - 1) && (i === 1 || i === ink.length - 2) && closed) ||
- (order === 3 && i === controlIndex - 1) ||
- (order === 3 && controlIndex !== ink.length - 1 && i === controlIndex + 1) ||
- (order === 3 && controlIndex !== ink.length - 1 && i === controlIndex + 2) ||
- (ink[0].X === ink[ink.length - 1].X && ink[0].Y === ink[ink.length - 1].Y && (i === 0 || i === ink.length - 1) && (controlIndex === 0 || controlIndex === ink.length - 1))
- ) {
- return { X: pt.X + deltaX, Y: pt.Y + deltaY };
- }
- return pt;
- });
- });
+ return ink.map((pt, i) => {
+ const leftHandlePoint = order === 0 && i === controlIndex + 1;
+ const rightHandlePoint = order === 0 && controlIndex !== 0 && i === controlIndex - 2;
+ if (controlIndex === i || (order === 0 && controlIndex !== 0 && i === controlIndex - 1) || (order === 3 && i === controlIndex - 1)) {
+ return { X: pt.X + deltaX, Y: pt.Y + deltaY };
+ }
+ if (
+ controlIndex === i ||
+ leftHandlePoint ||
+ rightHandlePoint ||
+ (order === 0 && controlIndex !== 0 && i === controlIndex - 1) ||
+ ((order === 0 || order === 3) && (controlIndex === 0 || controlIndex === ink.length - 1) && (i === 1 || i === ink.length - 2) && closed) ||
+ (order === 3 && i === controlIndex - 1) ||
+ (order === 3 && controlIndex !== ink.length - 1 && i === controlIndex + 1) ||
+ (order === 3 && controlIndex !== ink.length - 1 && i === controlIndex + 2) ||
+ (ink[0].X === ink[ink.length - 1].X && ink[0].Y === ink[ink.length - 1].Y && (i === 0 || i === ink.length - 1) && (controlIndex === 0 || controlIndex === ink.length - 1))
+ ) {
+ return { X: pt.X + deltaX, Y: pt.Y + deltaY };
+ }
+ return pt;
+ });
+ }),
+ 'move ink ctrl pt'
+ );
public static nearestPtToStroke(ctrlPoints: { X: number; Y: number }[], refInkSpacePt: { X: number; Y: number }, excludeSegs?: number[]) {
let distance = Number.MAX_SAFE_INTEGER;
@@ -470,26 +471,28 @@ export class InkStrokeProperties {
/**
* Handles the movement/scaling of a handle point.
*/
- @undoBatch
- moveTangentHandle = (inkView: DocumentView, deltaX: number, deltaY: number, handleIndex: number, oppositeHandleIndex: number, controlIndex: number) =>
- this.applyFunction(inkView, (view: DocumentView, ink: InkData) => {
- const doc = view.Document;
- const closed = InkingStroke.IsClosed(ink);
- const oldHandlePoint = ink[handleIndex];
- const oppositeHandlePoint = ink[oppositeHandleIndex];
- const controlPoint = ink[controlIndex];
- const newHandlePoint = { X: ink[handleIndex].X - deltaX, Y: ink[handleIndex].Y - deltaY };
- const inkCopy = ink.slice();
- inkCopy[handleIndex] = newHandlePoint;
- const brokenIndices = Cast(doc.brokenInkIndices, listSpec('number'));
- const equivIndex = closed ? (controlIndex === 0 ? ink.length - 1 : controlIndex === ink.length - 1 ? 0 : -1) : -1;
- // Rotate opposite handle if user hasn't held 'Alt' key or not first/final control (which have only 1 handle).
- if ((!brokenIndices || (!brokenIndices?.includes(controlIndex) && !brokenIndices?.includes(equivIndex))) && (closed || (handleIndex !== 1 && handleIndex !== ink.length - 2))) {
- const angle = InkStrokeProperties.angleChange(oldHandlePoint, newHandlePoint, controlPoint);
- inkCopy[oppositeHandleIndex] = this.rotatePoint(oppositeHandlePoint, controlPoint, angle);
- }
- return inkCopy;
- });
+ moveTangentHandle = undoable(
+ (inkView: DocumentView, deltaX: number, deltaY: number, handleIndex: number, oppositeHandleIndex: number, controlIndex: number) =>
+ this.applyFunction(inkView, (view: DocumentView, ink: InkData) => {
+ const doc = view.Document;
+ const closed = InkingStroke.IsClosed(ink);
+ const oldHandlePoint = ink[handleIndex];
+ const oppositeHandlePoint = ink[oppositeHandleIndex];
+ const controlPoint = ink[controlIndex];
+ const newHandlePoint = { X: ink[handleIndex].X - deltaX, Y: ink[handleIndex].Y - deltaY };
+ const inkCopy = ink.slice();
+ inkCopy[handleIndex] = newHandlePoint;
+ const brokenIndices = Cast(doc.brokenInkIndices, listSpec('number'));
+ const equivIndex = closed ? (controlIndex === 0 ? ink.length - 1 : controlIndex === ink.length - 1 ? 0 : -1) : -1;
+ // Rotate opposite handle if user hasn't held 'Alt' key or not first/final control (which have only 1 handle).
+ if ((!brokenIndices || (!brokenIndices?.includes(controlIndex) && !brokenIndices?.includes(equivIndex))) && (closed || (handleIndex !== 1 && handleIndex !== ink.length - 2))) {
+ const angle = InkStrokeProperties.angleChange(oldHandlePoint, newHandlePoint, controlPoint);
+ inkCopy[oppositeHandleIndex] = this.rotatePoint(oppositeHandlePoint, controlPoint, angle);
+ }
+ return inkCopy;
+ }),
+ 'move ink tangent'
+ );
/**
* Function that "smooths" ink strokes by using the gesture recognizer to detect shapes and
@@ -497,8 +500,7 @@ export class InkStrokeProperties {
* @param inkDocs
* @param tolerance Determines how strong the smooth effect will be
*/
- @undoBatch
- smoothInkStrokes = (inkDocs: Doc[], tolerance: number = 5) => {
+ smoothInkStrokes = undoable((inkDocs: Doc[], tolerance: number = 5) => {
inkDocs.forEach(inkDoc => {
const inkView = DocumentView.getDocumentView(inkDoc);
const inkStroke = inkView?.ComponentView as InkingStroke;
@@ -530,5 +532,5 @@ export class InkStrokeProperties {
}
}
});
- };
+ }, 'smooth ink stroke');
}
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index b94041642..f346d4ba8 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -13,7 +13,7 @@ import { MdClosedCaption, MdClosedCaptionDisabled, MdGridOff, MdGridOn, MdSubtit
import { RxWidth } from 'react-icons/rx';
import { TbEditCircle, TbEditCircleOff, TbHandOff, TbHandStop, TbHighlight, TbHighlightOff } from 'react-icons/tb';
import { TfiBarChart } from 'react-icons/tfi';
-import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { Doc, Opt } from '../../fields/Doc';
import { DocData } from '../../fields/DocSymbols';
import { ScriptField } from '../../fields/ScriptField';
import { BoolCast, ScriptCast, StrCast } from '../../fields/Types';
@@ -28,8 +28,6 @@ import { Colors } from './global/globalEnums';
import { DocumentView } from './nodes/DocumentView';
import { OpenWhere } from './nodes/OpenWhere';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
-import { MarqueeOptionsMenu } from './collections/collectionFreeForm';
-import { InkStrokeProperties } from './InkStrokeProperties';
@observer
export class PropertiesButtons extends React.Component {
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 98ddc61f9..486c826b6 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -847,7 +847,7 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
styleProvider={this._props.styleProvider}
renderDepth={this._props.renderDepth + 1}
LayoutTemplate={undefined}
- LayoutTemplateString={LabelBox.LayoutStringWithTitle('data', this.computeTitle())}
+ LayoutTemplateString={LabelBox.LayoutString('data')}
isDocumentActive={this._props.isDocumentActive}
PanelWidth={width}
PanelHeight={height}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index a0e079158..a60cd98ac 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -50,7 +50,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
@@ -81,8 +80,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) => {
@@ -132,7 +129,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 847ff5491..015f77ffd 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -472,7 +472,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
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 = () => {
@@ -754,7 +754,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
}
get onCheckedClick() {
- return this.Document.type === DocumentType.COL ? undefined : this._props.onCheckedClick?.() ?? ScriptCast(this.Document.onCheckedClick);
+ return this.Document.type === DocumentType.COL ? undefined : (this._props.onCheckedClick?.() ?? ScriptCast(this.Document.onCheckedClick));
}
@action
@@ -779,7 +779,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
TraceMobx();
const iconType = (this.treeView._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':treeOpen' : !this.childDocs.length ? ':empty' : '')) as string) || 'question';
const color = SettingsManager.userColor;
- const checked = this.onCheckedClick ? this.Document.treeView_Checked ?? 'unchecked' : undefined;
+ const checked = this.onCheckedClick ? (this.Document.treeView_Checked ?? 'unchecked') : undefined;
return (
<div
className={`bullet${this.treeView.outlineMode ? '-outline' : ''}`}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index d95bc528d..d51b1cd3a 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -328,6 +328,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/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 3ff3f49dc..4cc7eb0ff 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -156,13 +156,13 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
/// disable pointer events on content when there's an enabled onClick script (and not in explore mode) and the contents aren't forced active, or if contents are marked inactive
@computed get _contentPointerEvents() {
TraceMobx();
- return this._props.contentPointerEvents ??
+ return (this._props.contentPointerEvents ??
((!this.disableClickScriptFunc && //
this.onClickHdlr &&
!SnappingManager.ExploreMode &&
!this.layoutDoc.layout_isSvg &&
this.isContentActive() !== true) ||
- this.isContentActive() === false)
+ this.isContentActive() === false))
? 'none'
: this._pointerEvents;
}
@@ -892,7 +892,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
const showTitle = this.showTitle?.split(':')[0];
return !DocCast(this.Document) || GetEffectiveAcl(this.dataDoc) === AclPrivate
? null
- : this.docContents ?? (
+ : (this.docContents ?? (
<div
className="documentView-node"
id={this.Document.type !== DocumentType.LINK ? this._docView?.DocUniqueId : undefined}
@@ -918,7 +918,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
)}
{this.widgetDecorations ?? null}
</div>
- );
+ ));
};
render() {
@@ -994,7 +994,7 @@ 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);
@@ -1083,13 +1083,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
+ /**
+ * 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; // the first DocView that receives a pointerdown event. used by GestureOverlay to determine the doc a gesture should apply to.
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;
@@ -1468,11 +1471,10 @@ 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`,
- height: this._props.forceAutoHeight ? undefined : yshift ?? (this.layout_fitWidth ? `${this.panelHeight}px` : `${(this.effectiveNativeHeight / this.effectiveNativeWidth) * this._props.PanelWidth()}px`),
+ height: this._props.forceAutoHeight ? undefined : (yshift ?? (this.layout_fitWidth ? `${this.panelHeight}px` : `${(this.effectiveNativeHeight / this.effectiveNativeWidth) * this._props.PanelWidth()}px`)),
}}>
<DocumentViewInternal
{...this._props}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 0c0667575..38b22fad2 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -101,9 +101,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 _oldWheel: HTMLDivElement | null = null;
private _selectionHTML: string | undefined;
@@ -361,7 +361,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;
@@ -1897,11 +1897,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/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 7dd4047c1..3bd42873c 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -111,6 +111,7 @@ export class Annotation extends ObservableReactComponent<IAnnotationProps> {
outline = () => (this.linkHighlighted ? 'solid 1px lightBlue' : undefined);
background = () => (this._props.annoDoc[Highlight] ? 'orange' : StrCast(this._props.annoDoc.backgroundColor));
render() {
+ const forceRenderHack = [this.background(), this.outline(), this.opacity()]; // forces a re-render when these change -- because RegionAnnotation doesn't do this internally..
return (
<div style={{ display: this._props.annoDoc.textCopied && !Doc.GetBrushHighlightStatus(this._props.annoDoc) ? 'none' : undefined }}>
{StrListCast(this._props.annoDoc.text_inlineAnnotations)
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 5984905d0..20719442a 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -52,7 +52,7 @@ interface IViewerProps extends FieldViewProps {
*/
@observer
export class PDFViewer extends ObservableReactComponent<IViewerProps> {
- static _annotationStyle: any = addStyleSheet();
+ static _annotationStyle = addStyleSheet();
constructor(props: IViewerProps) {
super(props);
@@ -522,7 +522,7 @@ 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 this._props.styleProvider?.(doc, props, property);
};
diff --git a/src/client/views/smartdraw/AnnotationPalette.tsx b/src/client/views/smartdraw/AnnotationPalette.tsx
index c296138a8..22b8b7b67 100644
--- a/src/client/views/smartdraw/AnnotationPalette.tsx
+++ b/src/client/views/smartdraw/AnnotationPalette.tsx
@@ -6,25 +6,25 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { AiOutlineSend } from 'react-icons/ai';
import ReactLoading from 'react-loading';
-import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../ClientUtils';
-import { Doc, DocListCast } from '../../../fields/Doc';
+import { returnEmptyFilter, returnFalse, returnTrue } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
+import { Doc, DocListCast, returnEmptyDoclist } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
+import { Copy } from '../../../fields/FieldSymbols';
import { ImageCast } from '../../../fields/Types';
-import { emptyFunction } from '../../../Utils';
+import { ImageField } from '../../../fields/URLField';
+import { DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
import { makeUserTemplateImage } from '../../util/DropConverter';
import { SettingsManager } from '../../util/SettingsManager';
import { Transform } from '../../util/Transform';
import { undoBatch } from '../../util/UndoManager';
+import { ObservableReactComponent } from '../ObservableReactComponent';
+import { DefaultStyleProvider, returnEmptyDocViewList } from '../StyleProvider';
import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
import { FieldView } from '../nodes/FieldView';
-import { ObservableReactComponent } from '../ObservableReactComponent';
-import { DefaultStyleProvider } from '../StyleProvider';
import './AnnotationPalette.scss';
import { DrawingOptions, SmartDrawHandler } from './SmartDrawHandler';
-import { DocumentType } from '../../documents/DocumentTypes';
-import { ImageField } from '../../../fields/URLField';
-import { Copy } from '../../../fields/FieldSymbols';
interface AnnotationPaletteProps {
Document: Doc;
@@ -204,7 +204,7 @@ export class AnnotationPalette extends ObservableReactComponent<AnnotationPalett
addDocument={undefined}
addDocTab={DocumentViewInternal.addDocTabFunc}
pinToPres={DocumentView.PinDoc}
- containerViewPath={returnEmptyDoclist}
+ containerViewPath={returnEmptyDocViewList}
styleProvider={DefaultStyleProvider}
removeDocument={returnFalse}
ScreenToLocalTransform={Transform.Identity}
@@ -328,7 +328,7 @@ export class AnnotationPalette extends ObservableReactComponent<AnnotationPalett
addDocument={undefined}
addDocTab={DocumentViewInternal.addDocTabFunc}
pinToPres={DocumentView.PinDoc}
- containerViewPath={returnEmptyDoclist}
+ containerViewPath={returnEmptyDocViewList}
styleProvider={DefaultStyleProvider}
removeDocument={returnFalse}
ScreenToLocalTransform={Transform.Identity}
diff --git a/src/client/views/smartdraw/SmartDrawHandler.tsx b/src/client/views/smartdraw/SmartDrawHandler.tsx
index 368970f75..4679941fb 100644
--- a/src/client/views/smartdraw/SmartDrawHandler.tsx
+++ b/src/client/views/smartdraw/SmartDrawHandler.tsx
@@ -279,7 +279,7 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> {
const svgStrokes: INode[] = svgObject.children;
const strokeData: [InkData, string, string][] = [];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
- svgStrokes.forEach((child: any) => {
+ svgStrokes.forEach((child) => {
const convertedBezier: InkData = SVGToBezier(child.name, child.attributes);
strokeData.push([
convertedBezier.map(point => {