diff options
10 files changed, 189 insertions, 234 deletions
diff --git a/src/client/apis/gpt/customization.ts b/src/client/apis/gpt/customization.ts index 7da04918d..61b666bd3 100644 --- a/src/client/apis/gpt/customization.ts +++ b/src/client/apis/gpt/customization.ts @@ -103,7 +103,7 @@ export const getSlideTransitionSuggestions = async (inputText: string) => { } }; -export const gptTrailSlideCustomization = async (inputText: string, properties: any | any[], applyToWhole?: boolean) => { +export const gptTrailSlideCustomization = async (inputText: string, properties: any | any[]) => { let prompt = prompts.trails.description; prompts.trails.features.forEach(feature => { diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 24f50eb8b..df4ed98ac 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1044,32 +1044,30 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps setFinalNumber = () => { this._sliderBatch?.end(); }; - getNumber = (label: string, unit: string, min: number, max: number, number: number, setNumber: any, autorange?: number, autorangeMinVal?: number) => { - return ( - <div key={label + (this.selectedDoc?.title ?? '')}> - <NumberInput formLabel={label} formLabelPlacement="left" type={Type.SEC} unit={unit} fillWidth color={this.color} number={number} setNumber={setNumber} min={min} max={max} /> - <Slider - key={label} - onPointerDown={() => { - this._sliderBatch = UndoManager.StartBatch('slider ' + label); - }} - multithumb={false} - color={this.color} - size={Size.XSMALL} - min={min} - max={max} - autorangeMinVal={autorangeMinVal} - autorange={autorange} - number={number} - unit={unit} - decimals={1} - setFinalNumber={this.setFinalNumber} - setNumber={setNumber} - fillWidth - /> - </div> - ); - }; + getNumber = (label: string, unit: string, min: number, max: number, number: number, setNumber: any, autorange?: number, autorangeMinVal?: number) => ( + <div key={label + (this.selectedDoc?.title ?? '')}> + <NumberInput formLabel={label} formLabelPlacement="left" type={Type.SEC} unit={unit} fillWidth color={this.color} number={number} setNumber={setNumber} min={min} max={max} /> + <Slider + key={label} + onPointerDown={() => { + this._sliderBatch = UndoManager.StartBatch('slider ' + label); + }} + multithumb={false} + color={this.color} + size={Size.XSMALL} + min={min} + max={max} + autorangeMinVal={autorangeMinVal} + autorange={autorange} + number={number} + unit={unit} + decimals={1} + setFinalNumber={this.setFinalNumber} + setNumber={setNumber} + fillWidth + /> + </div> + ); setVal = (func: (doc: Doc, val: number) => void) => (val: number) => this.selectedDoc && !isNaN(val) && func(this.selectedDoc, val); @computed get transformEditor() { @@ -1770,12 +1768,14 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-presentationTrails"> <div className="propertiesView-presentationTrails-title" - onPointerDown={action(() => (this.openPresTransitions = !this.openPresTransitions))} + onPointerDown={action(() => { + this.openPresTransitions = !this.openPresTransitions; + })} style={{ color: SnappingManager.userColor, backgroundColor: this.openPresTransitions ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor, }}> - <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> Transitions + <FontAwesomeIcon style={{ alignSelf: 'center' }} icon="rocket" /> Transitions <div className="propertiesView-presentationTrails-title-icon"> <FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg" /> </div> @@ -1787,12 +1787,14 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-presentationTrails"> <div className="propertiesView-presentationTrails-title" - onPointerDown={action(() => (this.openPresVisibilityAndDuration = !this.openPresVisibilityAndDuration))} + onPointerDown={action(() => { + this.openPresVisibilityAndDuration = !this.openPresVisibilityAndDuration; + })} style={{ color: SnappingManager.userColor, backgroundColor: this.openPresVisibilityAndDuration ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor, }}> - <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> Visibility + <FontAwesomeIcon style={{ alignSelf: 'center' }} icon="rocket" /> Visibility <div className="propertiesView-presentationTrails-title-icon"> <FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" /> </div> @@ -1804,12 +1806,14 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-presentationTrails"> <div className="propertiesView-presentationTrails-title" - onPointerDown={action(() => (this.openPresProgressivize = !this.openPresProgressivize))} + onPointerDown={action(() => { + this.openPresProgressivize = !this.openPresProgressivize; + })} style={{ color: SnappingManager.userColor, backgroundColor: this.openPresProgressivize ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor, }}> - <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> Progressivize + <FontAwesomeIcon style={{ alignSelf: 'center' }} icon="rocket" /> Progressivize <div className="propertiesView-presentationTrails-title-icon"> <FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg" /> </div> @@ -1821,7 +1825,9 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-presentationTrails"> <div className="propertiesView-presentationTrails-title" - onPointerDown={action(() => (this.openSlideOptions = !this.openSlideOptions))} + onPointerDown={action(() => { + this.openSlideOptions = !this.openSlideOptions; + })} style={{ color: SnappingManager.userColor, backgroundColor: this.openSlideOptions ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor, diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 069132ec3..53493a968 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -14,6 +14,7 @@ import { DocData, Height, Width } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { InkData, InkField, InkTool, Segment } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; +import { RichTextField } from '../../../../fields/RichTextField'; import { listSpec } from '../../../../fields/Schema'; import { ScriptField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast, toList } from '../../../../fields/Types'; @@ -53,10 +54,6 @@ import { CollectionFreeFormPannableContents } from './CollectionFreeFormPannable import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCursors'; import './CollectionFreeFormView.scss'; import { MarqueeView } from './MarqueeView'; -import { PropertiesView } from '../../PropertiesView'; -import { ExtractColors } from '../../ExtractColors'; -import { extname } from 'path'; -import { RichTextField } from '../../../../fields/RichTextField'; class CollectionFreeFormOverlayView extends React.Component<{ elements: () => ViewDefResult[] }> { render() { diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index e91ed45c3..4d5f15a3e 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -14,6 +14,7 @@ import { Cast, CsvCast, DocCast, NumCast, StrCast } from '../../../../fields/Typ import { CsvField } from '../../../../fields/URLField'; import { TraceMobx } from '../../../../fields/util'; import { DocUtils } from '../../../documents/DocUtils'; +import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs } from '../../../documents/Documents'; import { UndoManager, undoable } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; @@ -31,7 +32,6 @@ import { Histogram } from './components/Histogram'; import { LineChart } from './components/LineChart'; import { PieChart } from './components/PieChart'; import { TableBox } from './components/TableBox'; -import { DocumentType } from '../../../documents/DocumentTypes'; export enum DataVizView { TABLE = 'table', @@ -127,8 +127,8 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @action // pinned / linked anchor doc includes selected rows, graph titles, and graph colors restoreView = (data: Doc) => { - const changedView = data.config_dataViz && this.dataVizView !== data.config_dataViz && (this.layoutDoc._dataViz = data.config_dataViz); - const changedAxes = data.config_dataVizAxes && this.axes.join('') !== StrListCast(data.config_dataVizAxes).join('') && (this.layoutDoc._dataViz_axes = new List<string>(StrListCast(data.config_dataVizAxes))); + // const changedView = data.config_dataViz && this.dataVizView !== data.config_dataViz && (this.layoutDoc._dataViz = data.config_dataViz); + // const changedAxes = data.config_dataVizAxes && this.axes.join('') !== StrListCast(data.config_dataVizAxes).join('') && (this.layoutDoc._dataViz_axes = new List<string>(StrListCast(data.config_dataVizAxes))); this.layoutDoc.dataViz_selectedRows = Field.Copy(data.dataViz_selectedRows); this.layoutDoc.dataViz_histogram_barColors = Field.Copy(data.dataViz_histogram_barColors); this.layoutDoc.dataViz_histogram_defaultColor = data.dataViz_histogram_defaultColor; diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx index ffced14f8..d055d269c 100644 --- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx @@ -1,6 +1,6 @@ import { Button, EditableText, Size } from 'browndash-components'; import * as d3 from 'd3'; -import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx'; +import { IReactionDisposer, action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, NumListCast, StrListCast } from '../../../../../fields/Doc'; diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx index d5410c1aa..19ea8e4fa 100644 --- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx @@ -93,7 +93,6 @@ export class PieChart extends ObservableReactComponent<PieChartProps> { // restore selected slices const svg = this._piechartSvg; if (svg && this._pieChartData[0]) { - const key = Object.keys(this._pieChartData[0])[0]; const selectedDataBars = StrListCast(this._props.layoutDoc.dataViz_pie_selectedData); svg.selectAll('path').attr('class', (d: any) => { let selected = false; diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index bcd8e54f2..a1deb1625 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -64,7 +64,10 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { // then we need to remove any selected rows that are no longer part of the visualized dataset. this._inputChangedDisposer = reaction(() => this._tableData.slice(), this.filterSelectedRowsDown, { fireImmediately: true }); const selected = NumListCast(this._props.layoutDoc.dataViz_selectedRows); - if (selected.length > 0) runInAction(() => (this.hasRowsToFilter = true)); + if (selected.length > 0) + runInAction(() => { + this.hasRowsToFilter = true; + }); this.handleScroll(); } componentWillUnmount() { diff --git a/src/client/views/nodes/trails/CubicBezierEditor.tsx b/src/client/views/nodes/trails/CubicBezierEditor.tsx index a5e21259a..e1ad1e6e5 100644 --- a/src/client/views/nodes/trails/CubicBezierEditor.tsx +++ b/src/client/views/nodes/trails/CubicBezierEditor.tsx @@ -3,7 +3,6 @@ import React, { useEffect, useState } from 'react'; type Props = { setFunc: (newPoints: { p1: number[]; p2: number[] }) => void; currPoints: { p1: number[]; p2: number[] }; - easeFunc: string; }; const ANIMATION_DURATION = 750; @@ -20,52 +19,50 @@ export const TIMING_DEFAULT_MAPPINGS = { 'ease-in-out': 'cubic-bezier(0.42, 0, 0.58, 1.0)', }; +export function EaseFuncToPoints(func: string) { + let strPoints = func || 'ease'; + if (!strPoints.startsWith('cubic')) { + switch (func) { + case 'linear': + strPoints = 'cubic-bezier(0.0, 0.0, 1.0, 1.0)'; + break; + case 'ease': + strPoints = 'cubic-bezier(0.25, 0.1, 0.25, 1.0)'; + break; + case 'ease-in': + strPoints = 'cubic-bezier(0.42, 0, 1.0, 1.0)'; + break; + case 'ease-out': + strPoints = 'cubic-bezier(0, 0, 0.58, 1.0)'; + break; + case 'ease-in-out': + strPoints = 'cubic-bezier(0.42, 0, 0.58, 1.0)'; + break; + default: + strPoints = 'cubic-bezier(0.25, 0.1, 0.25, 1.0)'; + } + } + const components = strPoints + .split('(')[1] + .split(')')[0] + .split(',') + .map(elem => parseFloat(elem)); + return { + p1: [components[0], components[1]], + p2: [components[2], components[3]], + }; +} + /** * Visual editor for a bezier curve with draggable control points. * */ -const CubicBezierEditor = ({ setFunc, currPoints, easeFunc }: Props) => { +function CubicBezierEditor({ setFunc, currPoints }: Props) { const [animating, setAnimating] = useState(false); const [c1Down, setC1Down] = useState(false); const [c2Down, setC2Down] = useState(false); - const roundToHundredth = (num: number) => { - return Math.round(num * 100) / 100; - }; - - const convertToPoints = (func: string) => { - let strPoints = func ? func : 'ease'; - if (!strPoints.startsWith('cubic')) { - switch (func) { - case 'linear': - strPoints = 'cubic-bezier(0.0, 0.0, 1.0, 1.0)'; - break; - case 'ease': - strPoints = 'cubic-bezier(0.25, 0.1, 0.25, 1.0)'; - break; - case 'ease-in': - strPoints = 'cubic-bezier(0.42, 0, 1.0, 1.0)'; - break; - case 'ease-out': - strPoints = 'cubic-bezier(0, 0, 0.58, 1.0)'; - break; - case 'ease-in-out': - strPoints = 'cubic-bezier(0.42, 0, 0.58, 1.0)'; - break; - default: - strPoints = 'cubic-bezier(0.25, 0.1, 0.25, 1.0)'; - } - } - const components = strPoints - .split('(')[1] - .split(')')[0] - .split(',') - .map(elem => parseFloat(elem)); - return { - p1: [components[0], components[1]], - p2: [components[2], components[3]], - }; - }; + const roundToHundredth = (num: number) => Math.round(num * 100) / 100; useEffect(() => { if (animating) { @@ -76,7 +73,7 @@ const CubicBezierEditor = ({ setFunc, currPoints, easeFunc }: Props) => { }, [animating]); useEffect(() => { - if (!c1Down) return; + if (!c1Down) return undefined; window.addEventListener('pointerup', () => { setC1Down(false); }); @@ -99,7 +96,7 @@ const CubicBezierEditor = ({ setFunc, currPoints, easeFunc }: Props) => { // Sets up pointer events for moving the control points useEffect(() => { - if (!c2Down) return; + if (!c2Down) return undefined; window.addEventListener('pointerup', () => { setC2Down(false); }); @@ -163,7 +160,7 @@ const CubicBezierEditor = ({ setFunc, currPoints, easeFunc }: Props) => { e.stopPropagation(); setC1Down(true); }} - onPointerUp={e => { + onPointerUp={() => { setC1Down(false); }} /> @@ -173,7 +170,7 @@ const CubicBezierEditor = ({ setFunc, currPoints, easeFunc }: Props) => { e.stopPropagation(); setC2Down(true); }} - onPointerUp={e => { + onPointerUp={() => { setC2Down(false); }} x1={`${EDITOR_WIDTH + OFFSET}`} @@ -193,13 +190,13 @@ const CubicBezierEditor = ({ setFunc, currPoints, easeFunc }: Props) => { e.stopPropagation(); setC2Down(true); }} - onPointerUp={e => { + onPointerUp={() => { setC2Down(false); }} /> </svg> </div> ); -}; +} export default CubicBezierEditor; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index c718b5b3c..69d03ac2e 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -2,9 +2,16 @@ /* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; +import Slider from '@mui/material/Slider'; +import { Button, Dropdown, DropdownType, IconButton, Toggle, ToggleType, Type } from 'browndash-components'; import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { AiOutlineSend } from 'react-icons/ai'; +import { BiMicrophone } from 'react-icons/bi'; +import { FaArrowDown, FaArrowLeft, FaArrowRight, FaArrowUp } from 'react-icons/fa'; +import ReactLoading from 'react-loading'; +import ReactTextareaAutosize from 'react-textarea-autosize'; import { lightOrDark, returnFalse, returnOne, setupMoveUpEvents, StopEvent } from '../../../../ClientUtils'; import { Doc, DocListCast, Field, FieldResult, FieldType, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; import { Animation, DocData, TransitionTimer } from '../../../../fields/DocSymbols'; @@ -16,9 +23,11 @@ import { listSpec } from '../../../../fields/Schema'; import { ComputedField, ScriptField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, NumCast, StrCast, toList } from '../../../../fields/Types'; import { emptyFunction, emptyPath, stringHash } from '../../../../Utils'; +import { getSlideTransitionSuggestions, gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/customization'; import { DocServer } from '../../../DocServer'; import { Docs } from '../../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; +import { DictationManager } from '../../../util/DictationManager'; import { dropActionType } from '../../../util/DropActionTypes'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { SerializationHelper } from '../../../util/SerializationHelper'; @@ -36,21 +45,12 @@ import { FieldView, FieldViewProps } from '../FieldView'; import { FocusViewOptions } from '../FocusViewOptions'; import { OpenWhere, OpenWhereMod } from '../OpenWhere'; import { ScriptingBox } from '../ScriptingBox'; +import CubicBezierEditor, { EaseFuncToPoints, TIMING_DEFAULT_MAPPINGS } from './CubicBezierEditor'; import './PresBox.scss'; -import ReactLoading from 'react-loading'; import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums'; -import ReactTextareaAutosize from 'react-textarea-autosize'; -import { Button, Dropdown, DropdownType, IconButton, Toggle, ToggleType, Type } from 'browndash-components'; -import { BiMicrophone } from 'react-icons/bi'; -import { AiOutlineSend } from 'react-icons/ai'; -import { getSlideTransitionSuggestions, gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/customization'; -import { DictationManager } from '../../../util/DictationManager'; -import CubicBezierEditor, { TIMING_DEFAULT_MAPPINGS } from './CubicBezierEditor'; -import Slider from '@mui/material/Slider'; -import { FaArrowDown, FaArrowLeft, FaArrowRight, FaArrowUp, FaCompressArrowsAlt } from 'react-icons/fa'; -import { effectTimings, SpringType, springMappings, effectItems, easeItems, movementItems, SpringSettings, presEffectDefaultTimings, AnimationSettings, springPreviewColors } from './SpringUtils'; import SlideEffect from './SlideEffect'; -import { IoMdInformationCircleOutline } from 'react-icons/io'; +import { AnimationSettings, easeItems, effectItems, effectTimings, movementItems, presEffectDefaultTimings, springMappings, springPreviewColors, SpringSettings, SpringType } from './SpringUtils'; + @observer export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { public static LayoutString(fieldKey: string) { @@ -162,9 +162,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }; @action - public setChatActive = (active: boolean) => {}; - - @action public setIsRecording = (isRecording: boolean) => { this.isRecording = isRecording; }; @@ -188,37 +185,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @computed get currCPoints() { - let strPoints = this.activeItem.presEaseFunc ? StrCast(this.activeItem.presEaseFunc) : 'ease'; - if (!strPoints.startsWith('cubic')) { - switch (StrCast(this.activeItem.presEaseFunc)) { - case 'linear': - strPoints = 'cubic-bezier(0.0, 0.0, 1.0, 1.0)'; - break; - case 'ease': - strPoints = 'cubic-bezier(0.25, 0.1, 0.25, 1.0)'; - break; - case 'ease-in': - strPoints = 'cubic-bezier(0.42, 0, 1.0, 1.0)'; - break; - case 'ease-out': - strPoints = 'cubic-bezier(0, 0, 0.58, 1.0)'; - break; - case 'ease-in-out': - strPoints = 'cubic-bezier(0.42, 0, 0.58, 1.0)'; - break; - default: - strPoints = 'cubic-bezier(0.25, 0.1, 0.25, 1.0)'; - } - } - const components = strPoints - .split('(')[1] - .split(')')[0] - .split(',') - .map(elem => parseFloat(elem)); - return { - p1: [components[0], components[1]], - p2: [components[2], components[3]], - }; + const strPoints = this.activeItem.presEaseFunc ? StrCast(this.activeItem.presEaseFunc) : 'ease'; + return EaseFuncToPoints(strPoints); } @computed @@ -364,7 +332,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } }); }; - stopDictation = (abort: boolean) => { + stopDictation = () => { this.setIsRecording(false); DictationManager.Controls.stop(); }; @@ -375,7 +343,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }; @action - customizeAnimations = async (input: string) => { + customizeAnimations = async () => { this.setIsLoading(true); try { const res = await getSlideTransitionSuggestions(this.animationChat); @@ -396,19 +364,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { this.setIsRecording(false); this.setIsLoading(true); - let currSlideProperties: { [key: string]: any } = {}; - for (const key of gptSlideProperties) { + const currSlideProperties: { [key: string]: any } = {}; + gptSlideProperties.forEach(key => { if (this.activeItem[key]) { currSlideProperties[key] = this.activeItem[key]; - } else { - // default values - if (key === 'presentation_transition') { - currSlideProperties[key] = 500; - } else if (key === 'config_zoom') { - currSlideProperties[key] = 1.0; - } } - } + // default values + else if (key === 'presentation_transition') { + currSlideProperties[key] = 500; + } else if (key === 'config_zoom') { + currSlideProperties[key] = 1.0; + } + }); console.log('current slide props ', currSlideProperties); try { @@ -416,7 +383,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (typeof res === 'string') { const resObj = JSON.parse(res); console.log('Parsed GPT Result ', resObj); - for (let key in resObj) { + // eslint-disable-next-line no-restricted-syntax + for (const key in resObj) { if (resObj[key]) { console.log('typeof property', typeof resObj[key]); this.activeItem[key] = resObj[key]; @@ -1612,10 +1580,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { doc.presEaseFunc = activeItem.presEaseFunc; }); }; - + setEaseFunc = (activeItem: Doc, easeFunc: string) => { activeItem.presEaseFunc = easeFunc; - this.selectedArray.forEach(doc => (doc.presEaseFunc = activeItem.presEaseFunc)); + this.selectedArray.forEach(doc => { + doc.presEaseFunc = activeItem.presEaseFunc; + }); }; @undoBatch @@ -1633,7 +1603,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @undoBatch updateEffectTiming = (activeItem: Doc, timing: SpringSettings) => { activeItem.presEffectTiming = JSON.stringify(timing); - this.selectedArray.forEach(doc => (doc.presEffectTiming = activeItem.presEffectTiming)); + this.selectedArray.forEach(doc => { + doc.presEffectTiming = activeItem.presEffectTiming; + }); }; static _sliderBatch: any; @@ -1702,7 +1674,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { Hide before </div> </Tooltip> - <Tooltip title={<div className="dash-tooltip">{'Hide while presented'}</div>}> + <Tooltip title={<div className="dash-tooltip">Hide while presented</div>}> <div className={`ribbon-toggle ${activeItem.presentation_hide ? 'active' : ''}`} style={{ border: `solid 1px ${SnappingManager.userColor}`, color: SnappingManager.userColor, background: activeItem.presentation_hide ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor }} @@ -1710,7 +1682,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { Hide </div> </Tooltip> - <Tooltip title={<div className="dash-tooltip">{'Hide after presented'}</div>}> + <Tooltip title={<div className="dash-tooltip">Hide after presented</div>}> <div className={`ribbon-toggle ${activeItem.presentation_hideAfter ? 'active' : ''}`} style={{ border: `solid 1px ${SnappingManager.userColor}`, color: SnappingManager.userColor, background: activeItem.presentation_hideAfter ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor }} @@ -1719,7 +1691,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { </div> </Tooltip> - <Tooltip title={<div className="dash-tooltip">{'Open in lightbox view'}</div>}> + <Tooltip title={<div className="dash-tooltip">Open in lightbox view</div>}> <div className="ribbon-toggle" style={{ @@ -1737,11 +1709,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <div className="ribbon-doubleButton"> <div className="presBox-subheading">Slide Duration</div> <div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}` }}> - <input className="presBox-input" type="number" readOnly={true} value={duration} onKeyDown={e => e.stopPropagation()} onChange={e => this.updateDurationTime(e.target.value)} /> s + <input className="presBox-input" type="number" readOnly value={duration} onKeyDown={e => e.stopPropagation()} onChange={e => this.updateDurationTime(e.target.value)} /> s </div> </div> {PresBox.inputter('0.1', '0.1', '20', duration, targetType !== DocumentType.AUDIO, this.updateDurationTime)} - <div className={'slider-headers'} style={{ display: targetType === DocumentType.AUDIO ? 'none' : 'grid' }}> + <div className="slider-headers" style={{ display: targetType === DocumentType.AUDIO ? 'none' : 'grid' }}> <div className="slider-text">Short</div> <div className="slider-text">Medium</div> <div className="slider-text">Long</div> @@ -1784,12 +1756,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // a progressivized slide doesn't have sub-slides, but rather iterates over the data list of the target being progressivized. // to avoid creating a new slide to correspond to each of the target's data list, we create a computedField to refernce the target's data list. let dataField = Doc.LayoutFieldKey(tagDoc); - if (Cast(tagDoc[dataField], listSpec(Doc), null)?.filter(d => d instanceof Doc) === undefined) dataField = dataField + '_annotations'; + if (Cast(tagDoc[dataField], listSpec(Doc), null)?.filter(d => d instanceof Doc) === undefined) dataField += '_annotations'; if (DocCast(activeItem.presentation_targetDoc).annotationOn) activeItem.data = ComputedField.MakeFunction(`this.presentation_targetDoc.annotationOn?.["${dataField}"]`); else activeItem.data = ComputedField.MakeFunction(`this.presentation_targetDoc?.["${dataField}"]`); }} - checked={Cast(activeItem.presentation_indexed, 'number', null) !== undefined ? true : false} + checked={Cast(activeItem.presentation_indexed, 'number', null) !== undefined} /> </div> <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}> @@ -1798,7 +1770,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { className="presBox-checkbox" style={{ margin: 10, border: `solid 1px ${SnappingManager.userColor}` }} type="checkbox" - onChange={() => (activeItem.presentation_indexedStart = activeItem.presentation_indexedStart ? 0 : 1)} + onChange={() => { + activeItem.presentation_indexedStart = activeItem.presentation_indexedStart ? 0 : 1; + }} checked={!NumCast(activeItem.presentation_indexedStart)} /> </div> @@ -1808,7 +1782,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { className="presBox-checkbox" style={{ margin: 10, border: `solid 1px ${SnappingManager.userColor}` }} type="checkbox" - onChange={() => (activeItem.presBulletExpand = !activeItem.presBulletExpand)} + onChange={() => { + activeItem.presBulletExpand = !activeItem.presBulletExpand; + }} checked={BoolCast(activeItem.presBulletExpand)} /> </div> @@ -1828,14 +1804,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { border: this._openBulletEffectDropdown ? `solid 2px ${SnappingManager.userVariantColor}` : `solid 1px ${SnappingManager.userColor}`, }}> {effect?.toString()} - <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openBulletEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} /> + <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openBulletEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon="angle-down" /> <div - className={'presBox-dropdownOptions'} + className="presBox-dropdownOptions" style={{ display: this._openBulletEffectDropdown ? 'grid' : 'none', color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }} onPointerDown={e => e.stopPropagation()}> {Object.values(PresEffect) .filter(v => isNaN(Number(v))) - .map(effect => bulletEffect(effect))} + .map(pEffect => bulletEffect(pEffect))} </div> </div> </div> @@ -1847,14 +1823,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } @computed get gptDropdown() { - const activeItem = this.activeItem; - return <div></div>; + return <div />; } @computed get transitionDropdown() { const { activeItem } = this; // Retrieving spring timing properties - let timing = StrCast(activeItem.presEffectTiming); + const timing = StrCast(activeItem.presEffectTiming); let timingConfig: SpringSettings | undefined; if (timing) { timingConfig = JSON.parse(timing); @@ -1869,32 +1844,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }; } - const presEffect = (effect: PresEffect) => ( - <div - className={`presBox-dropdownOption ${activeItem.presentation_effect === effect || (effect === PresEffect.None && !activeItem.presentation_effect) ? 'active' : ''}`} - onPointerDown={StopEvent} - onClick={() => this.updateEffect(effect, false)}> - {effect} - </div> - ); - const presMovement = (movement: PresMovement) => ( - <div className={`presBox-dropdownOption ${activeItem.presentation_movement === movement ? 'active' : ''}`} onPointerDown={StopEvent} onClick={() => this.updateMovement(movement)}> - {movement} - </div> - ); - const presDirection = (direction: PresEffectDirection, icon: string, gridColumn: number, gridRow: number, opts: object) => { - const color = activeItem.presentation_effectDirection === direction || (direction === PresEffectDirection.Center && !activeItem.presentation_effectDirection) ? SnappingManager.userVariantColor : SnappingManager.userColor; - return ( - <Tooltip title={<div className="dash-tooltip">{direction}</div>}> - <div - style={{ ...opts, border: direction === PresEffectDirection.Center ? `solid 2px ${color}` : undefined, borderRadius: '100%', cursor: 'pointer', gridColumn, gridRow, justifySelf: 'center', color }} - onClick={() => this.updateEffectDirection(direction)}> - {icon ? <FontAwesomeIcon icon={icon as any} /> : null} - </div> - </Tooltip> - ); - }; - if (activeItem && this.targetDoc) { const transitionSpeed = activeItem.presentation_transition ? NumCast(activeItem.presentation_transition) / 1000 : 0.5; const zoom = NumCast(activeItem.config_zoom, 1) * 100; @@ -1903,7 +1852,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { return ( <> - {/* This chatbox is for customizing the properties of trails, like transition time, movement type (zoom, pan) using GPT*/} + {/* This chatbox is for customizing the properties of trails, like transition time, movement type (zoom, pan) using GPT */} <div className="presBox-gpt-chat"> <span style={{ display: 'flex', alignItems: 'center', gap: '8px' }}> Customize Slide Properties{' '} @@ -1921,7 +1870,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { this.setChatInput(e.target.value); }} onKeyDown={e => { - this.stopDictation(true); + this.stopDictation(); e.stopPropagation(); }} /> @@ -1929,12 +1878,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { type={Type.TERT} color={this.isRecording ? '#2bcaff' : StrCast(Doc.UserDoc().userVariantColor)} tooltip="Record" - icon={<BiMicrophone size={'16px'} />} + icon={<BiMicrophone size="16px" />} onClick={() => { if (!this.isRecording) { this.recordDictation(); } else { - this.stopDictation(true); + this.stopDictation(); } }} /> @@ -1943,11 +1892,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { style={{ alignSelf: 'flex-end' }} text="Send" type={Type.TERT} - icon={this.isLoading ? <ReactLoading type="spin" color={'#ffffff'} width={20} height={20} /> : <AiOutlineSend />} + icon={this.isLoading ? <ReactLoading type="spin" color="#ffffff" width={20} height={20} /> : <AiOutlineSend />} iconPlacement="right" color={StrCast(Doc.UserDoc().userVariantColor)} onClick={() => { - this.stopDictation(true); + this.stopDictation(); this.customizeWithGPT(this.chatInput); }} /> @@ -1971,8 +1920,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { Movement <Dropdown color={StrCast(Doc.UserDoc().userColor)} - formLabel={'Movement'} - closeOnSelect={true} + formLabel="Movement" + closeOnSelect items={movementItems} selectedVal={this.movementName(activeItem)} setSelectedVal={val => { @@ -1984,18 +1933,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <div className="ribbon-doubleButton" style={{ display: activeItem.presentation_movement === PresMovement.Zoom ? 'inline-flex' : 'none' }}> <div className="presBox-subheading">Zoom (% screen filled)</div> <div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}` }}> - <input className="presBox-input" readOnly={true} type="number" value={zoom} onChange={e => this.updateZoom(e.target.value)} />% + <input className="presBox-input" readOnly type="number" value={zoom} onChange={e => this.updateZoom(e.target.value)} />% </div> </div> {PresBox.inputter('0', '1', '100', zoom, activeItem.presentation_movement === PresMovement.Zoom, this.updateZoom)} <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}> <div className="presBox-subheading">Transition Time</div> <div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}` }}> - <input className="presBox-input" type="number" readOnly={true} value={transitionSpeed} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.updateTransitionTime(e.target.value))} /> s + <input className="presBox-input" type="number" readOnly value={transitionSpeed} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.updateTransitionTime(e.target.value))} /> s </div> </div> {PresBox.inputter('0.1', '0.1', '10', transitionSpeed, true, this.updateTransitionTime)} - <div className={'slider-headers'}> + <div className="slider-headers"> <div className="slider-text">Fast</div> <div className="slider-text">Medium</div> <div className="slider-text">Slow</div> @@ -2003,8 +1952,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { {/* Easing function */} <Dropdown color={StrCast(Doc.UserDoc().userColor)} - formLabel={'Easing Function'} - closeOnSelect={true} + formLabel="Easing Function" + closeOnSelect items={easeItems} selectedVal={this.activeItem.presEaseFunc ? (StrCast(this.activeItem.presEaseFunc).startsWith('cubic') ? 'custom' : StrCast(this.activeItem.presEaseFunc)) : 'ease'} setSelectedVal={val => { @@ -2040,7 +1989,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <p className="presBox-submenu-label" style={{ alignSelf: 'flex-start' }}> Custom Timing Function </p> - <CubicBezierEditor setFunc={this.setBezierControlPoints} currPoints={this.currCPoints} easeFunc={StrCast(this.activeItem.presEaseFunc)} /> + <CubicBezierEditor setFunc={this.setBezierControlPoints} currPoints={this.currCPoints} /> </div> )} @@ -2057,7 +2006,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { this.setAnimationChat(e.target.value); }} onKeyDown={e => { - this.stopDictation(true); + this.stopDictation(); e.stopPropagation(); }} /> @@ -2066,12 +2015,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { style={{ alignSelf: 'flex-end' }} text="Send" type={Type.TERT} - icon={this.isLoading ? <ReactLoading type="spin" color={'#ffffff'} width={20} height={20} /> : <AiOutlineSend />} + icon={this.isLoading ? <ReactLoading type="spin" color="#ffffff" width={20} height={20} /> : <AiOutlineSend />} iconPlacement="right" color={StrCast(Doc.UserDoc().userVariantColor)} - onClick={() => { - this.customizeAnimations(this.animationChat); - }} + onClick={this.customizeAnimations} /> </div> </div> @@ -2093,6 +2040,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <div className="presBox-effects"> {this.generatedAnimations.map((elem, i) => ( <div + // eslint-disable-next-line react/no-array-index-key key={i} className="presBox-effect-container" onClick={() => { @@ -2106,7 +2054,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }); }}> <SlideEffect dir={elem.direction as PresEffectDirection} presEffect={elem.effect as PresEffect} tension={elem.stiffness} friction={elem.damping} mass={elem.mass} infinite> - <div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[i] }}></div> + <div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[i] }} /> </SlideEffect> </div> ))} @@ -2115,8 +2063,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { {/* Effect dropdown */} <Dropdown color={StrCast(Doc.UserDoc().userColor)} - formLabel={'Slide Effect'} - closeOnSelect={true} + formLabel="Slide Effect" + closeOnSelect items={effectItems} selectedVal={effect?.toString()} setSelectedVal={val => { @@ -2142,14 +2090,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { type={Type.TERT} color={activeItem.presentation_effectDirection === PresEffectDirection.Left ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor} tooltip="Left" - icon={<FaArrowRight size={'16px'} />} + icon={<FaArrowRight size="16px" />} onClick={() => this.updateEffectDirection(PresEffectDirection.Left)} /> <IconButton type={Type.TERT} color={activeItem.presentation_effectDirection === PresEffectDirection.Right ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor} tooltip="Right" - icon={<FaArrowLeft size={'16px'} />} + icon={<FaArrowLeft size="16px" />} onClick={() => this.updateEffectDirection(PresEffectDirection.Right)} /> {effect !== PresEffect.Roll && ( @@ -2158,14 +2106,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { type={Type.TERT} color={activeItem.presentation_effectDirection === PresEffectDirection.Top ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor} tooltip="Top" - icon={<FaArrowDown size={'16px'} />} + icon={<FaArrowDown size="16px" />} onClick={() => this.updateEffectDirection(PresEffectDirection.Top)} /> <IconButton type={Type.TERT} color={activeItem.presentation_effectDirection === PresEffectDirection.Bottom ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor} tooltip="Bottom" - icon={<FaArrowUp size={'16px'} />} + icon={<FaArrowUp size="16px" />} onClick={() => this.updateEffectDirection(PresEffectDirection.Bottom)} /> </> @@ -2179,8 +2127,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <> <Dropdown color={StrCast(Doc.UserDoc().userColor)} - formLabel={'Effect Timing'} - closeOnSelect={true} + formLabel="Effect Timing" + closeOnSelect items={effectTimings} selectedVal={timingConfig.type} setSelectedVal={val => { @@ -2261,7 +2209,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <div className="presBox-option-block presBox-option-center"> <div className="presBox-effect-container"> <SlideEffect dir={direction as PresEffectDirection} presEffect={effect as PresEffect} tension={timingConfig.stiffness} friction={timingConfig.damping} mass={timingConfig.mass} infinite> - <div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[0] }}></div> + <div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[0] }} /> </SlideEffect> </div> </div> @@ -2274,17 +2222,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { {/* Toggles */} <div className="presBox-option-block"> <Toggle - formLabel={'Play Audio Annotation'} + formLabel="Play Audio Annotation" toggleType={ToggleType.SWITCH} toggleStatus={BoolCast(activeItem.presPlayAudio)} - onClick={() => (activeItem.presPlayAudio = !BoolCast(activeItem.presPlayAudio))} + onClick={() => { + activeItem.presPlayAudio = !BoolCast(activeItem.presPlayAudio); + }} color={SnappingManager.userColor} /> <Toggle - formLabel={'Zoom Text Selections'} + formLabel="Zoom Text Selections" toggleType={ToggleType.SWITCH} toggleStatus={BoolCast(activeItem.presentation_zoomText)} - onClick={() => (activeItem.presentation_zoomText = !BoolCast(activeItem.presentation_zoomText))} + onClick={() => { + activeItem.presentation_zoomText = !BoolCast(activeItem.presentation_zoomText); + }} color={SnappingManager.userColor} /> <Button text="Apply to all" type={Type.TERT} color={StrCast(Doc.UserDoc().userVariantColor)} onClick={() => this.applyTo(this.childDocs)} /> @@ -3148,7 +3100,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } */} </div> {/* presbox chatbox */} - {this.chatActive && <div className="presBox-chatbox"></div>} + {this.chatActive && <div className="presBox-chatbox" />} </div> ); } diff --git a/src/client/views/nodes/trails/SlideEffect.tsx b/src/client/views/nodes/trails/SlideEffect.tsx index e0be86875..03cd88f45 100644 --- a/src/client/views/nodes/trails/SlideEffect.tsx +++ b/src/client/views/nodes/trails/SlideEffect.tsx @@ -1,9 +1,10 @@ -import { useSpring, animated, easings, to, useInView } from '@react-spring/web'; -import React, { useEffect, useState } from 'react'; -import { PresEffect, PresEffectDirection } from './PresEnums'; -import './SlideEffect.scss'; +/* eslint-disable react/require-default-props */ +import { animated, to, useInView, useSpring } from '@react-spring/web'; +import React, { useEffect } from 'react'; import { Doc } from '../../../../fields/Doc'; import { NumCast } from '../../../../fields/Types'; +import { PresEffect, PresEffectDirection } from './PresEnums'; +import './SlideEffect.scss'; interface SlideEffectProps { // pass in doc to extract width, height, bg @@ -296,7 +297,7 @@ export default function SpringAnimation({ doc, dir, friction, tension, mass, pre {dir === PresEffectDirection.Bottom || dir === PresEffectDirection.Top ? ( <> <animated.div - className={'flip-side flip-back'} + className="flip-side flip-back" style={{ transform: to(springs.x, val => `perspective(600px) rotateX(${val}deg)`), width: doc ? NumCast(doc.width) : DEFAULT_WIDTH, @@ -305,7 +306,7 @@ export default function SpringAnimation({ doc, dir, friction, tension, mass, pre }} /> <animated.div - className={'flip-side flip-front'} + className="flip-side flip-front" style={{ transform: to(springs.x, val => `perspective(600px) rotateX(${val}deg)`), rotateX: '180deg', width: doc ? NumCast(doc.width) : DEFAULT_WIDTH, height: doc ? NumCast(doc.height) : DEFAULT_WIDTH }}> {children} </animated.div> @@ -313,11 +314,11 @@ export default function SpringAnimation({ doc, dir, friction, tension, mass, pre ) : ( <> <animated.div - className={'flip-side flip-back'} + className="flip-side flip-back" style={{ transform: to(springs.x, val => `perspective(600px) rotateY(${val}deg)`), width: doc ? NumCast(doc.width) : DEFAULT_WIDTH, height: doc ? NumCast(doc.height) : DEFAULT_WIDTH }} /> <animated.div - className={'flip-side flip-front'} + className="flip-side flip-front" style={{ transform: to(springs.x, val => `perspective(600px) rotateY(${val}deg)`), rotateY: '180deg', width: doc ? NumCast(doc.width) : DEFAULT_WIDTH, height: doc ? NumCast(doc.height) : DEFAULT_WIDTH }}> {children} </animated.div> |