aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ClientUtils.ts24
-rw-r--r--src/client/util/DocumentManager.ts1
-rw-r--r--src/client/views/InkingStroke.tsx17
-rw-r--r--src/client/views/StyleProvider.tsx42
-rw-r--r--src/client/views/collections/CollectionCarousel3DView.tsx10
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx7
-rw-r--r--src/client/views/collections/CollectionSubView.tsx2
-rw-r--r--src/client/views/collections/TabDocView.tsx13
-rw-r--r--src/client/views/collections/TreeView.tsx8
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx20
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx81
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx6
-rw-r--r--src/client/views/nodes/DocumentView.tsx111
-rw-r--r--src/client/views/nodes/FieldView.tsx29
-rw-r--r--src/client/views/nodes/RecordingBox/RecordingView.tsx14
-rw-r--r--src/client/views/nodes/ScreenshotBox.tsx1
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx4
17 files changed, 215 insertions, 175 deletions
diff --git a/src/ClientUtils.ts b/src/ClientUtils.ts
index 630d7edbc..fc415d589 100644
--- a/src/ClientUtils.ts
+++ b/src/ClientUtils.ts
@@ -7,11 +7,11 @@ import { CollectionViewType, DocumentType } from './client/documents/DocumentTyp
import { Colors } from './client/views/global/globalEnums';
import { CreateImage } from './client/views/nodes/WebBoxRenderer';
-export function DashColor(color: string) {
+export function DashColor(color: string | undefined) {
try {
return color ? Color(color.toLowerCase()) : Color('transparent');
} catch (e) {
- if (color.includes('gradient')) console.log("using color 'white' in place of :" + color);
+ if (color?.includes('gradient')) console.log("using color 'white' in place of :" + color);
else console.log('COLOR error:', e);
return Color('white');
}
@@ -455,7 +455,7 @@ export function addStyleSheet() {
const sheets = document.head.appendChild(style);
return sheets.sheet;
}
-export function addStyleSheetRule(sheet: CSSStyleSheet | null, selector: string, css: string | {[key:string]: string}, selectorPrefix = '.') {
+export function addStyleSheetRule(sheet: CSSStyleSheet | null, selector: string, css: string | { [key: string]: string }, selectorPrefix = '.') {
const propText =
typeof css === 'string'
? css
@@ -464,14 +464,14 @@ export function addStyleSheetRule(sheet: CSSStyleSheet | null, selector: string,
.join(';');
return sheet?.insertRule(selectorPrefix + selector + '{' + propText + '}', sheet.cssRules.length);
}
-export function removeStyleSheetRule(sheet: CSSStyleSheet|null, rule: number) {
+export function removeStyleSheetRule(sheet: CSSStyleSheet | null, rule: number) {
if (sheet?.rules.length) {
sheet.removeRule(rule);
return true;
}
return false;
}
-export function clearStyleSheetRules(sheet: CSSStyleSheet|null) {
+export function clearStyleSheetRules(sheet: CSSStyleSheet | null) {
if (sheet?.rules.length) {
numberRange(sheet.rules.length).map(() => sheet.removeRule(0));
return true;
@@ -479,10 +479,16 @@ export function clearStyleSheetRules(sheet: CSSStyleSheet|null) {
return false;
}
+export class simPointerEvent extends PointerEvent {
+ dash?: boolean;
+}
+export class simMouseEvent extends MouseEvent {
+ dash?: boolean;
+}
export function simulateMouseClick(element: Element | null | undefined, x: number, y: number, sx: number, sy: number, rightClick = true) {
if (!element) return;
['pointerdown', 'pointerup'].forEach(event => {
- const me = new PointerEvent(event, {
+ const me = new simPointerEvent(event, {
view: window,
bubbles: true,
cancelable: true,
@@ -493,12 +499,12 @@ export function simulateMouseClick(element: Element | null | undefined, x: numbe
screenX: sx,
screenY: sy,
});
- (me as any).dash = true;
+ me.dash = true;
element.dispatchEvent(me);
});
if (rightClick) {
- const me = new MouseEvent('contextmenu', {
+ const me = new simMouseEvent('contextmenu', {
view: window,
bubbles: true,
cancelable: true,
@@ -510,7 +516,7 @@ export function simulateMouseClick(element: Element | null | undefined, x: numbe
screenX: sx,
screenY: sy,
});
- (me as any).dash = true;
+ me.dash = true;
element.dispatchEvent(me);
}
}
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 96b8b5657..e41546d09 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -356,7 +356,6 @@ export class DocumentManager {
if (options.playMedia) docView.ComponentView?.playFrom?.(NumCast(docView.Document._layout_currentTimecode));
if (options.playAudio) DocumentManager.playAudioAnno(docView.Document);
if (options.toggleTarget && (!options.didMove || docView.Document.hidden)) docView.Document.hidden = !docView.Document.hidden;
- Doc.AddUnHighlightWatcher(() => docView.Document[Animation] = undefined);
}
}
}
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 55f28f415..784d252a3 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -47,6 +47,7 @@ import { FormattedTextBox, FormattedTextBoxProps } from './nodes/formattedText/F
import { PinDocView, PinProps } from './PinFuncs';
import { StyleProp } from './StyleProp';
+// eslint-disable-next-line @typescript-eslint/no-var-requires
const { INK_MASK_SIZE } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
@observer
@@ -292,7 +293,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
* @param boundsTop the screen space top coordinate of the ink stroke
* @returns the JSX controls for displaying an editing UI for the stroke (control point & tangent handles)
*/
- componentUI = (boundsLeft: number, boundsTop: number) => {
+ componentUI = (boundsLeft: number, boundsTop: number): null | JSX.Element => {
const inkDoc = this.Document;
const { inkData, inkStrokeWidth } = this.inkScaledData();
const screenSpaceCenterlineStrokeWidth = Math.min(3, inkStrokeWidth * this.ScreenToLocalBoxXf().inverse().Scale); // the width of the blue line widget that shows the centerline of the ink stroke
@@ -344,12 +345,12 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
};
@computed get fillColor(): string {
const isInkMask = BoolCast(this.layoutDoc.stroke_isInkMask);
- return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FillColor) ?? 'transparent';
+ return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : ((this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FillColor) as 'string') ?? 'transparent');
}
@computed get strokeColor() {
const { inkData } = this.inkScaledData();
const { fillColor } = this;
- return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) ?? StrCast(this.layoutDoc.color);
+ return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : ((this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as 'string') ?? StrCast(this.layoutDoc.color));
}
render() {
TraceMobx();
@@ -370,8 +371,8 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
});
}
const highlight = !this.controlUndo && this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting);
- const highlightIndex = highlight?.highlightIndex;
- const highlightColor = !this._props.isSelected() && !isInkMask && highlight?.highlightIndex ? highlight?.highlightColor : undefined;
+ const { highlightIndex, highlightColor: hColor } = (highlight as { highlightIndex?: number; highlightColor?: string }) ?? { highlightIndex: undefined, highlightColor: undefined };
+ const highlightColor = !this._props.isSelected() && !isInkMask && highlightIndex ? hColor : undefined;
const color = StrCast(this.layoutDoc.stroke_outlineColor, !closed && fillColor && fillColor !== 'transparent' ? StrCast(this.layoutDoc.color, 'transparent') : 'transparent');
// Visually renders the polygonal line made by the user.
@@ -401,12 +402,12 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
);
const higlightMargin = Math.min(12, Math.max(2, 0.3 * inkStrokeWidth));
// Invisible polygonal line that enables the ink to be selected by the user.
- const clickableLine = (downHdlr?: (e: React.PointerEvent) => void, mask: boolean = false): any =>
+ const clickableLine = (downHdlr?: (e: React.PointerEvent) => void, mask: boolean = false) =>
InteractionUtils.CreatePolyline(
inkData,
inkLeft,
inkTop,
- mask && color === 'transparent' ? this.strokeColor : highlightColor ?? color,
+ mask && color === 'transparent' ? this.strokeColor : (highlightColor ?? color),
inkStrokeWidth,
inkStrokeWidth + NumCast(this.layoutDoc.stroke_borderWidth) + (fillColor ? (closed ? higlightMargin : (highlightIndex ?? 0) + higlightMargin) : higlightMargin),
StrCast(this.layoutDoc.stroke_lineJoin),
@@ -420,7 +421,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
inkScaleX,
inkScaleY,
'',
- this._props.pointerEvents?.() ?? 'visiblepainted',
+ this._props.pointerEvents?.() ?? 'visiblePainted',
0.0,
false,
downHdlr,
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 8c100f238..8a07a6bd7 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -1,6 +1,3 @@
-/* eslint-disable jsx-a11y/alt-text */
-/* 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 { Tooltip } from '@mui/material';
@@ -24,7 +21,7 @@ import { undoBatch, UndoManager } from '../util/UndoManager';
import { TreeSort } from './collections/TreeSort';
import { Colors } from './global/globalEnums';
import { DocumentView, DocumentViewProps } from './nodes/DocumentView';
-import { FieldViewProps } from './nodes/FieldView';
+import { FieldViewProps, StyleProviderFuncType } from './nodes/FieldView';
import { StyleProp } from './StyleProp';
import './StyleProvider.scss';
@@ -43,9 +40,9 @@ function togglePaintView(e: React.MouseEvent, doc: Opt<Doc>, props: Opt<FieldVie
}
export function styleFromLayoutString(doc: Doc, props: FieldViewProps, scale: number) {
- const style: { [key: string]: any } = {};
+ const style: { [key: string]: string } = {};
const divKeys = ['width', 'height', 'fontSize', 'transform', 'left', 'backgroundColor', 'left', 'right', 'top', 'bottom', 'pointerEvents', 'position'];
- const replacer = (match: any, expr: string) =>
+ const replacer = (match: string, expr: string) =>
// bcz: this executes a script to convert a property expression string: { script } into a value
ScriptField.MakeFunction(expr, { this: Doc.name, scale: 'number' })?.script.run({ this: doc, scale }).result?.toString() ?? '';
divKeys.forEach((prop: string) => {
@@ -72,7 +69,7 @@ export function SetFilterOpener(func: () => void) {
// a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab
//
-export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & DocumentViewProps>, property: string): any {
+export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & DocumentViewProps>, property: string) : StyleProviderFuncType {
const remoteDocHeader = 'author;author_date;noMargin';
const isCaption = property.includes(':caption');
const isAnchor = property.includes(':anchor');
@@ -110,9 +107,9 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
const lockedPosition = () => doc && BoolCast(doc._lockedPosition);
const titleHeight = () => styleProvider?.(doc, props, StyleProp.TitleHeight);
const backgroundCol = () => styleProvider?.(doc, props, StyleProp.BackgroundColor + ':nonTransparent' + (isNonTransparentLevel + 1));
- const color = () => styleProvider?.(doc, props, StyleProp.Color);
+ const color = () => styleProvider?.(doc, props, StyleProp.Color) as string;
const opacity = () => styleProvider?.(doc, props, StyleProp.Opacity);
- const layoutShowTitle = () => styleProvider?.(doc, props, StyleProp.ShowTitle);
+ const layoutShowTitle = () => styleProvider?.(doc, props, StyleProp.ShowTitle) as string;
// prettier-ignore
switch (property.split(':')[0]) {
case StyleProp.TreeViewIcon: {
@@ -144,7 +141,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
highlightStyle: doc.isGroup ? "dotted": highlightStyle,
highlightColor,
highlightIndex,
- highlightStroke: layoutDoc?.layout_isSvg,
+ highlightStroke: BoolCast(layoutDoc?.layout_isSvg),
};
}
}
@@ -152,7 +149,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
case StyleProp.DocContents: return undefined;
case StyleProp.WidgetColor: return isAnnotated ? Colors.LIGHT_BLUE : 'dimgrey';
case StyleProp.Opacity: return componentView?.isUnstyledView?.() ? 1 : Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
- case StyleProp.FontColor: return StrCast(doc?.[fieldKey + 'fontColor'], isCaption ? lightOrDark(backgroundCol()) : StrCast(Doc.UserDoc().fontColor, color()));
+ case StyleProp.FontColor: return StrCast(doc?.[fieldKey + 'fontColor'], isCaption ? lightOrDark(backgroundCol()) : StrCast(Doc.UserDoc().fontColor, color()));
case StyleProp.FontSize: return StrCast(doc?.[fieldKey + 'fontSize'], StrCast(Doc.UserDoc().fontSize));
case StyleProp.FontFamily: return StrCast(doc?.[fieldKey + 'fontFamily'], StrCast(Doc.UserDoc().fontFamily));
case StyleProp.FontWeight: return StrCast(doc?.[fieldKey + 'fontWeight'], StrCast(Doc.UserDoc().fontWeight));
@@ -168,7 +165,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
StrCast(
doc._layout_showTitle,
showTitle?.() ||
- (!Doc.IsSystem(doc) && [DocumentType.COL, DocumentType.FUNCPLOT, DocumentType.LABEL, DocumentType.RTF, DocumentType.IMG, DocumentType.VID].includes(doc.type as any)
+ (!Doc.IsSystem(doc) && [DocumentType.COL, DocumentType.FUNCPLOT, DocumentType.LABEL, DocumentType.RTF, DocumentType.IMG, DocumentType.VID].includes(doc.type as DocumentType)
? doc.author === ClientUtils.CurrentUserEmail()
? StrCast(Doc.UserDoc().layout_showTitle)
: remoteDocHeader
@@ -207,7 +204,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
};
}
case StyleProp.HeaderMargin:
- return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._type_collection as any) ||
+ return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._type_collection as CollectionViewType) ||
(doc?.type === DocumentType.RTF && !layoutShowTitle()?.includes('noMargin')) ||
doc?.type === DocumentType.LABEL) &&
layoutShowTitle() &&
@@ -297,8 +294,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
if (SnappingManager.ExploreMode || doc?.layout_unrendered) return isInk() ? 'visiblePainted' : 'all';
if (pointerEvents?.() === 'none') return 'none';
if (opacity() === 0) return 'none';
- if (isGroupActive?.() ) return isInk() ? 'visiblePainted': (doc?.
- isGroup )? undefined: 'all'
+ if (isGroupActive?.() ) return isInk() ? 'visiblePainted': (doc?.isGroup ) ? undefined: 'all';
if (isDocumentActive?.()) return isInk() ? 'visiblePainted' : 'all';
return undefined; // fixes problem with tree view elements getting pointer events when the tree view is not active
case StyleProp.Decorations: {
@@ -329,11 +325,12 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
// eslint-disable-next-line react/no-unstable-nested-components
iconProvider={() => <div className='styleProvider-filterShift'><FaFilter/></div>}
closeOnSelect
- setSelectedVal={((dv: DocumentView) => {
+ setSelectedVal={((dvValue: unknown) => {
+ const dv = dvValue as DocumentView;
dv.select(false);
SnappingManager.SetPropertiesWidth(250);
_filterOpener?.();
- }) as any // Dropdown assumes values are strings or numbers..
+ }) // Dropdown assumes values are strings or numbers..
}
size={Size.XSMALL}
width={15}
@@ -345,11 +342,9 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
background={showFilterIcon}
items={[ ...(dashView ? [dashView]: []), ...(docViewPath?.()??[])]
.filter(dv => StrListCast(dv?.Document.childFilters).length || StrListCast(dv?.Document.childRangeFilters).length)
- .map(dv => ({
- text: StrCast(dv?.Document.title),
- val: dv as any,
- style: {color:SnappingManager.userColor, background:SnappingManager.userBackgroundColor},
- } as IListItemProps)) }
+ .map(dv => ({ text: StrCast(dv?.Document.title),
+ val: dv as unknown,
+ style: {color:SnappingManager.userColor, background:SnappingManager.userBackgroundColor} } as IListItemProps)) }
/>
</div>
);
@@ -378,6 +373,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
}
default:
}
+ return undefined;
}
export function DashboardToggleButton(doc: Doc, field: string, onIcon: IconProp, offIcon: IconProp, clickFunc?: () => void) {
@@ -386,7 +382,7 @@ export function DashboardToggleButton(doc: Doc, field: string, onIcon: IconProp,
<IconButton
size={Size.XSMALL}
color={color}
- icon={<FontAwesomeIcon icon={(doc[field] ? (onIcon as any) : offIcon) as IconProp} />}
+ icon={<FontAwesomeIcon icon={doc[field] ? onIcon : offIcon} />}
onClick={undoBatch(
action((e: React.MouseEvent) => {
e.stopPropagation();
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx
index 38f681e87..c799eb3c8 100644
--- a/src/client/views/collections/CollectionCarousel3DView.tsx
+++ b/src/client/views/collections/CollectionCarousel3DView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
@@ -15,7 +13,7 @@ import { StyleProp } from '../StyleProp';
import { DocumentView } from '../nodes/DocumentView';
import { FocusViewOptions } from '../nodes/FocusViewOptions';
import './CollectionCarousel3DView.scss';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } = require('../global/globalCssVariables.module.scss');
@@ -25,7 +23,7 @@ export class CollectionCarousel3DView extends CollectionSubView() {
@computed get scrollSpeed() {
return this.layoutDoc._autoScrollSpeed ? NumCast(this.layoutDoc._autoScrollSpeed) : 1000; // default scroll speed
}
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -181,8 +179,8 @@ export class CollectionCarousel3DView extends CollectionSubView() {
className="collectionCarousel3DView-outer"
ref={this.createDashEventsTarget}
style={{
- background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor),
- color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color),
+ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string,
+ color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string,
}}>
<div className="carousel-wrapper" style={{ transform: `translateX(${this.translateX}px)` }}>
{this.content}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 2a36e96bf..5a142cc6e 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
import { action, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
@@ -28,7 +29,7 @@ import { OverlayView } from '../OverlayView';
import { ScriptingRepl } from '../ScriptingRepl';
import { UndoStack } from '../UndoStack';
import './CollectionDockingView.scss';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
const _global = (window /* browser */ || global) /* node */ as any;
@@ -40,7 +41,7 @@ export class CollectionDockingView extends CollectionSubView() {
* configuring golden layout to render its documents using the specified React component
* @param ele - typically would be set to TabDocView
*/
- public static Init(ele: any) {
+ public static Init(ele: JSX.Element | null) {
this.tabClass = ele;
DocumentView.addSplit = CollectionDockingView.AddSplit;
}
@@ -60,7 +61,7 @@ export class CollectionDockingView extends CollectionSubView() {
private _goldenLayout: any = null;
static _highlightStyleSheet = addStyleSheet();
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
if (this._props.renderDepth < 0) CollectionDockingView.Instance = this;
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index e250d7a90..b7169ece0 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -67,7 +67,7 @@ export function CollectionSubView<X>() {
private gestureDisposer?: GestureUtils.GestureEventDisposer;
protected _mainCont?: HTMLDivElement;
- constructor(props: any) {
+ constructor(props: X & SubCollectionViewProps) {
super(props);
makeObservable(this);
}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 46f61290e..f50f7394b 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -14,7 +14,7 @@ import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { FieldId } from '../../../fields/RefField';
import { ComputedField } from '../../../fields/ScriptField';
-import { Cast, DocCast, NumCast, StrCast, toList } from '../../../fields/Types';
+import { Cast, NumCast, StrCast, toList } from '../../../fields/Types';
import { DocServer } from '../../DocServer';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
@@ -67,7 +67,7 @@ class TabMiniThumb extends React.Component<TabMiniThumbProps> {
}
@observer
export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps> {
- static miniStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => {
+ static miniStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => {
if (doc) {
switch (property.split(':')[0]) {
case StyleProp.PointerEvents: return 'none';
@@ -274,7 +274,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
}
static Activate = (tabDoc: Doc) => {
- const tab = Array.from(CollectionDockingView.Instance?.tabMap!).find(findTab => findTab.DashDoc === tabDoc && !findTab.contentItem.config.props.keyValue);
+ const tab = Array.from(CollectionDockingView.Instance?.tabMap ?? []).find(findTab => findTab.DashDoc === tabDoc && !findTab.contentItem.config.props.keyValue);
tab?.header.parent.setActiveContentItem(tab.contentItem); // glr: Panning does not work when this is set - (this line is for trying to make a tab that is not topmost become topmost)
return tab !== undefined;
};
@@ -286,7 +286,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
// }
// return undefined;
// }
- constructor(props: any) {
+ constructor(props: TabDocViewProps) {
super(props);
makeObservable(this);
DocumentView.activateTabView = TabDocView.Activate;
@@ -399,9 +399,10 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
tab._disposers.color = reaction(
() => ({ variant: SnappingManager.userVariantColor, degree: Doc.GetBrushStatus(doc), highlight: DefaultStyleProvider(this._document, undefined, StyleProp.Highlighting) }),
({ variant, degree, highlight }) => {
- const color = highlight?.highlightIndex === Doc.DocBrushStatus.highlighted ? highlight.highlightColor : degree ? ['transparent', variant, variant, 'orange'][degree] : variant;
+ const { highlightIndex, highlightColor } = (highlight as { highlightIndex: number; highlightColor: string }) ?? { highlightIndex: undefined, highlightColor: undefined };
+ const color = highlightIndex === Doc.DocBrushStatus.highlighted ? highlightColor : degree ? ['transparent', variant, variant, 'orange'][degree] : variant;
- const textColor = color === variant ? SnappingManager.userColor ?? '' : lightOrDark(color);
+ const textColor = color === variant ? (SnappingManager.userColor ?? '') : lightOrDark(color);
titleEle.style.color = textColor;
iconWrap.style.color = textColor;
closeWrap.style.color = textColor;
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index f69aea2a7..161d93788 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> {
refTransform = (ref: HTMLElement | undefined | null) => {
if (!ref) return this.ScreenToLocalTransform();
const { translateX, translateY, scale } = ClientUtils.GetScreenTransform(ref);
- return new Transform(-translateX, -translateY, 1).scale(1/scale);
+ return new Transform(-translateX, -translateY, 1).scale(1 / scale);
};
docTransform = () => this.refTransform(this._dref?.ContentDiv);
getTransform = () => this.refTransform(this._tref.current);
@@ -777,7 +777,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
@computed get renderBullet() {
TraceMobx();
- const iconType = this.treeView._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':treeOpen' : !this.childDocs.length ? ':empty' : '')) || 'question';
+ 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;
return (
@@ -923,7 +923,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
style={{
// just render a title for a tree view label (identified by treeViewDoc being set in 'props')
maxWidth: props?.PanelWidth() || undefined,
- background: props?.styleProvider?.(doc, props, StyleProp.BackgroundColor),
+ background: props?.styleProvider?.(doc, props, StyleProp.BackgroundColor) as string,
outline: SnappingManager.IsDragging ? undefined: `solid ${highlightColor} ${highlightIndex}px`,
paddingLeft: NumCast(treeView.Document.childXPadding, NumCast(treeView._props.childXPadding, Doc.IsComicStyle(doc)?20:0)),
paddingRight: NumCast(treeView.Document.childXPadding, NumCast(treeView._props.childXPadding, Doc.IsComicStyle(doc)?20:0)),
@@ -1179,7 +1179,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
@computed get renderBorder() {
const sorting = StrCast(this.Document.treeView_SortCriterion, TreeSort.WhenAdded);
- const sortings = (this._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewSortings) ?? {}) as { [key: string]: { color: string; label: string } };
+ const sortings = (this._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewSortings) ?? {}) as { [key: string]: { color: string; icon: JSX.Element } };
return (
<div className={`treeView-border${this.treeView.outlineMode ? TreeViewType.outline : ''}`} style={{ borderColor: sortings[sorting]?.color }}>
{!this.treeViewOpen ? null : this.renderContent}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index de51cc73c..79aad0ef2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -9,7 +9,7 @@ import { aggregateBounds } from '../../../../Utils';
export interface ViewDefBounds {
type: string;
- payload: any;
+ payload: unknown;
x: number;
y: number;
z?: number;
@@ -72,11 +72,15 @@ function toLabel(target: FieldResult<FieldType>) {
*/
function getTextWidth(text: string, font: string): number {
// re-use canvas object for better performance
- const canvas = (getTextWidth as any).canvas || ((getTextWidth as any).canvas = document.createElement('canvas'));
+ const selfStoreHack = getTextWidth as unknown as { canvas: Element };
+ const canvas = (selfStoreHack.canvas = (selfStoreHack.canvas as unknown as HTMLCanvasElement) ?? document.createElement('canvas'));
const context = canvas.getContext('2d');
- context.font = font;
- const metrics = context.measureText(text);
- return metrics.width;
+ if (context) {
+ context.font = font;
+ const metrics = context.measureText(text);
+ return metrics.width;
+ }
+ return 0;
}
interface PivotColumn {
@@ -131,13 +135,13 @@ export function computeStarburstLayout(poolData: Map<string, PoolData>, pivotDoc
return normalizeResults(burstDiam, 12, docMap, poolData, viewDefsToJSX, [], 0, [divider]);
}
-export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) {
+export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: unknown) {
const docMap = new Map<string, PoolData>();
const fieldKey = 'data';
const pivotColumnGroups = new Map<FieldResult<FieldType>, PivotColumn>();
let nonNumbers = 0;
- const pivotFieldKey = toLabel(engineProps?.pivotField ?? pivotDoc._pivotField) || 'author';
+ const pivotFieldKey = toLabel((engineProps as { pivotField?: string })?.pivotField ?? pivotDoc._pivotField) || 'author';
childPairs.forEach(pair => {
const listValue = Cast(pair.layout[pivotFieldKey], listSpec('string'), null);
@@ -265,7 +269,7 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do
y: -maxColHeight + pivotAxisWidth,
width: pivotAxisWidth * numCols * expander,
height: maxColHeight,
- payload: pivotColumnGroups.get(key)!.filters,
+ payload: pivotColumnGroups.get(key)?.filters,
}));
groupNames.push(...dividers);
// eslint-disable-next-line no-use-before-define
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 5b7f09be3..39c3da7a5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,6 +1,4 @@
/* eslint-disable react/jsx-props-no-spreading */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
import { Bezier } from 'bezier-js';
import { Colors } from 'browndash-components';
import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
@@ -9,7 +7,7 @@ import { computedFn } from 'mobx-utils';
import * as React from 'react';
import { ClientUtils, DashColor, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../../ClientUtils';
import { DateField } from '../../../../fields/DateField';
-import { Doc, DocListCast, Field, FieldType, Opt } from '../../../../fields/Doc';
+import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc';
import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveEraserWidth, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, SetActiveInkColor, SetActiveInkWidth } from '../../nodes/DocumentView';
import { DocData, Height, Width } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
@@ -46,7 +44,7 @@ import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
import { OpenWhere, OpenWhereMod } from '../../nodes/OpenWhere';
import { PinDocView, PinProps } from '../../PinFuncs';
import { StyleProp } from '../../StyleProp';
-import { CollectionSubView } from '../CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView';
import { TreeViewType } from '../CollectionTreeViewType';
import { CollectionFreeFormBackgroundGrid } from './CollectionFreeFormBackgroundGrid';
import { CollectionFreeFormClusters } from './CollectionFreeFormClusters';
@@ -71,7 +69,7 @@ export interface collectionFreeformViewProps {
childPointerEvents?: () => string | undefined;
viewField?: string;
noOverlay?: boolean; // used to suppress docs in the overlay (z) layer (ie, for minimap since overlay doesn't scale)
- engineProps?: any;
+ engineProps?: unknown;
getScrollHeight?: () => number | undefined;
}
@@ -83,7 +81,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
public unprocessedDocs: Doc[] = [];
public static collectionsWithUnprocessedInk = new Set<CollectionFreeFormView>();
public static from(dv?: DocumentView): CollectionFreeFormView | undefined {
- const parent = CollectionFreeFormDocumentView.from(dv)?._props.parent;
+ const parent = CollectionFreeFormDocumentView.from(dv)?._props.reactParent;
return parent instanceof CollectionFreeFormView ? parent : undefined;
}
@@ -123,14 +121,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@observable _marqueeViewRef = React.createRef<MarqueeView>();
@observable _brushedView: { width: number; height: number; panX: number; panY: number } | undefined = undefined; // highlighted region of freeform canvas used by presentations to indicate a region
@observable GroupChildDrag: boolean = false; // child document view being dragged. needed to update drop areas of groups when a group item is dragged.
- @observable _childPointerEvents: 'none' | 'all' | 'visiblepainted' | undefined = undefined;
+ @observable _childPointerEvents: 'none' | 'all' | 'visiblePainted' | undefined = undefined;
@observable _lightboxDoc: Opt<Doc> = undefined;
@observable _paintedId = 'id' + Utils.GenerateGuid().replace(/-/g, '');
@observable _keyframeEditing = false;
@observable _eraserX: number = 0;
@observable _eraserY: number = 0;
@observable _showEraserCircle: boolean = false; // to determine whether the radius eraser should show
- constructor(props: collectionFreeformViewProps) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -140,12 +138,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@computed get childPointerEvents() {
return SnappingManager.IsResizing
? 'none'
- : this._props.childPointerEvents?.() ??
+ : (this._props.childPointerEvents?.() ??
(this._props.viewDefDivClick || //
(this.layoutEngine === computePassLayout.name && !this._props.isSelected()) ||
this.isContentActive() === false
? 'none'
- : this._props.pointerEvents?.());
+ : this._props.pointerEvents?.()));
}
@computed get contentViews() {
const viewsMask = this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z && ele.inkMask !== -1 && ele.inkMask !== undefined).map(ele => ele.ele);
@@ -185,7 +183,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
.transform(this.panZoomXf);
}
@computed get backgroundColor() {
- return this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor);
+ return this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor) as string;
}
@computed get fitWidth() {
return this._props.fitWidth?.(this.Document) ?? this.layoutDoc.layout_fitWidth;
@@ -357,7 +355,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
* @param options
* @returns
*/
- focus = (anchor: Doc, options: FocusViewOptions): any => {
+ focus = (anchor: Doc, options: FocusViewOptions) => {
if (anchor.isGroup && !options.docTransform && options.contextPath?.length) {
// don't focus on group if there's a context path because we're about to focus on a group item
// which will override any group focus. (If we allowed the group to focus, it would mark didMove even if there were no net movement)
@@ -374,14 +372,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const xfToCollection = options?.docTransform ?? Transform.Identity();
const savedState = { panX: NumCast(this.Document[this.panXFieldKey]), panY: NumCast(this.Document[this.panYFieldKey]), scale: options?.willZoomCentered ? this.Document[this.scaleFieldKey] : undefined };
const cantTransform = this.fitContentsToBox || ((this.Document.isGroup || this.layoutDoc._lockedTransform) && !DocumentView.LightboxDoc());
- const { panX, panY, scale } = cantTransform || (!options.willPan && !options.willZoomCentered) ? savedState : this.calculatePanIntoView(anchor, xfToCollection, options?.willZoomCentered ? options?.zoomScale ?? 0.75 : undefined);
+ const { panX, panY, scale } = cantTransform || (!options.willPan && !options.willZoomCentered) ? savedState : this.calculatePanIntoView(anchor, xfToCollection, options?.willZoomCentered ? (options?.zoomScale ?? 0.75) : undefined);
// focus on the document in the collection
const didMove = !cantTransform && !anchor.z && (panX !== savedState.panX || panY !== savedState.panY || scale !== savedState.scale);
if (didMove) options.didMove = true;
// glr: freeform transform speed can be set by adjusting presentation_transition field - needs a way of knowing when presentation is not active...
if (didMove) {
- const focusTime = options?.instant ? 0 : options.zoomTime ?? 500;
+ const focusTime = options?.instant ? 0 : (options.zoomTime ?? 500);
(options.zoomScale ?? options.willZoomCentered) && scale && (this.Document[this.scaleFieldKey] = scale);
this.setPan(panX, panY, focusTime); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow
return focusTime;
@@ -1178,6 +1176,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
// for some reason bezier.js doesn't handle the case of intersecting a linear curve, so we wrap the intersection
// call in a test for linearity
bintersects = (curve: Bezier, otherCurve: Bezier) => {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
if ((curve as any)._linear) {
// bezier.js doesn't intersect properly if the curve is actually a line -- so get intersect other curve against this line, then figure out the t coordinates of the intersection on this line
const intersections = otherCurve.lineIntersects({ p1: curve.points[0], p2: curve.points[3] });
@@ -1187,6 +1186,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return intT ? [intT] : [];
}
}
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
if ((otherCurve as any)._linear) {
return curve.lineIntersects({ p1: otherCurve.points[0], p2: otherCurve.points[3] });
}
@@ -1478,7 +1478,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return ret;
};
childPointerEventsFunc = () => this._childPointerEvents;
- childContentsActive = () => (this._props.childContentsActive ?? this.isContentActive() === false ? returnFalse : emptyFunction)();
+ childContentsActive = () => ((this._props.childContentsActive ?? this.isContentActive() === false) ? returnFalse : emptyFunction)();
getChildDocView(entry: PoolData) {
const childLayout = entry.pair.layout;
const childData = entry.pair.data;
@@ -1488,7 +1488,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
{...OmitKeys(entry, ['replica', 'pair']).omit}
key={childLayout[Id] + (entry.replica || '')}
Document={childLayout}
- parent={this}
+ reactParent={this}
containerViewPath={this.DocumentView?.().docViewPath}
styleProvider={this._clusters.styleProvider}
TemplateDataDocument={childData}
@@ -1603,7 +1603,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
}
- onViewDefDivClick = (e: React.MouseEvent, payload: any) => {
+ onViewDefDivClick = (e: React.MouseEvent, payload: unknown) => {
(this._props.viewDefDivClick || ScriptCast(this.Document.onViewDefDivClick))?.script.run({ this: this.Document, payload });
e.stopPropagation();
};
@@ -1637,7 +1637,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
ele: (
<div
className="collectionFreeform-customDiv"
- title={viewDef.payload?.join(' ')}
+ title={StrListCast(viewDef.payload as string).join(' ')}
key={'div' + x + y + z + viewDef.payload}
onClick={e => this.onViewDefDivClick(e, viewDef)}
style={{ width, height, backgroundColor: color, transform }}
@@ -1658,7 +1658,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
doEngineLayout(
poolData: Map<string, PoolData>,
- engine: (poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) => ViewDefResult[]
+ engine: (poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: unknown) => ViewDefResult[]
) {
return engine(poolData, this.Document, this.childLayoutPairs, [this._props.PanelWidth(), this._props.PanelHeight()], this.viewDefsToJSX, this._props.engineProps);
}
@@ -1688,7 +1688,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
.forEach(entry =>
elements.push({
ele: this.getChildDocView(entry[1]),
- bounds: (entry[1].opacity === 0 ? { payload:undefined, type:"", ...entry[1], width: 0, height: 0 } : { payload:undefined, type:"",...entry[1] }),
+ bounds: entry[1].opacity === 0 ? { payload: undefined, type: '', ...entry[1], width: 0, height: 0 } : { payload: undefined, type: '', ...entry[1] },
inkMask: BoolCast(entry[1].pair.layout.stroke_isInkMask) ? NumCast(entry[1].pair.layout.opacity, 1) : -1,
})
);
@@ -1771,7 +1771,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._disposers.pointerevents = reaction(
() => this.childPointerEvents,
pointerevents => {
- this._childPointerEvents = pointerevents as any;
+ this._childPointerEvents = pointerevents as 'none' | 'all' | 'visiblePainted' | undefined;
},
{ fireImmediately: true }
);
@@ -1812,24 +1812,25 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
updateIcon = () => {
const contentDiv = this.DocumentView?.().ContentDiv;
- contentDiv && UpdateIcon(
- this.layoutDoc[Id] + '-icon' + new Date().getTime(),
- contentDiv,
- NumCast(this.layoutDoc._width),
- NumCast(this.layoutDoc._height),
- this._props.PanelWidth(),
- this._props.PanelHeight(),
- 0,
- 1,
- false,
- '',
- (iconFile, nativeWidth, nativeHeight) => {
- this.dataDoc.icon = new ImageField(iconFile);
- this.dataDoc.icon_nativeWidth = nativeWidth;
- this.dataDoc.icon_nativeHeight = nativeHeight;
- }
- );
- }
+ contentDiv &&
+ UpdateIcon(
+ this.layoutDoc[Id] + '-icon' + new Date().getTime(),
+ contentDiv,
+ NumCast(this.layoutDoc._width),
+ NumCast(this.layoutDoc._height),
+ this._props.PanelWidth(),
+ this._props.PanelHeight(),
+ 0,
+ 1,
+ false,
+ '',
+ (iconFile, nativeWidth, nativeHeight) => {
+ this.dataDoc.icon = new ImageField(iconFile);
+ this.dataDoc.icon_nativeWidth = nativeWidth;
+ this.dataDoc.icon_nativeHeight = nativeHeight;
+ }
+ );
+ };
@action
onCursorMove = (e: React.PointerEvent) => {
@@ -2134,7 +2135,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
onDragOver={e => e.preventDefault()}
onContextMenu={this.onContextMenu}
style={{
- pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : (this._props.pointerEvents?.() as any),
+ pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : this._props.pointerEvents?.(),
textAlign: this.isAnnotationOverlay ? 'initial' : undefined,
transform: `scale(${this.nativeDimScaling})`,
width: `${100 / this.nativeDimScaling}%`,
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index ee67dd305..9a383c1e4 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -47,7 +47,7 @@ interface freeFormProps {
export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
RenderCutoffProvider: (doc: Doc) => boolean;
isAnyChildContentActive: () => boolean;
- parent: any;
+ reactParent: React.Component;
}
@observer
export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps & freeFormProps>() {
@@ -71,7 +71,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
public static animStringFields = ['backgroundColor', 'color', 'fillColor']; // fields that are configured to be animatable using animation frames
public static animDataFields = (doc: Doc) => (Doc.LayoutFieldKey(doc) ? [Doc.LayoutFieldKey(doc)] : []); // fields that are configured to be animatable using animation frames
public static from(dv?: DocumentView): CollectionFreeFormDocumentView | undefined {
- return dv?._props.parent instanceof CollectionFreeFormDocumentView ? dv._props.parent : undefined;
+ return dv?._props.reactParent instanceof CollectionFreeFormDocumentView ? dv._props.reactParent : undefined;
}
constructor(props: CollectionFreeFormDocumentViewProps & freeFormProps) {
@@ -304,7 +304,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
<DocumentView
// eslint-disable-next-line react/jsx-props-no-spreading
{...OmitKeys(this._props,this.WrapperKeys.map(val => val.lower)).omit} // prettier-ignore
- parent={this}
+ reactParent={this}
DataTransition={this.DataTransition}
LocalRotation={this.localRotation}
CollectionFreeFormDocumentView={this.returnThis}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ce7cfa5f4..0f2905d5b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,13 +1,12 @@
/* eslint-disable no-use-before-define */
/* eslint-disable react/jsx-props-no-spreading */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { Howl } from 'howler';
import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Fade, JackInTheBox } from 'react-awesome-reveal';
-import { ClientUtils, DivWidth, isTargetChildOf as isParentOf, lightOrDark, returnFalse, returnVal, simulateMouseClick } from '../../../ClientUtils';
+import { ClientUtils, DivWidth, isTargetChildOf as isParentOf, lightOrDark, returnFalse, returnVal, simMouseEvent, simulateMouseClick } from '../../../ClientUtils';
import { Utils, emptyFunction } from '../../../Utils';
import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../fields/Doc';
import { AclAdmin, AclEdit, AclPrivate, Animation, AudioPlay, DocData, DocViews } from '../../../fields/DocSymbols';
@@ -55,13 +54,6 @@ import { PresEffect, PresEffectDirection } from './trails/PresEnums';
import SpringAnimation from './trails/SlideEffect';
import { SpringType, springMappings } from './trails/SpringUtils';
-interface Window {
- MediaRecorder: MediaRecorder;
-}
-declare class MediaRecorder {
- constructor(e: any); // whatever MediaRecorder has
-}
-
export interface DocumentViewProps extends FieldViewSharedProps {
hideDecorations?: boolean; // whether to suppress all DocumentDecorations when doc is selected
hideResizeHandles?: boolean; // whether to suppress resized handles on doc decorations when this document is selected
@@ -89,7 +81,7 @@ export interface DocumentViewProps extends FieldViewSharedProps {
dragStarting?: () => void;
dragEnding?: () => void;
- parent?: any; // parent React component view (see CollectionFreeFormDocumentView)
+ reactParent?: React.Component; // parent React component view (see CollectionFreeFormDocumentView)
}
@observer
export class DocumentViewInternal extends DocComponent<FieldViewProps & DocumentViewProps>() {
@@ -105,7 +97,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
private _disposers: { [name: string]: IReactionDisposer } = {};
private _doubleClickTimeout: NodeJS.Timeout | undefined;
- private _singleClickFunc: undefined | (() => any);
+ private _singleClickFunc: undefined | (() => void);
private _longPressSelector: NodeJS.Timeout | undefined;
private _downX: number = 0;
private _downY: number = 0;
@@ -134,16 +126,16 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
animateScaleTime = () => this._animateScaleTime ?? 100;
style = (doc: Doc, sprop: StyleProp | string) => this._props.styleProvider?.(doc, this._props, sprop);
- @computed get opacity() { return this.style(this.layoutDoc, StyleProp.Opacity); } // prettier-ignore
- @computed get boxShadow() { return this.style(this.layoutDoc, StyleProp.BoxShadow); } // prettier-ignore
- @computed get borderRounding() { return this.style(this.layoutDoc, StyleProp.BorderRounding); } // prettier-ignore
- @computed get widgetDecorations() { return this.style(this.layoutDoc, StyleProp.Decorations); } // prettier-ignore
- @computed get backgroundBoxColor(){ return this.style(this.layoutDoc, StyleProp.BackgroundColor + ':docView'); } // prettier-ignore
+ @computed get opacity() { return this.style(this.layoutDoc, StyleProp.Opacity) as number; } // prettier-ignore
+ @computed get boxShadow() { return this.style(this.layoutDoc, StyleProp.BoxShadow) as string; } // prettier-ignore
+ @computed get borderRounding() { return this.style(this.layoutDoc, StyleProp.BorderRounding) as string; } // prettier-ignore
+ @computed get widgetDecorations() { return this.style(this.layoutDoc, StyleProp.Decorations) as JSX.Element; } // prettier-ignore
+ @computed get backgroundBoxColor(){ return this.style(this.layoutDoc, StyleProp.BackgroundColor + ':docView') as string; } // prettier-ignore
@computed get showTitle() { return this.style(this.layoutDoc, StyleProp.ShowTitle) as Opt<string>; } // prettier-ignore
- @computed get showCaption() { return this.style(this.layoutDoc, StyleProp.ShowCaption) ?? 0; } // prettier-ignore
- @computed get headerMargin() { return this.style(this.layoutDoc, StyleProp.HeaderMargin) ?? 0; } // prettier-ignore
- @computed get titleHeight() { return this.style(this.layoutDoc, StyleProp.TitleHeight) ?? 0; } // prettier-ignore
- @computed get docContents() { return this.style(this.Document, StyleProp.DocContents); } // prettier-ignore
+ @computed get showCaption() { return this.style(this.layoutDoc, StyleProp.ShowCaption) as string ?? ""; } // prettier-ignore
+ @computed get headerMargin() { return this.style(this.layoutDoc, StyleProp.HeaderMargin) as number ?? 0; } // prettier-ignore
+ @computed get titleHeight() { return this.style(this.layoutDoc, StyleProp.TitleHeight) as number ?? 0; } // prettier-ignore
+ @computed get docContents() { return this.style(this.Document, StyleProp.DocContents) as JSX.Element; } // prettier-ignore
@computed get highlighting() { return this.style(this.Document, StyleProp.Highlighting); } // prettier-ignore
@computed get borderPath() { return this.style(this.Document, StyleProp.BorderPath); } // prettier-ignore
@@ -164,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;
}
@@ -224,7 +216,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
{ fireImmediately: true }
);
this._disposers.pointerevents = reaction(
- () => this.style(this.Document, StyleProp.PointerEvents),
+ () => this.style(this.Document, StyleProp.PointerEvents) as 'all' | 'none' | 'visiblePainted' | undefined,
pointerevents => {
this._pointerEvents = pointerevents;
},
@@ -450,7 +442,11 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
if (this.Document === Doc.ActiveDashboard) {
e.stopPropagation();
e.preventDefault();
- alert((e.target as any)?.closest?.('*.lm_content') ? "You can't perform this move most likely because you didn't drag the document's title bar to enable embedding in a different document." : 'Linking to document tabs not yet supported.');
+ alert(
+ (e.target as HTMLElement)?.closest?.('*.lm_content')
+ ? "You can't perform this move most likely because you didn't drag the document's title bar to enable embedding in a different document."
+ : 'Linking to document tabs not yet supported.'
+ );
return true;
}
const annoData = de.complete.annoDragData;
@@ -532,9 +528,9 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
}
const cm = ContextMenu.Instance;
- if (!cm || (e as any)?.nativeEvent?.SchemaHandled || SnappingManager.ExploreMode) return;
+ if (!cm || SnappingManager.ExploreMode) return;
- if (e && !(e.nativeEvent as any).dash) {
+ if (e && !(e.nativeEvent instanceof simMouseEvent ? e.nativeEvent.dash : false)) {
const onDisplay = () => {
if (this.Document.type !== DocumentType.MAP) DocumentViewInternal.SelectAfterContextMenu && this._props.select(false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear.
setTimeout(() => simulateMouseClick(document.elementFromPoint(e.clientX, e.clientY), e.clientX, e.clientY, e.screenX, e.screenY));
@@ -722,7 +718,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
anchorPanelWidth = () => this._props.PanelWidth() || 1;
anchorPanelHeight = () => this._props.PanelHeight() || 1;
- anchorStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => {
+ anchorStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => {
// prettier-ignore
switch (property.split(':')[0]) {
case StyleProp.ShowTitle: return '';
@@ -770,7 +766,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
captionStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => this._props?.styleProvider?.(doc, props, property + ':caption');
fieldsDropdown = (placeholder: string) => (
<div
- ref={action((r: any) => { r && (this._titleDropDownInnerWidth = DivWidth(r));} )} // prettier-ignore
+ ref={r => { r && runInAction(() => (this._titleDropDownInnerWidth = DivWidth(r)));}} // prettier-ignore
onPointerDown={action(() => { this._changingTitleField = true; })} // prettier-ignore
style={{ width: 'max-content', background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor, transformOrigin: 'left', transform: `scale(${this.titleHeight / 30 /* height of Dropdown */})` }}>
<FieldsDropdown
@@ -897,7 +893,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}
@@ -923,27 +919,33 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
)}
{this.widgetDecorations ?? null}
</div>
- );
+ ));
};
render() {
TraceMobx();
const { highlighting, borderPath } = this;
+ const { highlightIndex, highlightStyle, highlightColor, highlightStroke } = (highlighting as { highlightIndex: number; highlightStyle: string; highlightColor: string; highlightStroke: boolean }) ?? {
+ highlightIndex: undefined,
+ highlightStyle: undefined,
+ highlightColor: undefined,
+ highlightStroke: undefined,
+ };
+ const { clipPath, jsx } = (borderPath as { clipPath: string; jsx: JSX.Element }) ?? { clipPath: undefined, jsx: undefined };
const boxShadow = !highlighting
? this.boxShadow
- : highlighting && this.borderRounding && highlighting.highlightStyle !== 'dashed'
- ? `0 0 0 ${highlighting.highlightIndex}px ${highlighting.highlightColor}`
+ : highlighting && this.borderRounding && highlightStyle !== 'dashed'
+ ? `0 0 0 ${highlightIndex}px ${highlightColor}`
: this.boxShadow || (this.Document.isTemplateForField ? 'black 0.2vw 0.2vw 0.8vw' : undefined);
const renderDoc = this.renderDoc({
borderRadius: this.borderRounding,
- outline: highlighting && !this.borderRounding && !highlighting.highlightStroke ? `${highlighting.highlightColor} ${highlighting.highlightStyle} ${highlighting.highlightIndex}px` : 'solid 0px',
- border: highlighting && this.borderRounding && highlighting.highlightStyle === 'dashed' ? `${highlighting.highlightStyle} ${highlighting.highlightColor} ${highlighting.highlightIndex}px` : undefined,
+ outline: highlighting && !this.borderRounding && !highlightStroke ? `${highlightColor} ${highlightStyle} ${highlightIndex}px` : 'solid 0px',
+ border: highlighting && this.borderRounding && highlightStyle === 'dashed' ? `${highlightStyle} ${highlightColor} ${highlightIndex}px` : undefined,
boxShadow,
- clipPath: borderPath?.clipPath,
+ clipPath,
});
return (
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events
<div
className={`${DocumentView.ROOT_DIV} docView-hack`}
ref={this._mainCont}
@@ -957,8 +959,8 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
borderRadius: this.borderRounding,
pointerEvents: this._pointerEvents === 'visiblePainted' ? 'none' : this._pointerEvents, // visible painted means that the underlying doc contents are irregular and will process their own pointer events (otherwise, the contents are expected to fill the entire doc view box so we can handle pointer events here)
}}>
- {this._componentView?.isUnstyledView?.() || this.Document.type === DocumentType.CONFIG ? renderDoc : DocumentViewInternal.AnimationEffect(renderDoc, this.Document[Animation], this.Document)}
- {borderPath?.jsx}
+ {this._componentView?.isUnstyledView?.() || this.Document.type === DocumentType.CONFIG || !renderDoc ? renderDoc : DocumentViewInternal.AnimationEffect(renderDoc, this.Document[Animation], this.Document)}
+ {jsx}
</div>
);
}
@@ -968,7 +970,22 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
* @param presEffectDoc presentation effects document that specifies the animation effect parameters
* @returns a function that will wrap a JSX animation element wrapping any JSX element
*/
- public static AnimationEffect(renderDoc: JSX.Element, presEffectDoc: Opt<Doc>, root: Doc) {
+ public static AnimationEffect(
+ renderDoc: JSX.Element,
+ presEffectDoc: Opt<
+ | Doc
+ | {
+ presentation_effectDirection?: string;
+ followLinkAnimDirection?: string;
+ presentation_transition?: number;
+ followLinkTransitionTime?: number;
+ presentation_effectTiming?: number;
+ presentation_effect?: string;
+ followLinkAnimEffect?: string;
+ }
+ >,
+ root: Doc
+ ) {
const dir = ((presEffectDoc?.presentation_effectDirection ?? presEffectDoc?.followLinkAnimDirection) || PresEffectDirection.Center) as PresEffectDirection;
const duration = Cast(presEffectDoc?.presentation_transition, 'number', Cast(presEffectDoc?.followLinkTransitionTime, 'number', null));
const effectProps = {
@@ -982,7 +999,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
};
const timing = StrCast(presEffectDoc?.presentation_effectTiming);
- const timingConfig = (timing ? JSON.parse(timing) : undefined) ?? {
+ const timingConfig = (timing ? JSON.parse(timing) : undefined) ?? {
type: SpringType.GENTLE,
...springMappings.gentle,
};
@@ -1054,7 +1071,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
public static allViews: () => DocumentView[];
public static addView: (dv: DocumentView) => void | undefined;
public static removeView: (dv: DocumentView) => void | undefined;
- public static addViewRenderedCb: (doc: Opt<Doc>, func: (dv: DocumentView) => any) => boolean;
+ public static addViewRenderedCb: (doc: Opt<Doc>, func: (dv: DocumentView) => void) => boolean;
public static getViews = (doc?: Doc) => Array.from(doc?.[DocViews] ?? []) as DocumentView[];
public static getFirstDocumentView: (toFind: Doc) => DocumentView | undefined;
public static getDocumentView: (target: Doc | undefined, preferredCollection?: DocumentView) => Opt<DocumentView>;
@@ -1107,7 +1124,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
@observable private _htmlOverlayText: Opt<string> = undefined;
@observable private _isHovering = false;
@observable private _selected = false;
- @observable public static CurrentlyPlaying: DocumentView[] = []; // audio or video media views that are currently playing
+ @observable public static CurrentlyPlaying: DocumentView[] = []; // audio or video media views that are currently playing
@computed private get shouldNotScale() {
return (this.layout_fitWidth && !this.nativeWidth) || this.ComponentView?.isUnstyledView?.();
@@ -1254,7 +1271,6 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
}
public playAnnotation = () => {
- const self = this;
const audioAnnoState = this.dataDoc.audioAnnoState ?? AudioAnnoState.stopped;
const audioAnnos = Cast(this.dataDoc[this.LayoutFieldKey + '_audioAnnotations'], listSpec(AudioField), null);
const anno = audioAnnos?.lastElement();
@@ -1267,7 +1283,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
autoplay: true,
loop: false,
volume: 0.5,
- onend: action(() => { self.dataDoc.audioAnnoState = AudioAnnoState.stopped; }), // prettier-ignore
+ onend: action(() => { this.dataDoc.audioAnnoState = AudioAnnoState.stopped; }), // prettier-ignore
});
this.dataDoc.audioAnnoState = AudioAnnoState.playing;
break;
@@ -1426,9 +1442,10 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
<div className="documentView-htmlOverlayInner" style={{ transition: `all 500ms`, opacity: this._enableHtmlOverlayTransitions ? 0.9 : 0 }}>
{DocumentViewInternal.AnimationEffect(
<div className="webBox-textHighlight">
+ {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
<ObserverJsxParser autoCloseVoidElements key={42} onError={(e: any) => console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this._htmlOverlayText)} />
</div>,
- { ...(this._htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Expand } as any as Doc,
+ { ...(this._htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Expand },
this.Document
)}
</div>
@@ -1457,11 +1474,11 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
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}
- parent={undefined}
+ reactParent={undefined}
isHovering={this.isHovering}
fieldKey={this.LayoutFieldKey}
DataTransition={this.DataTransition}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 818d26956..fc59e9e26 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -4,7 +4,7 @@ import { computed } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { DateField } from '../../../fields/DateField';
-import { Doc, Field, Opt } from '../../../fields/Doc';
+import { Doc, Field, FieldType, Opt } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { ScriptField } from '../../../fields/ScriptField';
import { WebField } from '../../../fields/URLField';
@@ -18,7 +18,26 @@ import { OpenWhere } from './OpenWhere';
export type FocusFuncType = (doc: Doc, options: FocusViewOptions) => Opt<number>;
// eslint-disable-next-line no-use-before-define
-export type StyleProviderFuncType = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => any;
+export type StyleProviderFuncType = (
+ doc: Opt<Doc>,
+ props: Opt<FieldViewProps>,
+ property: string
+) =>
+ | Opt<FieldType>
+ | { clipPath: string; jsx: JSX.Element }
+ | JSX.Element
+ | JSX.IntrinsicElements
+ | null
+ | {
+ [key: string]:
+ | {
+ color: string;
+ icon: JSX.Element | string;
+ }
+ | undefined;
+ }
+ | { highlightStyle: string; highlightColor: string; highlightIndex: number; highlightStroke: boolean }
+ | undefined;
//
// these properties get assigned through the render() method of the DocumentView when it creates this node.
// However, that only happens because the properties are "defined" in the markup for the field view.
@@ -30,7 +49,7 @@ export interface FieldViewSharedProps {
LayoutTemplateString?: string;
LayoutTemplate?: () => Opt<Doc>;
renderDepth: number;
- scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document
+ scriptContext?: unknown; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document
xPadding?: number;
yPadding?: number;
dontRegisterView?: boolean;
@@ -45,7 +64,7 @@ export interface FieldViewSharedProps {
containerViewPath?: () => DocumentView[];
fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document
isGroupActive?: () => string | undefined; // is this document part of a group that is active
- setContentViewBox?: (view: ViewBoxInterface<any>) => any; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox
+ setContentViewBox?: (view: ViewBoxInterface<FieldViewProps>) => void; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox
PanelWidth: () => number;
PanelHeight: () => number;
isDocumentActive?: () => boolean | undefined; // whether a document should handle pointer events
@@ -76,7 +95,7 @@ export interface FieldViewSharedProps {
bringToFront?: (doc: Doc, sendToBack?: boolean) => void;
waitForDoubleClickToClick?: () => 'never' | 'always' | undefined;
defaultDoubleClick?: () => 'default' | 'ignore' | undefined;
- pointerEvents?: () => Opt<string>;
+ pointerEvents?: () => Opt<'none' | 'all' | 'visiblePainted'>;
suppressSetHeight?: boolean;
}
diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx
index b8451fe60..37ffca2d6 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx
@@ -1,6 +1,4 @@
-/* eslint-disable jsx-a11y/label-has-associated-control */
/* eslint-disable react/button-has-type */
-/* eslint-disable jsx-a11y/control-has-associated-label */
import * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import { IconContext } from 'react-icons';
@@ -14,7 +12,7 @@ import { ProgressBar } from './ProgressBar';
import './RecordingView.scss';
export interface MediaSegment {
- videoChunks: any[];
+ videoChunks: Blob[];
endTime: number;
startTime: number;
presentation?: Presentation;
@@ -91,15 +89,15 @@ export function RecordingView(props: IRecordingViewProps) {
}, []);
useEffect(() => {
- let interval: any = null;
+ let interval: null | NodeJS.Timeout = null;
if (recording) {
interval = setInterval(() => {
setRecordingTimer(unit => unit + 1);
}, 10);
} else if (!recording && recordingTimer !== 0) {
- clearInterval(interval);
+ interval && clearInterval(interval);
}
- return () => clearInterval(interval);
+ return interval ? () => clearInterval(interval!) : undefined;
}, [recording]);
const setVideoProgressHelper = (curProgrss: number) => {
@@ -127,9 +125,9 @@ export function RecordingView(props: IRecordingViewProps) {
if (!videoRecorder.current) videoRecorder.current = new MediaRecorder(await startShowingStream());
// temporary chunks of video
- let videoChunks: any = [];
+ let videoChunks: Blob[] = [];
- videoRecorder.current.ondataavailable = (event: any) => {
+ videoRecorder.current.ondataavailable = (event: BlobEvent) => {
if (event.data.size > 0) videoChunks.push(event.data);
};
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 3be50f5e6..9ef1071f7 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable jsx-a11y/media-has-caption */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import * as React from 'react';
// import { Canvas } from '@react-three/fiber';
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 5b435e44a..b0c6120d4 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -14,7 +14,7 @@ import { EditorState, NodeSelection, Plugin, Selection, TextSelection, Transacti
import { EditorView, NodeViewConstructor } from 'prosemirror-view';
import * as React from 'react';
import { BsMarkdownFill } from 'react-icons/bs';
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivWidth, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, StopEvent } from '../../../../ClientUtils';
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivWidth, returnFalse, returnZero, setupMoveUpEvents, simMouseEvent, smoothScroll, StopEvent } from '../../../../ClientUtils';
import { DateField } from '../../../../fields/DateField';
import { CreateLinkToActiveAudio, Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc';
import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, DocData, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols';
@@ -821,7 +821,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
let target = e.target as any; // hrefs are stored on the database of the <a> node that wraps the hyerlink <span>
while (target && !target.dataset?.targethrefs) target = target.parentElement;
const editor = this._editorView;
- if (editor && target && !(e.nativeEvent as any).dash) {
+ if (editor && target && !(e.nativeEvent instanceof simMouseEvent ? e.nativeEvent.dash : false)) {
const hrefs = (target.dataset?.targethrefs as string)
?.trim()
.split(' ')