diff options
Diffstat (limited to 'src/client')
146 files changed, 1733 insertions, 1690 deletions
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index 353e11775..df92fe50e 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -7,6 +7,7 @@ import { HandleUpdate, Id, Parent } from '../fields/FieldSymbols'; import { ObjectField } from '../fields/ObjectField'; import { RefField } from '../fields/RefField'; import { DocCast, StrCast } from '../fields/Types'; +import { Socket } from '../../node_modules/socket.io/dist/index'; //import MobileInkOverlay from '../mobile/MobileInkOverlay'; import { emptyFunction, Utils } from '../Utils'; import { GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, YoutubeQueryTypes } from './../server/Message'; @@ -76,7 +77,7 @@ export namespace DocServer { json: true, }); } - export let _socket: SocketIOClient.Socket; + export let _socket: Socket; // this client's distinct GUID created at initialization let USER_ID: string; // indicates whether or not a document is currently being udpated, and, if so, its id @@ -189,20 +190,20 @@ export namespace DocServer { Utils.AddServerHandler(_socket, MessageStore.DeleteFields, respondToDelete); Utils.AddServerHandler(_socket, MessageStore.ConnectionTerminated, alertUser); - // mobile ink overlay socket events to communicate between mobile view and desktop view - _socket.addEventListener('receiveGesturePoints', (content: GestureContent) => { - // MobileInkOverlay.Instance.drawStroke(content); - }); - _socket.addEventListener('receiveOverlayTrigger', (content: MobileInkOverlayContent) => { - //GestureOverlay.Instance.enableMobileInkOverlay(content); - // MobileInkOverlay.Instance.initMobileInkOverlay(content); - }); - _socket.addEventListener('receiveUpdateOverlayPosition', (content: UpdateMobileInkOverlayPositionContent) => { - // MobileInkOverlay.Instance.updatePosition(content); - }); - _socket.addEventListener('receiveMobileDocumentUpload', (content: MobileDocumentUploadContent) => { - // MobileInkOverlay.Instance.uploadDocument(content); - }); + // // mobile ink overlay socket events to communicate between mobile view and desktop view + // _socket.addEventListener('receiveGesturePoints', (content: GestureContent) => { + // // MobileInkOverlay.Instance.drawStroke(content); + // }); + // _socket.addEventListener('receiveOverlayTrigger', (content: MobileInkOverlayContent) => { + // //GestureOverlay.Instance.enableMobileInkOverlay(content); + // // MobileInkOverlay.Instance.initMobileInkOverlay(content); + // }); + // _socket.addEventListener('receiveUpdateOverlayPosition', (content: UpdateMobileInkOverlayPositionContent) => { + // // MobileInkOverlay.Instance.updatePosition(content); + // }); + // _socket.addEventListener('receiveMobileDocumentUpload', (content: MobileDocumentUploadContent) => { + // // MobileInkOverlay.Instance.uploadDocument(content); + // }); } function errorFunc(): never { @@ -470,10 +471,13 @@ export namespace DocServer { // to their actual RefField | undefined values. This return value either becomes the input // argument to the caller's promise (i.e. GetRefFields(["_id1_", "_id2_", "_id3_"]).then(map => //do something with map...)) // or it is the direct return result if the promise is awaited (i.e. let fields = await GetRefFields(["_id1_", "_id2_", "_id3_"])). - return ids.reduce((map, id) => { - map[id] = _cache[id] as any; - return map; - }, {} as { [id: string]: Opt<RefField> }); + return ids.reduce( + (map, id) => { + map[id] = _cache[id] as any; + return map; + }, + {} as { [id: string]: Opt<RefField> } + ); }; let _GetRefFields: (ids: string[]) => Promise<{ [id: string]: Opt<RefField> }> = errorFunc; diff --git a/src/client/Network.ts b/src/client/Network.ts index 89b31fdca..cdcd5225a 100644 --- a/src/client/Network.ts +++ b/src/client/Network.ts @@ -1,5 +1,5 @@ import { Utils } from '../Utils'; -import requestPromise = require('request-promise'); +import * as requestPromise from 'request-promise'; import { Upload } from '../server/SharedMediaTypes'; /** diff --git a/src/client/apis/google_docs/GoogleApiClientUtils.ts b/src/client/apis/google_docs/GoogleApiClientUtils.ts index 551dca073..c8f381cc0 100644 --- a/src/client/apis/google_docs/GoogleApiClientUtils.ts +++ b/src/client/apis/google_docs/GoogleApiClientUtils.ts @@ -84,7 +84,7 @@ export namespace GoogleApiClientUtils { }; try { const schema: docs_v1.Schema$Document = await Networking.PostToServer(path, parameters); - return schema.documentId; + return schema.documentId === null ? undefined : schema.documentId; } catch { return undefined; } @@ -195,7 +195,7 @@ export namespace GoogleApiClientUtils { const title = document.title; let bodyLines = Utils.extractText(document).text.split("\n"); options.removeNewlines && (bodyLines = bodyLines.filter(line => line.length)); - return { title, bodyLines }; + return { title: title ?? "", bodyLines }; } }); }; diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index 6bde7989b..85634bc8b 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -1,4 +1,4 @@ -import { Configuration, OpenAIApi } from 'openai'; +import { ClientOptions, OpenAI } from 'openai'; enum GPTCallType { SUMMARY = 'summary', @@ -29,17 +29,17 @@ const gptAPICall = async (inputText: string, callType: GPTCallType) => { if (callType === GPTCallType.SUMMARY) inputText += '.'; const opts: GPTCallOpts = callTypeMap[callType]; try { - const configuration = new Configuration({ + const configuration:ClientOptions ={ apiKey: process.env.OPENAI_KEY, - }); - const openai = new OpenAIApi(configuration); - const response = await openai.createCompletion({ + }; + const openai = new OpenAI(configuration); + const response = await openai.completions.create({ model: opts.model, max_tokens: opts.maxTokens, temperature: opts.temp, prompt: `${opts.prompt}${inputText}`, }); - return response.data.choices[0].text; + return response.choices[0].text; } catch (err) { console.log(err); return 'Error connecting with API.'; @@ -48,16 +48,16 @@ const gptAPICall = async (inputText: string, callType: GPTCallType) => { const gptImageCall = async (prompt: string, n?: number) => { try { - const configuration = new Configuration({ + const configuration:ClientOptions = { apiKey: process.env.OPENAI_KEY, - }); - const openai = new OpenAIApi(configuration); - const response = await openai.createImage({ + }; + const openai = new OpenAI(configuration); + const response = await openai.images.generate({ prompt: prompt, n: n ?? 1, size: '1024x1024', }); - return response.data.data.map(data => data.url); + return response.data.map((data:any) => data.url); // return response.data.data[0].url; } catch (err) { console.error(err); diff --git a/src/client/apis/youtube/YoutubeBox.tsx b/src/client/apis/youtube/YoutubeBox.tsx index 2da9927c0..ceb80acbc 100644 --- a/src/client/apis/youtube/YoutubeBox.tsx +++ b/src/client/apis/youtube/YoutubeBox.tsx @@ -10,7 +10,7 @@ import { DocumentView } from '../../views/nodes/DocumentView'; import { FieldView, FieldViewProps } from '../../views/nodes/FieldView'; import '../../views/nodes/WebBox.scss'; import './YoutubeBox.scss'; -import React = require('react'); +import * as React from 'react'; interface VideoTemplate { thumbnailUrl: string; diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 929660ff4..4ec100728 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -30,7 +30,6 @@ import { DimUnit } from '../views/collections/collectionMulticolumn/CollectionMu import { CollectionView } from '../views/collections/CollectionView'; import { ContextMenu } from '../views/ContextMenu'; import { ContextMenuProps } from '../views/ContextMenuItem'; -import { DFLT_IMAGE_NATIVE_DIM } from '../views/global/globalCssVariables.scss'; import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke } from '../views/InkingStroke'; import { AudioBox, media_state } from '../views/nodes/AudioBox'; import { ColorBox } from '../views/nodes/ColorBox'; @@ -61,6 +60,8 @@ import { VideoBox } from '../views/nodes/VideoBox'; import { WebBox } from '../views/nodes/WebBox'; import { SearchBox } from '../views/search/SearchBox'; import { CollectionViewType, DocumentType } from './DocumentTypes'; +//import { DFLT_IMAGE_NATIVE_DIM } from '../views/global/globalCssVariables.scss'; +const DFLT_IMAGE_NATIVE_DIM = '900px'; const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', '')); class EmptyBox { @@ -1299,7 +1300,7 @@ export namespace DocUtils { // links are not a field value, so handled here. value is an expression of form ([field=]idToDoc("...")) const allLinks = LinkManager.Instance.getAllRelatedLinks(doc); const matchLink = (value: string, anchor: Doc) => { - const linkedToExp = value?.split('='); + const linkedToExp = (value ?? '').split('='); if (linkedToExp.length === 1) return Field.toScriptString(anchor) === value; return Field.toScriptString(DocCast(anchor[linkedToExp[0]])) === linkedToExp[1]; }; @@ -1909,7 +1910,7 @@ export namespace DocUtils { const generatedDocuments: Doc[] = []; Networking.UploadYoutubeToServer(videoId, overwriteDoc?.[Id]).then(upfiles => { const { - source: { name, type }, + source: { newFilename, originalFilename, mimetype }, result, } = upfiles.lastElement(); if ((result as any).message) { @@ -1918,7 +1919,7 @@ export namespace DocUtils { overwriteDoc.loadingError = (result as any).message; LoadingBox.removeCurrentlyLoading(overwriteDoc); } - } else name && processFileupload(generatedDocuments, name, type, result, options, overwriteDoc); + } else newFilename && processFileupload(generatedDocuments, newFilename, mimetype ?? '', result, options, overwriteDoc); }); } @@ -1938,10 +1939,10 @@ export namespace DocUtils { const upfiles = await Networking.UploadFilesToServer(fileNoGuidPairs); for (const { - source: { name, type }, + source: { newFilename, mimetype }, result, } of upfiles) { - name && type && processFileupload(generatedDocuments, name, type, result, options); + newFilename && mimetype && processFileupload(generatedDocuments, newFilename, mimetype, result, options); } return generatedDocuments; } @@ -1951,15 +1952,15 @@ export namespace DocUtils { // Since this file has an overwriteDoc, we can set the client tracking guid to the overwriteDoc's guid. Networking.UploadFilesToServer([{ file, guid: overwriteDoc[Id] }]).then(upfiles => { const { - source: { name, type }, + source: { newFilename, mimetype }, result, - } = upfiles.lastElement() ?? { source: { name: '', type: '' }, result: { message: 'upload failed' } }; + } = upfiles.lastElement() ?? { source: { newFilename: '', mimetype: '' }, result: { message: 'upload failed' } }; if ((result as any).message) { if (overwriteDoc) { overwriteDoc.loadingError = (result as any).message; LoadingBox.removeCurrentlyLoading(overwriteDoc); } - } else name && type && processFileupload(generatedDocuments, name, type, result, options, overwriteDoc); + } else newFilename && mimetype && processFileupload(generatedDocuments, newFilename, mimetype, result, options, overwriteDoc); }); } diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index d3ed4ca7c..8b5f23aa4 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -561,7 +561,7 @@ export class CurrentUserUtils { toolTip: "Empty recently closed",}; DocUtils.AssignDocField(recentlyClosed, "layout_headerButton", (opts) => Docs.Create.FontIconDocument(opts), clearBtnsOpts, undefined, {onClick: clearAll("this.target")}); - if (!Cast(recentlyClosed.contextMenuScripts, listSpec(ScriptField),null)?.find((script) => script.script.originalScript === clearAll("self"))) { + if (!Cast(recentlyClosed.contextMenuScripts, listSpec(ScriptField),null)?.find((script) => script?.script.originalScript === clearAll("self"))) { recentlyClosed.contextMenuScripts = new List<ScriptField>([ScriptField.MakeScript(clearAll("self"))!]) } return recentlyClosed; @@ -946,7 +946,7 @@ export class CurrentUserUtils { runInAction(() => CurrentUserUtils.ServerVersion = result.version); Doc.CurrentUserEmail = result.email; resolvedPorts = result.resolvedPorts as any; - DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts.socket, result.email); + DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts?.socket, result.email); if (result.cacheDocumentIds) { const ids = result.cacheDocumentIds.split(";"); diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 162a0a11f..427b1c85f 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -7,13 +7,14 @@ import { ScriptField } from '../../fields/ScriptField'; import { ScriptCast, StrCast } from '../../fields/Types'; import { emptyFunction, Utils } from '../../Utils'; import { Docs, DocUtils } from '../documents/Documents'; -import * as globalCssVariables from '../views/global/globalCssVariables.scss'; import { CollectionFreeFormDocumentView } from '../views/nodes/CollectionFreeFormDocumentView'; import { DocumentView } from '../views/nodes/DocumentView'; import { ScriptingGlobals } from './ScriptingGlobals'; import { SelectionManager } from './SelectionManager'; import { SnappingManager } from './SnappingManager'; import { UndoManager } from './UndoManager'; +// import * as globalCssVariables from '../views/global/globalCssVariables.scss'; +const contextMenuZindex = 100002; export type dropActionType = 'embed' | 'copy' | 'move' | 'add' | 'same' | 'inSame' | 'proto' | 'none' | undefined; // undefined = move, "same" = move but don't call dropPropertiesToRemove @@ -85,7 +86,16 @@ export namespace DragManager { // event called when the drag operation results in a drop action export class DropEvent { - constructor(readonly x: number, readonly y: number, readonly complete: DragCompleteEvent, readonly shiftKey: boolean, readonly altKey: boolean, readonly metaKey: boolean, readonly ctrlKey: boolean, readonly embedKey: boolean) {} + constructor( + readonly x: number, + readonly y: number, + readonly complete: DragCompleteEvent, + readonly shiftKey: boolean, + readonly altKey: boolean, + readonly metaKey: boolean, + readonly ctrlKey: boolean, + readonly embedKey: boolean + ) {} } // event called when the drag operation has completed (aborted or completed a drop) -- this will be after any drop event has been generated @@ -209,16 +219,14 @@ export namespace DragManager { !dragData.isDocDecorationMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) : docDragData.dropAction === 'embed' - ? Doc.BestEmbedding(d) - : docDragData.dropAction === 'add' - ? d - : docDragData.dropAction === 'proto' - ? Doc.GetProto(d) - : docDragData.dropAction === 'copy' - ? ( - await Doc.MakeClone(d) - ).clone - : d + ? Doc.BestEmbedding(d) + : docDragData.dropAction === 'add' + ? d + : docDragData.dropAction === 'proto' + ? Doc.GetProto(d) + : docDragData.dropAction === 'copy' + ? (await Doc.MakeClone(d)).clone + : d ) ) ).filter(d => d); @@ -428,7 +436,7 @@ export namespace DragManager { color: 'black', transition: 'none', borderRadius: getComputedStyle(ele).borderRadius, - zIndex: globalCssVariables.contextMenuZindex, + zIndex: contextMenuZindex, transformOrigin: '0 0', width, height, diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx index 8973306bf..c8c93b7d0 100644 --- a/src/client/util/GroupManager.tsx +++ b/src/client/util/GroupManager.tsx @@ -52,7 +52,7 @@ export class GroupManager extends React.Component<{}> { * Fetches the list of users stored on the database. */ populateUsers = async () => { - if (Doc.UserDoc()[Id] !== '__guest__') { + if (Doc.UserDoc()[Id] !== Utils.GuestID()) { const userList = await RequestPromise.get(Utils.prepend('/getUsers')); const raw = JSON.parse(userList) as User[]; raw.map(action(user => !this.users.some(umail => umail === user.email) && this.users.push(user.email))); @@ -258,10 +258,7 @@ export class GroupManager extends React.Component<{}> { alert('Please select a unique group name'); return; } - this.createGroupDoc( - value, - this.selectedUsers?.map(user => user.value) - ); + this.createGroupDoc(value, this.selectedUsers?.map(user => user.value)); this.selectedUsers = null; this.inputRef.current!.value = ''; this.buttonColour = '#979797'; diff --git a/src/client/util/History.ts b/src/client/util/History.ts index 18aee6444..2f1a336cc 100644 --- a/src/client/util/History.ts +++ b/src/client/util/History.ts @@ -85,7 +85,7 @@ export namespace HistoryUtil { }; function addParser(type: string, requiredFields: Parser, optionalFields: Parser, customParser?: (pathname: string[], opts: qs.ParsedQuery, current: ParsedUrl) => ParsedUrl | null | undefined) { - function parse(parser: ParserValue, value: string | string[] | null | undefined) { + function parse(parser: ParserValue, value: string | (string | null)[] | null | undefined) { if (value === undefined || value === null) { return value; } diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index c45143f43..30e448797 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -20,8 +20,8 @@ import { FieldView, FieldViewProps } from '../../views/nodes/FieldView'; import { DocumentManager } from '../DocumentManager'; import './DirectoryImportBox.scss'; import ImportMetadataEntry, { keyPlaceholder, valuePlaceholder } from './ImportMetadataEntry'; -import React = require('react'); -import _ = require('lodash'); +import * as React from 'react'; +import * as _ from 'lodash'; const unsupported = ['text/html', 'text/plain']; @@ -119,7 +119,7 @@ export class DirectoryImportBox extends React.Component<FieldViewProps> { await Promise.all( uploads.map(async response => { const { - source: { type }, + source: { mimetype }, result, } = response; if (result instanceof Error) { @@ -127,7 +127,7 @@ export class DirectoryImportBox extends React.Component<FieldViewProps> { } const { accessPaths, exifData } = result; const path = Utils.prepend(accessPaths.agnostic.client); - const document = type && (await DocUtils.DocumentFromType(type, path, { _width: 300 })); + const document = mimetype && (await DocUtils.DocumentFromType(mimetype, path, { _width: 300 })); const { data, error } = exifData; if (document) { Doc.GetProto(document).exif = error || Doc.Get.FromJson({ data }); diff --git a/src/client/util/Import & Export/ImportMetadataEntry.tsx b/src/client/util/Import & Export/ImportMetadataEntry.tsx index 45d8c0c63..58a09b9c9 100644 --- a/src/client/util/Import & Export/ImportMetadataEntry.tsx +++ b/src/client/util/Import & Export/ImportMetadataEntry.tsx @@ -1,10 +1,10 @@ -import React = require("react"); -import { observer } from "mobx-react"; -import { EditableView } from "../../views/EditableView"; -import { action, computed } from "mobx"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Doc } from "../../../fields/Doc"; -import { StrCast, BoolCast } from "../../../fields/Types"; +import * as React from 'react'; +import { observer } from 'mobx-react'; +import { EditableView } from '../../views/EditableView'; +import { action, computed } from 'mobx'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Doc } from '../../../fields/Doc'; +import { StrCast, BoolCast } from '../../../fields/Types'; interface KeyValueProps { Document: Doc; @@ -12,19 +12,18 @@ interface KeyValueProps { next: () => void; } -export const keyPlaceholder = "Key"; -export const valuePlaceholder = "Value"; +export const keyPlaceholder = 'Key'; +export const valuePlaceholder = 'Value'; @observer export default class ImportMetadataEntry extends React.Component<KeyValueProps> { - private keyRef = React.createRef<EditableView>(); private valueRef = React.createRef<EditableView>(); private checkRef = React.createRef<HTMLInputElement>(); @computed public get valid() { - return (this.key.length > 0 && this.key !== keyPlaceholder) && (this.value.length > 0 && this.value !== valuePlaceholder); + return this.key.length > 0 && this.key !== keyPlaceholder && this.value.length > 0 && this.value !== valuePlaceholder; } @computed @@ -66,7 +65,7 @@ export default class ImportMetadataEntry extends React.Component<KeyValueProps> this.valueRef.current && this.valueRef.current.setIsFocused(true); this.key.length === 0 && (this.key = keyPlaceholder); return true; - } + }; @action updateValue = (newValue: string, shiftDown: boolean) => { @@ -75,68 +74,45 @@ export default class ImportMetadataEntry extends React.Component<KeyValueProps> this.value.length > 0 && shiftDown && this.props.next(); this.value.length === 0 && (this.value = valuePlaceholder); return true; - } + }; render() { const keyValueStyle: React.CSSProperties = { paddingLeft: 10, - width: "50%", + width: '50%', opacity: this.valid ? 1 : 0.5, }; return ( <div style={{ - display: "flex", - flexDirection: "row", + display: 'flex', + flexDirection: 'row', paddingBottom: 5, paddingRight: 5, - justifyContent: "center", - alignItems: "center", - alignContent: "center" - }} - > - <input - onChange={e => this.onDataDoc = e.target.checked} - ref={this.checkRef} - style={{ margin: "0 10px 0 15px" }} - type="checkbox" - title={"Add to Data Document?"} - checked={this.onDataDoc} - /> - <div className={"key_container"} style={keyValueStyle}> - <EditableView - ref={this.keyRef} - contents={this.key} - SetValue={this.updateKey} - GetValue={() => ""} - oneLine={true} - /> + justifyContent: 'center', + alignItems: 'center', + alignContent: 'center', + }}> + <input onChange={e => (this.onDataDoc = e.target.checked)} ref={this.checkRef} style={{ margin: '0 10px 0 15px' }} type="checkbox" title={'Add to Data Document?'} checked={this.onDataDoc} /> + <div className={'key_container'} style={keyValueStyle}> + <EditableView ref={this.keyRef} contents={this.key} SetValue={this.updateKey} GetValue={() => ''} oneLine={true} /> </div> - <div - className={"value_container"} - style={keyValueStyle}> - <EditableView - ref={this.valueRef} - contents={this.value} - SetValue={this.updateValue} - GetValue={() => ""} - oneLine={true} - /> + <div className={'value_container'} style={keyValueStyle}> + <EditableView ref={this.valueRef} contents={this.value} SetValue={this.updateValue} GetValue={() => ''} oneLine={true} /> </div> - <div onClick={() => this.props.remove(this)} title={"Delete Entry"}> + <div onClick={() => this.props.remove(this)} title={'Delete Entry'}> <FontAwesomeIcon - icon={"plus"} - color={"red"} - size={"1x"} + icon={'plus'} + color={'red'} + size={'1x'} style={{ marginLeft: 15, marginRight: 15, - transform: "rotate(45deg)" + transform: 'rotate(45deg)', }} /> </div> </div> ); } - -}
\ No newline at end of file +} diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index be885312d..a2f5826fe 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { GestureUtils } from '../../pen-gestures/GestureUtils'; import { Utils } from '../../Utils'; import './InteractionUtils.scss'; diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index 400b63a1c..f0a5f9ed9 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -120,6 +120,7 @@ class ScriptingCompilerHost { } return undefined; } + // getDefaultLibFileName(options: ts.CompilerOptions): string { getDefaultLibFileName(options: any): string { return 'node_modules/typescript/lib/lib.d.ts'; // No idea what this means... @@ -247,7 +248,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp const funcScript = `(function(${paramString})${reqTypes} { ${body} })`; host.writeFile('file.ts', funcScript); - if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib); + if (typecheck && false) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib); const program = ts.createProgram(['file.ts'], {}, host); const testResult = program.emit(); const outputText = host.readFile('file.js'); diff --git a/src/client/util/ScrollBox.tsx b/src/client/util/ScrollBox.tsx index d4620ae3f..785526ab3 100644 --- a/src/client/util/ScrollBox.tsx +++ b/src/client/util/ScrollBox.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; export class ScrollBox extends React.Component<React.PropsWithChildren<{}>> { onWheel = (e: React.WheelEvent) => { diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts index 76037a7e9..8daa69890 100644 --- a/src/client/util/SerializationHelper.ts +++ b/src/client/util/SerializationHelper.ts @@ -1,6 +1,5 @@ import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema } from 'serializr'; import { Field } from '../../fields/Doc'; -import { ClientUtils } from './ClientUtils'; let serializing = 0; export function afterDocDeserialize(cb: (err: any, val: any) => void, err: any, newValue: any) { diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 34e294a4a..403f4e090 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -133,7 +133,7 @@ export class SharingManager extends React.Component<{}> { * Populates the list of validated users (this.users) by adding registered users which have a sharingDocument. */ populateUsers = async () => { - if (!this.populating && Doc.UserDoc()[Id] !== '__guest__') { + if (!this.populating && Doc.UserDoc()[Id] !== Utils.GuestID()) { this.populating = true; const userList = await RequestPromise.get(Utils.prepend('/getUsers')); const raw = (JSON.parse(userList) as User[]).filter(user => user.email !== 'guest' && user.email !== Doc.CurrentUserEmail); diff --git a/src/client/util/reportManager/ReportManager.tsx b/src/client/util/reportManager/ReportManager.tsx index b25d51b41..738902a31 100644 --- a/src/client/util/reportManager/ReportManager.tsx +++ b/src/client/util/reportManager/ReportManager.tsx @@ -1,13 +1,11 @@ import * as React from 'react'; -import v4 = require('uuid/v4'); +import * as uuid from 'uuid'; import '.././SettingsManager.scss'; import './ReportManager.scss'; -import Dropzone from 'react-dropzone'; import ReactLoading from 'react-loading'; import { action, observable } from 'mobx'; import { BsX, BsArrowsAngleExpand, BsArrowsAngleContract } from 'react-icons/bs'; import { CgClose } from 'react-icons/cg'; -import { AiOutlineUpload } from 'react-icons/ai'; import { HiOutlineArrowLeft } from 'react-icons/hi'; import { Issue } from './reportManagerSchema'; import { observer } from 'mobx-react'; @@ -156,7 +154,7 @@ export class ReportManager extends React.Component<{}> { * @param files uploaded files */ private onDrop = (files: File[]) => { - this.setFormData({ ...this.formData, mediaFiles: [...this.formData.mediaFiles, ...files.map(file => ({ _id: v4(), file }))] }); + this.setFormData({ ...this.formData, mediaFiles: [...this.formData.mediaFiles, ...files.map(file => ({ _id: uuid.v4(), file }))] }); }; /** @@ -338,7 +336,7 @@ export class ReportManager extends React.Component<{}> { multiple onChange={e => { if (!e.target.files) return; - this.setFormData({ ...this.formData, mediaFiles: [...this.formData.mediaFiles, ...Array.from(e.target.files).map(file => ({ _id: v4(), file }))] }); + this.setFormData({ ...this.formData, mediaFiles: [...this.formData.mediaFiles, ...Array.from(e.target.files).map(file => ({ _id: uuid.v4(), file }))] }); }} /> {this.formData.mediaFiles.length > 0 && <ul className="file-list">{this.formData.mediaFiles.map(file => this.getMediaPreview(file))}</ul>} diff --git a/src/client/util/reportManager/ReportManagerComponents.tsx b/src/client/util/reportManager/ReportManagerComponents.tsx index e870c073d..1e226bf6d 100644 --- a/src/client/util/reportManager/ReportManagerComponents.tsx +++ b/src/client/util/reportManager/ReportManagerComponents.tsx @@ -289,7 +289,7 @@ export const IssueView = ({ issue }: IssueViewProps) => { </div> </div> )} - <ReactMarkdown children={issueBody} className="issue-content" linkTarget={'_blank'} remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]} /> + <ReactMarkdown children={issueBody} className="issue-content" remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]} /> </div> ); }; diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index 16e76694d..412b8ba6e 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { observable, action, runInAction } from 'mobx'; import './AntimodeMenu.scss'; import { StrCast } from '../../fields/Types'; diff --git a/src/client/views/AudioWaveform.tsx b/src/client/views/AudioWaveform.tsx index c779ce8c4..1fd2fedc3 100644 --- a/src/client/views/AudioWaveform.tsx +++ b/src/client/views/AudioWaveform.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import axios from 'axios'; import { action, computed, IReactionDisposer, reaction } from 'mobx'; import { observer } from 'mobx-react'; @@ -102,7 +102,15 @@ export class AudioWaveform extends React.Component<AudioWaveformProps> { render() { return ( <div className="audioWaveform"> - <Waveform color={Colors.MEDIUM_BLUE_ALT} height={this.waveHeight} barWidth={200 / this.audioBuckets.length} pos={this.props.duration} duration={this.props.duration} peaks={Array.from(this.audioBuckets)} progressColor={Colors.MEDIUM_BLUE_ALT} /> + <Waveform + color={Colors.MEDIUM_BLUE_ALT} + height={this.waveHeight} + barWidth={200 / this.audioBuckets.length} + pos={this.props.duration} + duration={this.props.duration} + peaks={Array.from(this.audioBuckets)} + progressColor={Colors.MEDIUM_BLUE_ALT} + /> </div> ); } diff --git a/src/client/views/ComponentDecorations.tsx b/src/client/views/ComponentDecorations.tsx index 66d1bd63d..0a34b283b 100644 --- a/src/client/views/ComponentDecorations.tsx +++ b/src/client/views/ComponentDecorations.tsx @@ -1,14 +1,14 @@ -import { observer } from "mobx-react"; -import { SelectionManager } from "../util/SelectionManager"; +import { observer } from 'mobx-react'; +import { SelectionManager } from '../util/SelectionManager'; import './ComponentDecorations.scss'; -import React = require("react"); +import * as React from 'react'; @observer -export class ComponentDecorations extends React.Component<{ boundsTop: number, boundsLeft: number }, { value: string }> { +export class ComponentDecorations extends React.Component<{ boundsTop: number; boundsLeft: number }, { value: string }> { static Instance: ComponentDecorations; render() { const seldoc = SelectionManager.Views().lastElement(); - return seldoc?.ComponentView?.componentUI?.(this.props.boundsLeft, this.props.boundsTop) ?? (null); + return seldoc?.ComponentView?.componentUI?.(this.props.boundsLeft, this.props.boundsTop) ?? null; } -}
\ No newline at end of file +} diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index adefc7e9c..57bc11385 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, IReactionDisposer, observable } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index c2cbca3e1..6d97d965e 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { observable, action, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 59d7e75da..a64722a0b 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -1,6 +1,6 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, computed, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc } from '../../fields/Doc'; @@ -27,10 +27,10 @@ import { DashFieldView } from './nodes/formattedText/DashFieldView'; import { GoogleRef } from './nodes/formattedText/FormattedTextBox'; import { PinProps } from './nodes/trails'; import { TemplateMenu } from './TemplateMenu'; -import React = require('react'); -const higflyout = require('@hig/flyout'); -export const { anchorPoints } = higflyout; -export const Flyout = higflyout.default; +import * as React from 'react'; +// import * as higflyout from '@hig/flyout'; +// export const { anchorPoints } = higflyout; +// export const Flyout = higflyout.default; const cloud: IconProp = 'cloud-upload-alt'; const fetch: IconProp = 'sync-alt'; @@ -423,7 +423,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV return !view0 ? null : ( <Tooltip title={<div className="dash-tooltip">Show metadata panel</div>}> <div className="documentButtonBar-linkFlyout"> - <Flyout + {/* <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={ <MetadataEntryMenu @@ -432,12 +432,12 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV .filter(dv => dv) .map(dv => dv!.props.Document)} suggestWithFunction - /> /* tfs: @bcz This might need to be the data document? */ + /> // tfs: @bcz This might need to be the data document? }> <div className={'documentButtonBar-linkButton-' + 'empty'} onPointerDown={e => e.stopPropagation()}> {<FontAwesomeIcon className="documentdecorations-icon" icon="tag" />} </div> - </Flyout> + </Flyout> */} </div> </Tooltip> ); @@ -501,7 +501,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV return !view0 ? null : ( <Tooltip title={<div className="dash-tooltip">Tap to Customize Layout. Drag an embedding</div>} open={this._tooltipOpen} onClose={action(() => (this._tooltipOpen = false))} placement="bottom"> <div className="documentButtonBar-linkFlyout" ref={this._dragRef} onPointerEnter={action(() => !this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true))}> - <Flyout + {/* <Flyout anchorPoint={anchorPoints.LEFT_TOP} onOpen={action(() => (this._embedDown = true))} onClose={action(() => (this._embedDown = false))} @@ -516,7 +516,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV <div className={'documentButtonBar-linkButton-empty'} ref={this._dragRef} onPointerDown={this.onTemplateButton}> <FontAwesomeIcon className="documentdecorations-icon" icon="edit" size="sm" /> </div> - </Flyout> + </Flyout> */} </div> </Tooltip> ); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index b9fcf5360..b4c19df2d 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { IconButton } from 'browndash-components'; import { action, computed, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; @@ -33,8 +33,8 @@ import { LightboxView } from './LightboxView'; import { DocumentView, OpenWhereMod } from './nodes/DocumentView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { ImageBox } from './nodes/ImageBox'; -import React = require('react'); -import _ = require('lodash'); +import * as React from 'react'; +import * as _ from 'lodash'; @observer export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> { diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index abb7ed7ee..6bc0e5424 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { action, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as Autosuggest from 'react-autosuggest'; @@ -222,12 +222,14 @@ export class EditableView extends React.Component<EditableProps> { className: 'editableView-input', onKeyDown: this.onKeyDown, autoFocus: true, + // @ts-ignore onBlur: e => this.finalizeEdit(e.currentTarget.value, false, true, false), onPointerDown: this.stopPropagation, onClick: this.stopPropagation, onPointerUp: this.stopPropagation, onKeyPress: this.stopPropagation, value: this.props.autosuggestProps.value, + // @ts-ignore onChange: this.props.autosuggestProps.onChange, }} /> diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index 1deca401d..a3c4350d9 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { action, computed, observable, ObservableMap } from 'mobx'; import { observer } from 'mobx-react'; import { Handles, Rail, Slider, Ticks, Tracks } from 'react-compound-slider'; diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 559f245d9..214da5541 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import * as fitCurve from 'fit-curve'; import { action, computed, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; @@ -14,7 +14,6 @@ import { InteractionUtils } from '../util/InteractionUtils'; import { ScriptingGlobals } from '../util/ScriptingGlobals'; import { Transform } from '../util/Transform'; import './GestureOverlay.scss'; -import { InkTranscription } from './InkTranscription'; import { ActiveArrowEnd, ActiveArrowScale, @@ -178,7 +177,7 @@ export class GestureOverlay extends React.Component<React.PropsWithChildren<Gest newPoints.pop(); const controlPoints: { X: number; Y: number }[] = []; - const bezierCurves = fitCurve(newPoints, 10); + const bezierCurves = (fitCurve as any)(newPoints, 10); for (const curve of bezierCurves) { controlPoints.push({ X: curve[0][0], Y: curve[0][1] }); controlPoints.push({ X: curve[1][0], Y: curve[1][1] }); diff --git a/src/client/views/InkControlPtHandles.tsx b/src/client/views/InkControlPtHandles.tsx index e5141b7f4..b835a3798 100644 --- a/src/client/views/InkControlPtHandles.tsx +++ b/src/client/views/InkControlPtHandles.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; import { Doc } from '../../fields/Doc'; diff --git a/src/client/views/InkTangentHandles.tsx b/src/client/views/InkTangentHandles.tsx index 65f6a6dfa..a00c26a07 100644 --- a/src/client/views/InkTangentHandles.tsx +++ b/src/client/views/InkTangentHandles.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { action } from 'mobx'; import { observer } from 'mobx-react'; import { Doc } from '../../fields/Doc'; diff --git a/src/client/views/InkTranscription.tsx b/src/client/views/InkTranscription.tsx index 17136a737..b2ac208ca 100644 --- a/src/client/views/InkTranscription.tsx +++ b/src/client/views/InkTranscription.tsx @@ -1,350 +1,350 @@ -import * as iink from 'iink-js'; -import { action, observable } from 'mobx'; -import * as React from 'react'; -import { Doc, DocListCast } from '../../fields/Doc'; -import { InkData, InkField, InkTool } from '../../fields/InkField'; -import { Cast, DateCast, NumCast } from '../../fields/Types'; -import { aggregateBounds } from '../../Utils'; -import { DocumentType } from '../documents/DocumentTypes'; -import { DocumentManager } from '../util/DocumentManager'; -import { CollectionFreeFormView } from './collections/collectionFreeForm'; -import { InkingStroke } from './InkingStroke'; -import './InkTranscription.scss'; - -/** - * Class component that handles inking in writing mode - */ -export class InkTranscription extends React.Component { - static Instance: InkTranscription; - - @observable _mathRegister: any; - @observable _mathRef: any; - @observable _textRegister: any; - @observable _textRef: any; - private lastJiix: any; - private currGroup?: Doc; - - constructor(props: Readonly<{}>) { - super(props); - - InkTranscription.Instance = this; - } - - componentWillUnmount() { - this._mathRef.removeEventListener('exported', (e: any) => this.exportInk(e, this._mathRef)); - this._textRef.removeEventListener('exported', (e: any) => this.exportInk(e, this._textRef)); - } - - @action - setMathRef = (r: any) => { - if (!this._mathRegister) { - this._mathRegister = r - ? iink.register(r, { - recognitionParams: { - type: 'MATH', - protocol: 'WEBSOCKET', - server: { - host: 'cloud.myscript.com', - applicationKey: process.env.IINKJS_APP, - hmacKey: process.env.IINKJS_HMAC, - websocket: { - pingEnabled: false, - autoReconnect: true, - }, - }, - iink: { - math: { - mimeTypes: ['application/x-latex', 'application/vnd.myscript.jiix'], - }, - export: { - jiix: { - strokes: true, - }, - }, - }, - }, - }) - : null; - } - - r?.addEventListener('exported', (e: any) => this.exportInk(e, this._mathRef)); - - return (this._mathRef = r); - }; - - @action - setTextRef = (r: any) => { - if (!this._textRegister) { - this._textRegister = r - ? iink.register(r, { - recognitionParams: { - type: 'TEXT', - protocol: 'WEBSOCKET', - server: { - host: 'cloud.myscript.com', - applicationKey: '7277ec34-0c2e-4ee1-9757-ccb657e3f89f', - hmacKey: 'f5cb18f2-1f95-4ddb-96ac-3f7c888dffc1', - websocket: { - pingEnabled: false, - autoReconnect: true, - }, - }, - iink: { - text: { - mimeTypes: ['text/plain'], - }, - export: { - jiix: { - strokes: true, - }, - }, - }, - }, - }) - : null; - } - - r?.addEventListener('exported', (e: any) => this.exportInk(e, this._textRef)); - - return (this._textRef = r); - }; - - /** - * Handles processing Dash Doc data for ink transcription. - * - * @param groupDoc the group which contains the ink strokes we want to transcribe - * @param inkDocs the ink docs contained within the selected group - * @param math boolean whether to do math transcription or not - */ - transcribeInk = (groupDoc: Doc | undefined, inkDocs: Doc[], math: boolean) => { - if (!groupDoc) return; - const validInks = inkDocs.filter(s => s.type === DocumentType.INK); - - const strokes: InkData[] = []; - const times: number[] = []; - validInks - .filter(i => Cast(i[Doc.LayoutFieldKey(i)], InkField)) - .forEach(i => { - const d = Cast(i[Doc.LayoutFieldKey(i)], InkField, null); - const inkStroke = DocumentManager.Instance.getDocumentView(i)?.ComponentView as InkingStroke; - strokes.push(d.inkData.map(pd => inkStroke.ptToScreen({ X: pd.X, Y: pd.Y }))); - times.push(DateCast(i.author_date).getDate().getTime()); - }); - - this.currGroup = groupDoc; - - const pointerData = { events: strokes.map((stroke, i) => this.inkJSON(stroke, times[i])) }; - const processGestures = false; - - if (math) { - this._mathRef.editor.pointerEvents(pointerData, processGestures); - } else { - this._textRef.editor.pointerEvents(pointerData, processGestures); - } - }; - - /** - * Converts the Dash Ink Data to JSON. - * - * @param stroke The dash ink data - * @param time the time of the stroke - * @returns json object representation of ink data - */ - inkJSON = (stroke: InkData, time: number) => { - return { - pointerType: 'PEN', - pointerId: 1, - x: stroke.map(point => point.X), - y: stroke.map(point => point.Y), - t: new Array(stroke.length).fill(time), - p: new Array(stroke.length).fill(1.0), - }; - }; - - /** - * Creates subgroups for each word for the whole text transcription - * @param wordInkDocMap the mapping of words to ink strokes (Ink Docs) - */ - subgroupsTranscriptions = (wordInkDocMap: Map<string, Doc[]>) => { - // iterate through the keys of wordInkDocMap - wordInkDocMap.forEach(async (inkDocs: Doc[], word: string) => { - const selected = inkDocs.slice(); - if (!selected) { - return; - } - const ctx = await Cast(selected[0].embedContainer, Doc); - if (!ctx) { - return; - } - const docView: CollectionFreeFormView = DocumentManager.Instance.getDocumentView(ctx)?.ComponentView as CollectionFreeFormView; - - if (!docView) return; - const marqViewRef = docView._marqueeViewRef.current; - if (!marqViewRef) return; - this.groupInkDocs(selected, docView, word); - }); - }; - - /** - * Event listener function for when the 'exported' event is heard. - * - * @param e the event objects - * @param ref the ref to the editor - */ - exportInk = (e: any, ref: any) => { - const exports = e.detail.exports; - if (exports) { - if (exports['application/x-latex']) { - const latex = exports['application/x-latex']; - if (this.currGroup) { - this.currGroup.text = latex; - this.currGroup.title = latex; - } - - ref.editor.clear(); - } else if (exports['text/plain']) { - if (exports['application/vnd.myscript.jiix']) { - this.lastJiix = JSON.parse(exports['application/vnd.myscript.jiix']); - // map timestamp to strokes - const timestampWord = new Map<number, string>(); - this.lastJiix.words.map((word: any) => { - if (word.items) { - word.items.forEach((i: { id: string; timestamp: string; X: Array<number>; Y: Array<number>; F: Array<number> }) => { - const ms = Date.parse(i.timestamp); - timestampWord.set(ms, word.label); - }); - } - }); - - const wordInkDocMap = new Map<string, Doc[]>(); - if (this.currGroup) { - const docList = DocListCast(this.currGroup.data); - docList.forEach((inkDoc: Doc) => { - // just having the times match up and be a unique value (actual timestamp doesn't matter) - const ms = DateCast(inkDoc.author_date).getDate().getTime() + 14400000; - const word = timestampWord.get(ms); - if (!word) { - return; - } - const entry = wordInkDocMap.get(word); - if (entry) { - entry.push(inkDoc); - wordInkDocMap.set(word, entry); - } else { - const newEntry = [inkDoc]; - wordInkDocMap.set(word, newEntry); - } - }); - if (this.lastJiix.words.length > 1) this.subgroupsTranscriptions(wordInkDocMap); - } - } - const text = exports['text/plain']; - - if (this.currGroup) { - this.currGroup.transcription = text; - this.currGroup.title = text.split('\n')[0]; - } - - ref.editor.clear(); - } - } - }; - - /** - * Creates the ink grouping once the user leaves the writing mode. - */ - createInkGroup() { - // TODO nda - if document being added to is a inkGrouping then we can just add to that group - if (Doc.ActiveTool === InkTool.Write) { - CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => { - // TODO: nda - will probably want to go through ffView unprocessed docs and then see if any of the inksToGroup docs are in it and only use those - const selected = ffView.unprocessedDocs; - const newCollection = this.groupInkDocs( - selected.filter(doc => doc.embedContainer), - ffView - ); - ffView.unprocessedDocs = []; - - InkTranscription.Instance.transcribeInk(newCollection, selected, false); - }); - } - CollectionFreeFormView.collectionsWithUnprocessedInk.clear(); - } - - /** - * Creates the groupings for a given list of ink docs on a specific doc view - * @param selected: the list of ink docs to create a grouping of - * @param docView: the view in which we want the grouping to be created - * @param word: optional param if the group we are creating is a word (subgrouping individual words) - * @returns a new collection Doc or undefined if the grouping fails - */ - groupInkDocs(selected: Doc[], docView: CollectionFreeFormView, word?: string): Doc | undefined { - const bounds: { x: number; y: number; width?: number; height?: number }[] = []; - - // calculate the necessary bounds from the selected ink docs - selected.map( - action(d => { - const x = NumCast(d.x); - const y = NumCast(d.y); - const width = NumCast(d._width); - const height = NumCast(d._height); - bounds.push({ x, y, width, height }); - }) - ); - - // calculate the aggregated bounds - const aggregBounds = aggregateBounds(bounds, 0, 0); - const marqViewRef = docView._marqueeViewRef.current; - - // set the vals for bounds in marqueeView - if (marqViewRef) { - marqViewRef._downX = aggregBounds.x; - marqViewRef._downY = aggregBounds.y; - marqViewRef._lastX = aggregBounds.r; - marqViewRef._lastY = aggregBounds.b; - } - - // map through all the selected ink strokes and create the groupings - selected.map( - action(d => { - const dx = NumCast(d.x); - const dy = NumCast(d.y); - delete d.x; - delete d.y; - delete d.activeFrame; - delete d._timecodeToShow; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection - delete d._timecodeToHide; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection - // calculate pos based on bounds - if (marqViewRef?.Bounds) { - d.x = dx - marqViewRef.Bounds.left - marqViewRef.Bounds.width / 2; - d.y = dy - marqViewRef.Bounds.top - marqViewRef.Bounds.height / 2; - } - return d; - }) - ); - docView.props.removeDocument?.(selected); - // Gets a collection based on the selected nodes using a marquee view ref - const newCollection = marqViewRef?.getCollection(selected, undefined, true); - if (newCollection) { - newCollection.width = NumCast(newCollection._width); - newCollection.height = NumCast(newCollection._height); - // if the grouping we are creating is an individual word - if (word) { - newCollection.title = word; - } - } - - // nda - bug: when deleting a stroke before leaving writing mode, delete the stroke from unprocessed ink docs - newCollection && docView.props.addDocument?.(newCollection); - return newCollection; - } - - render() { - return ( - <div className="ink-transcription"> - <div className="math-editor" ref={this.setMathRef} touch-action="none"></div> - <div className="text-editor" ref={this.setTextRef} touch-action="none"></div> - </div> - ); - } -} +// import * as iink from 'iink-js'; +// import { action, observable } from 'mobx'; +// import * as React from 'react'; +// import { Doc, DocListCast } from '../../fields/Doc'; +// import { InkData, InkField, InkTool } from '../../fields/InkField'; +// import { Cast, DateCast, NumCast } from '../../fields/Types'; +// import { aggregateBounds } from '../../Utils'; +// import { DocumentType } from '../documents/DocumentTypes'; +// import { DocumentManager } from '../util/DocumentManager'; +// import { CollectionFreeFormView } from './collections/collectionFreeForm'; +// import { InkingStroke } from './InkingStroke'; +// import './InkTranscription.scss'; + +// /** +// * Class component that handles inking in writing mode +// */ +// export class InkTranscription extends React.Component { +// static Instance: InkTranscription; + +// @observable _mathRegister: any; +// @observable _mathRef: any; +// @observable _textRegister: any; +// @observable _textRef: any; +// private lastJiix: any; +// private currGroup?: Doc; + +// constructor(props: Readonly<{}>) { +// super(props); + +// InkTranscription.Instance = this; +// } + +// componentWillUnmount() { +// this._mathRef.removeEventListener('exported', (e: any) => this.exportInk(e, this._mathRef)); +// this._textRef.removeEventListener('exported', (e: any) => this.exportInk(e, this._textRef)); +// } + +// @action +// setMathRef = (r: any) => { +// if (!this._mathRegister) { +// this._mathRegister = r +// ? iink.register(r, { +// recognitionParams: { +// type: 'MATH', +// protocol: 'WEBSOCKET', +// server: { +// host: 'cloud.myscript.com', +// applicationKey: process.env.IINKJS_APP, +// hmacKey: process.env.IINKJS_HMAC, +// websocket: { +// pingEnabled: false, +// autoReconnect: true, +// }, +// }, +// iink: { +// math: { +// mimeTypes: ['application/x-latex', 'application/vnd.myscript.jiix'], +// }, +// export: { +// jiix: { +// strokes: true, +// }, +// }, +// }, +// }, +// }) +// : null; +// } + +// r?.addEventListener('exported', (e: any) => this.exportInk(e, this._mathRef)); + +// return (this._mathRef = r); +// }; + +// @action +// setTextRef = (r: any) => { +// if (!this._textRegister) { +// this._textRegister = r +// ? iink.register(r, { +// recognitionParams: { +// type: 'TEXT', +// protocol: 'WEBSOCKET', +// server: { +// host: 'cloud.myscript.com', +// applicationKey: '7277ec34-0c2e-4ee1-9757-ccb657e3f89f', +// hmacKey: 'f5cb18f2-1f95-4ddb-96ac-3f7c888dffc1', +// websocket: { +// pingEnabled: false, +// autoReconnect: true, +// }, +// }, +// iink: { +// text: { +// mimeTypes: ['text/plain'], +// }, +// export: { +// jiix: { +// strokes: true, +// }, +// }, +// }, +// }, +// }) +// : null; +// } + +// r?.addEventListener('exported', (e: any) => this.exportInk(e, this._textRef)); + +// return (this._textRef = r); +// }; + +// /** +// * Handles processing Dash Doc data for ink transcription. +// * +// * @param groupDoc the group which contains the ink strokes we want to transcribe +// * @param inkDocs the ink docs contained within the selected group +// * @param math boolean whether to do math transcription or not +// */ +// transcribeInk = (groupDoc: Doc | undefined, inkDocs: Doc[], math: boolean) => { +// if (!groupDoc) return; +// const validInks = inkDocs.filter(s => s.type === DocumentType.INK); + +// const strokes: InkData[] = []; +// const times: number[] = []; +// validInks +// .filter(i => Cast(i[Doc.LayoutFieldKey(i)], InkField)) +// .forEach(i => { +// const d = Cast(i[Doc.LayoutFieldKey(i)], InkField, null); +// const inkStroke = DocumentManager.Instance.getDocumentView(i)?.ComponentView as InkingStroke; +// strokes.push(d.inkData.map(pd => inkStroke.ptToScreen({ X: pd.X, Y: pd.Y }))); +// times.push(DateCast(i.author_date).getDate().getTime()); +// }); + +// this.currGroup = groupDoc; + +// const pointerData = { events: strokes.map((stroke, i) => this.inkJSON(stroke, times[i])) }; +// const processGestures = false; + +// if (math) { +// this._mathRef.editor.pointerEvents(pointerData, processGestures); +// } else { +// this._textRef.editor.pointerEvents(pointerData, processGestures); +// } +// }; + +// /** +// * Converts the Dash Ink Data to JSON. +// * +// * @param stroke The dash ink data +// * @param time the time of the stroke +// * @returns json object representation of ink data +// */ +// inkJSON = (stroke: InkData, time: number) => { +// return { +// pointerType: 'PEN', +// pointerId: 1, +// x: stroke.map(point => point.X), +// y: stroke.map(point => point.Y), +// t: new Array(stroke.length).fill(time), +// p: new Array(stroke.length).fill(1.0), +// }; +// }; + +// /** +// * Creates subgroups for each word for the whole text transcription +// * @param wordInkDocMap the mapping of words to ink strokes (Ink Docs) +// */ +// subgroupsTranscriptions = (wordInkDocMap: Map<string, Doc[]>) => { +// // iterate through the keys of wordInkDocMap +// wordInkDocMap.forEach(async (inkDocs: Doc[], word: string) => { +// const selected = inkDocs.slice(); +// if (!selected) { +// return; +// } +// const ctx = await Cast(selected[0].embedContainer, Doc); +// if (!ctx) { +// return; +// } +// const docView: CollectionFreeFormView = DocumentManager.Instance.getDocumentView(ctx)?.ComponentView as CollectionFreeFormView; + +// if (!docView) return; +// const marqViewRef = docView._marqueeViewRef.current; +// if (!marqViewRef) return; +// this.groupInkDocs(selected, docView, word); +// }); +// }; + +// /** +// * Event listener function for when the 'exported' event is heard. +// * +// * @param e the event objects +// * @param ref the ref to the editor +// */ +// exportInk = (e: any, ref: any) => { +// const exports = e.detail.exports; +// if (exports) { +// if (exports['application/x-latex']) { +// const latex = exports['application/x-latex']; +// if (this.currGroup) { +// this.currGroup.text = latex; +// this.currGroup.title = latex; +// } + +// ref.editor.clear(); +// } else if (exports['text/plain']) { +// if (exports['application/vnd.myscript.jiix']) { +// this.lastJiix = JSON.parse(exports['application/vnd.myscript.jiix']); +// // map timestamp to strokes +// const timestampWord = new Map<number, string>(); +// this.lastJiix.words.map((word: any) => { +// if (word.items) { +// word.items.forEach((i: { id: string; timestamp: string; X: Array<number>; Y: Array<number>; F: Array<number> }) => { +// const ms = Date.parse(i.timestamp); +// timestampWord.set(ms, word.label); +// }); +// } +// }); + +// const wordInkDocMap = new Map<string, Doc[]>(); +// if (this.currGroup) { +// const docList = DocListCast(this.currGroup.data); +// docList.forEach((inkDoc: Doc) => { +// // just having the times match up and be a unique value (actual timestamp doesn't matter) +// const ms = DateCast(inkDoc.author_date).getDate().getTime() + 14400000; +// const word = timestampWord.get(ms); +// if (!word) { +// return; +// } +// const entry = wordInkDocMap.get(word); +// if (entry) { +// entry.push(inkDoc); +// wordInkDocMap.set(word, entry); +// } else { +// const newEntry = [inkDoc]; +// wordInkDocMap.set(word, newEntry); +// } +// }); +// if (this.lastJiix.words.length > 1) this.subgroupsTranscriptions(wordInkDocMap); +// } +// } +// const text = exports['text/plain']; + +// if (this.currGroup) { +// this.currGroup.transcription = text; +// this.currGroup.title = text.split('\n')[0]; +// } + +// ref.editor.clear(); +// } +// } +// }; + +// /** +// * Creates the ink grouping once the user leaves the writing mode. +// */ +// createInkGroup() { +// // TODO nda - if document being added to is a inkGrouping then we can just add to that group +// if (Doc.ActiveTool === InkTool.Write) { +// CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => { +// // TODO: nda - will probably want to go through ffView unprocessed docs and then see if any of the inksToGroup docs are in it and only use those +// const selected = ffView.unprocessedDocs; +// const newCollection = this.groupInkDocs( +// selected.filter(doc => doc.embedContainer), +// ffView +// ); +// ffView.unprocessedDocs = []; + +// InkTranscription.Instance.transcribeInk(newCollection, selected, false); +// }); +// } +// CollectionFreeFormView.collectionsWithUnprocessedInk.clear(); +// } + +// /** +// * Creates the groupings for a given list of ink docs on a specific doc view +// * @param selected: the list of ink docs to create a grouping of +// * @param docView: the view in which we want the grouping to be created +// * @param word: optional param if the group we are creating is a word (subgrouping individual words) +// * @returns a new collection Doc or undefined if the grouping fails +// */ +// groupInkDocs(selected: Doc[], docView: CollectionFreeFormView, word?: string): Doc | undefined { +// const bounds: { x: number; y: number; width?: number; height?: number }[] = []; + +// // calculate the necessary bounds from the selected ink docs +// selected.map( +// action(d => { +// const x = NumCast(d.x); +// const y = NumCast(d.y); +// const width = NumCast(d._width); +// const height = NumCast(d._height); +// bounds.push({ x, y, width, height }); +// }) +// ); + +// // calculate the aggregated bounds +// const aggregBounds = aggregateBounds(bounds, 0, 0); +// const marqViewRef = docView._marqueeViewRef.current; + +// // set the vals for bounds in marqueeView +// if (marqViewRef) { +// marqViewRef._downX = aggregBounds.x; +// marqViewRef._downY = aggregBounds.y; +// marqViewRef._lastX = aggregBounds.r; +// marqViewRef._lastY = aggregBounds.b; +// } + +// // map through all the selected ink strokes and create the groupings +// selected.map( +// action(d => { +// const dx = NumCast(d.x); +// const dy = NumCast(d.y); +// delete d.x; +// delete d.y; +// delete d.activeFrame; +// delete d._timecodeToShow; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection +// delete d._timecodeToHide; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection +// // calculate pos based on bounds +// if (marqViewRef?.Bounds) { +// d.x = dx - marqViewRef.Bounds.left - marqViewRef.Bounds.width / 2; +// d.y = dy - marqViewRef.Bounds.top - marqViewRef.Bounds.height / 2; +// } +// return d; +// }) +// ); +// docView.props.removeDocument?.(selected); +// // Gets a collection based on the selected nodes using a marquee view ref +// const newCollection = marqViewRef?.getCollection(selected, undefined, true); +// if (newCollection) { +// newCollection.width = NumCast(newCollection._width); +// newCollection.height = NumCast(newCollection._height); +// // if the grouping we are creating is an individual word +// if (word) { +// newCollection.title = word; +// } +// } + +// // nda - bug: when deleting a stroke before leaving writing mode, delete the stroke from unprocessed ink docs +// newCollection && docView.props.addDocument?.(newCollection); +// return newCollection; +// } + +// render() { +// return ( +// <div className="ink-transcription"> +// <div className="math-editor" ref={this.setMathRef} touch-action="none"></div> +// <div className="text-editor" ref={this.setTextRef} touch-action="none"></div> +// </div> +// ); +// } +// } diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index e081961e5..41a2507f9 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -20,7 +20,7 @@ Most of the operations that can be performed on an InkStroke (eg delete a point, rotate, stretch) are implemented in the InkStrokeProperties helper class */ -import React = require('react'); +import * as React from 'react'; import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc } from '../../fields/Doc'; @@ -36,7 +36,6 @@ import { Transform } from '../util/Transform'; import { UndoManager } from '../util/UndoManager'; import { ContextMenu } from './ContextMenu'; import { ViewBoxBaseComponent } from './DocComponent'; -import { INK_MASK_SIZE } from './global/globalCssVariables.scss'; import { Colors } from './global/globalEnums'; import { InkControlPtHandles, InkEndPtHandles } from './InkControlPtHandles'; import './InkStroke.scss'; @@ -47,7 +46,8 @@ import { FieldView, FieldViewProps } from './nodes/FieldView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { PinProps, PresBox } from './nodes/trails'; import { StyleProp } from './StyleProvider'; -import Color = require('color'); +// import { INK_MASK_SIZE } from './global/globalCssVariables.scss'; +const INK_MASK_SIZE = 1000; @observer export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() { diff --git a/src/client/views/KeyphraseQueryView.tsx b/src/client/views/KeyphraseQueryView.tsx index 13d52db88..e996fc946 100644 --- a/src/client/views/KeyphraseQueryView.tsx +++ b/src/client/views/KeyphraseQueryView.tsx @@ -1,6 +1,6 @@ -import { observer } from "mobx-react"; -import React = require("react"); -import "./KeyphraseQueryView.scss"; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import './KeyphraseQueryView.scss'; // tslint:disable-next-line: class-name export interface KP_Props { @@ -8,7 +8,7 @@ export interface KP_Props { } @observer -export class KeyphraseQueryView extends React.Component<KP_Props>{ +export class KeyphraseQueryView extends React.Component<KP_Props> { constructor(props: KP_Props) { super(props); } @@ -22,13 +22,17 @@ export class KeyphraseQueryView extends React.Component<KP_Props>{ <form> {keyterms.map((kp: string) => { //return (<p>{"-" + kp}</p>); - return (<p><label> - <input name="query" type="radio" /> - <span>{kp}</span> - </label></p>); + return ( + <p> + <label> + <input name="query" type="radio" /> + <span>{kp}</span> + </label> + </p> + ); })} </form> </div> ); } -}
\ No newline at end of file +} diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 58c1570b2..50feccce2 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -3,7 +3,7 @@ import { faBuffer, faHireAHelper } from '@fortawesome/free-brands-svg-icons'; import * as far from '@fortawesome/free-regular-svg-icons'; import * as fa from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import 'browndash-components/dist/styles/global.min.css'; +import '../../../node_modules/browndash-components/dist/styles/global.min.css'; import { action, computed, configure, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import 'normalize.css'; @@ -43,9 +43,7 @@ import { DashboardView } from './DashboardView'; import { DictationOverlay } from './DictationOverlay'; import { DocumentDecorations } from './DocumentDecorations'; import { GestureOverlay } from './GestureOverlay'; -import { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } from './global/globalCssVariables.scss'; import { KeyManager } from './GlobalKeyHandler'; -import { InkTranscription } from './InkTranscription'; import { LightboxView } from './LightboxView'; import { LinkMenu } from './linking/LinkMenu'; import './MainView.scss'; @@ -71,6 +69,9 @@ import { PreviewCursor } from './PreviewCursor'; import { PropertiesView } from './PropertiesView'; import { DashboardStyleProvider, DefaultStyleProvider } from './StyleProvider'; import { TopBar } from './topbar/TopBar'; +// import { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } from './global/globalCssVariables.scss'; +const LEFT_MENU_WIDTH = '60px'; +const TOPBAR_HEIGHT = '37px'; const _global = (window /* browser */ || global) /* node */ as any; @observer @@ -1063,7 +1064,7 @@ export class MainView extends React.Component { <MarqueeOptionsMenu /> <TimelineMenu /> <RichTextMenu /> - <InkTranscription /> + {/* <InkTranscription /> */} {this.snapLines} <LightboxView key="lightbox" PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} maxBorder={[200, 50]} /> <OverlayView /> diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index 70a44a08a..a241e3a2b 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -15,7 +15,7 @@ import './MarqueeAnnotator.scss'; import { DocumentView } from './nodes/DocumentView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { AnchorMenu } from './pdf/AnchorMenu'; -import React = require('react'); +import * as React from 'react'; const _global = (window /* browser */ || global) /* node */ as any; export interface MarqueeAnnotatorProps { diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx index bcbdd3ccb..5c6912121 100644 --- a/src/client/views/MetadataEntryMenu.tsx +++ b/src/client/views/MetadataEntryMenu.tsx @@ -156,6 +156,7 @@ export class MetadataEntryMenu extends React.Component<MetadataEntryProps> { <span>Key:</span> <div className="metadataEntry-autoSuggester" onClick={e => this.autosuggestRef.current!.input?.focus()}> <Autosuggest + // @ts-ignore inputProps={{ value: this._currentKey, onChange: this.onKeyChange }} getSuggestionValue={this.getSuggestionValue} suggestions={emptyPath} diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 6635aabf9..7824ad1c8 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -27,7 +27,7 @@ import { Colors } from './global/globalEnums'; import { InkingStroke } from './InkingStroke'; import { DocumentView, OpenWhere } from './nodes/DocumentView'; import './PropertiesButtons.scss'; -import React = require('react'); +import * as React from 'react'; enum UtilityButtonState { Default, diff --git a/src/client/views/PropertiesSection.tsx b/src/client/views/PropertiesSection.tsx index bd586b2f9..2b9bfb505 100644 --- a/src/client/views/PropertiesSection.tsx +++ b/src/client/views/PropertiesSection.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index c5b0528af..2c3cd8eac 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1,13 +1,13 @@ -import React = require('react'); +import * as React from 'react'; import { IconLookup } from '@fortawesome/fontawesome-svg-core'; import { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Checkbox, Tooltip } from '@material-ui/core'; +import { Checkbox, Tooltip } from '@mui/material'; import { Colors, EditableText, IconButton, NumberInput, Size, Slider, Type } from 'browndash-components'; import { concat } from 'lodash'; import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; -import { ColorState, SketchPicker } from 'react-color'; +import { ColorResult, SketchPicker } from 'react-color'; import * as Icons from 'react-icons/bs'; //{BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs" import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc'; import { AclAdmin, DocAcl, DocData } from '../../fields/DocSymbols'; @@ -875,7 +875,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return ( <SketchPicker onChange={undoable( - action((color: ColorState) => setter(color.hex)), + action((color: ColorResult) => setter(color.hex)), 'set stroke color property' )} presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']} diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index 049ba4841..2a52d86c2 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -16,7 +16,7 @@ import { FieldViewProps } from './nodes/FieldView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import './SidebarAnnos.scss'; import { StyleProp } from './StyleProvider'; -import React = require('react'); +import * as React from 'react'; interface ExtraProps { fieldKey: string; diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 806c9c001..4a08081a1 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -1,6 +1,6 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { Dropdown, DropdownType, IconButton, IListItemProps, Shadows, Size, Type } from 'browndash-components'; import { action, runInAction, untracked } from 'mobx'; import { extname } from 'path'; @@ -23,7 +23,7 @@ import { FieldViewProps } from './nodes/FieldView'; import { KeyValueBox } from './nodes/KeyValueBox'; import { PropertiesView } from './PropertiesView'; import './StyleProvider.scss'; -import React = require('react'); +import * as React from 'react'; export enum StyleProp { TreeViewIcon = 'treeView_Icon', @@ -320,9 +320,9 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps color={SettingsManager.userColor} background={showFilterIcon} items={[ ...(dashView ? [dashView]: []), ...(props?.docViewPath?.()??[]), ...(props?.DocumentView?[props?.DocumentView?.()]:[])] - .filter(dv => StrListCast(dv.Document.childFilters).length || StrListCast(dv.Document.childRangeFilters).length) + .filter(dv => StrListCast(dv?.Document.childFilters).length || StrListCast(dv?.Document.childRangeFilters).length) .map(dv => ({ - text: StrCast(dv.Document.title), + text: StrCast(dv?.Document.title), val: dv as any, style: {color:SettingsManager.userColor, background:SettingsManager.userBackgroundColor}, } as IListItemProps)) } diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 6da228417..48653f30a 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -13,7 +13,7 @@ import { CollectionTreeView } from './collections/CollectionTreeView'; import { DocumentView } from './nodes/DocumentView'; import { DefaultStyleProvider } from './StyleProvider'; import './TemplateMenu.scss'; -import React = require('react'); +import * as React from 'react'; @observer class TemplateToggle extends React.Component<{ template: string; checked: boolean; toggle: (event: React.ChangeEvent<HTMLInputElement>, template: string) => void }> { diff --git a/src/client/views/TouchScrollableMenu.tsx b/src/client/views/TouchScrollableMenu.tsx index 969605be9..530c693a7 100644 --- a/src/client/views/TouchScrollableMenu.tsx +++ b/src/client/views/TouchScrollableMenu.tsx @@ -1,6 +1,6 @@ -import React = require("react"); -import { computed } from "mobx"; -import { observer } from "mobx-react"; +import * as React from 'react'; +import { computed } from 'mobx'; +import { observer } from 'mobx-react'; export interface TouchScrollableMenuProps { options: JSX.Element[]; @@ -24,31 +24,35 @@ export interface TouchScrollableMenuItemProps { @observer export default class TouchScrollableMenu extends React.Component<TouchScrollableMenuProps> { - @computed - private get possibilities() { return this.props.options; } + private get possibilities() { + return this.props.options; + } @computed - private get selectedIndex() { return this.props.selectedIndex; } + private get selectedIndex() { + return this.props.selectedIndex; + } render() { return ( - <div className="inkToTextDoc-cont" style={{ - transform: `translate(${this.props.x}px, ${this.props.y}px)`, - width: 300, - height: this.possibilities.length * 25 - }}> + <div + className="inkToTextDoc-cont" + style={{ + transform: `translate(${this.props.x}px, ${this.props.y}px)`, + width: 300, + height: this.possibilities.length * 25, + }}> <div className="inkToTextDoc-scroller" style={{ transform: `translate(0, ${-this.selectedIndex * 25}px)` }}> {this.possibilities} </div> - <div className="shadow" style={{ height: `calc(100% - 25px - ${this.selectedIndex * 25}px)` }}> - </div> + <div className="shadow" style={{ height: `calc(100% - 25px - ${this.selectedIndex * 25}px)` }}></div> </div> ); } } -export class TouchScrollableMenuItem extends React.Component<TouchScrollableMenuItemProps>{ +export class TouchScrollableMenuItem extends React.Component<TouchScrollableMenuItemProps> { render() { return ( <div className="menuItem-cont" onClick={this.props.onClick}> @@ -56,4 +60,4 @@ export class TouchScrollableMenuItem extends React.Component<TouchScrollableMenu </div> ); } -}
\ No newline at end of file +} diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index d6368464a..330cb93e4 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -10,11 +10,13 @@ import { DocumentType } from '../../documents/DocumentTypes'; import { DragManager } from '../../util/DragManager'; import { SelectionManager } from '../../util/SelectionManager'; import { StyleProp } from '../StyleProvider'; -import { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } from '../global/globalCssVariables.scss'; import { DocFocusOptions, DocumentView } from '../nodes/DocumentView'; import './CollectionCarousel3DView.scss'; import { CollectionSubView } from './CollectionSubView'; - +// import { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } from '../global/globalCssVariables.scss'; +const CAROUSEL3D_CENTER_SCALE = '1'; +const CAROUSEL3D_SIDE_SCALE = '1'; +const CAROUSEL3D_TOP = '0'; @observer export class CollectionCarousel3DView extends CollectionSubView() { @computed get scrollSpeed() { diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss index 333ba9f32..11543bbe5 100644 --- a/src/client/views/collections/CollectionDockingView.scss +++ b/src/client/views/collections/CollectionDockingView.scss @@ -276,8 +276,6 @@ z-index: 20; } /*# sourceMappingURL=goldenlayout-base.css.map */ -@import '../../../../node_modules/golden-layout/src/css/goldenlayout-dark-theme.css'; - .lm_title { -webkit-appearance: none; display: inline-block; @@ -681,11 +679,6 @@ ul.lm_tabs::before { height: 8px; } - .flexlayout__tab_button:hover .flexlayout__tab_button_trailing, - .flexlayout__tab_button--selected .flexlayout__tab_button_trailing { - background: transparent url('../../../../node_modules/flexlayout-react/images/close_white.png') no-repeat center; - } - .flexlayout__tab_button_overflow { float: left; width: 20px; @@ -696,7 +689,6 @@ ul.lm_tabs::before { font-size: 10px; color: lightgray; font-family: Arial, sans-serif; - background: transparent url('../../../../node_modules/flexlayout-react/images/more.png') no-repeat left; } .flexlayout__tabset_header { @@ -751,7 +743,6 @@ ul.lm_tabs::before { height: 20px; border: none; outline-width: 0; - background: transparent url('../../../../node_modules/flexlayout-react/images/maximize.png') no-repeat center; } .flexlayout__tab_toolbar_button-max { @@ -759,7 +750,6 @@ ul.lm_tabs::before { height: 20px; border: none; outline-width: 0; - background: transparent url('../../../../node_modules/flexlayout-react/images/restore.png') no-repeat center; } .flexlayout__popup_menu_item { @@ -877,11 +867,6 @@ ul.lm_tabs::before { height: 8px; } - .flexlayout__border_button:hover .flexlayout__border_button_trailing, - .flexlayout__border_button--selected .flexlayout__border_button_trailing { - background: transparent url('../../../../node_modules/flexlayout-react/images/close_white.png') no-repeat center; - } - .flexlayout__border_toolbar_left { position: absolute; display: flex; diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 2e8047309..858090c05 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -30,7 +30,7 @@ import './CollectionDockingView.scss'; import { CollectionFreeFormView } from './collectionFreeForm'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import { TabDocView } from './TabDocView'; -import React = require('react'); +import * as React from 'react'; import { SettingsManager } from '../../util/SettingsManager'; const _global = (window /* browser */ || global) /* node */ as any; diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index a9b5f401d..61a5738ec 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; @@ -18,9 +18,9 @@ import { EditableView } from '../EditableView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { CollectionStackingView } from './CollectionStackingView'; import './CollectionStackingView.scss'; -const higflyout = require('@hig/flyout'); -export const { anchorPoints } = higflyout; -export const Flyout = higflyout.default; +// import * as higflyout from '@hig/flyout'; +// export const { anchorPoints } = higflyout; +// export const Flyout = higflyout.default; interface CMVFieldRowProps { rows: () => number; @@ -338,11 +338,11 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr )} {noChrome || evContents === `NO ${key.toUpperCase()} VALUE` ? null : ( <div className="collectionStackingView-sectionOptions" onPointerDown={e => e.stopPropagation()}> - <Flyout anchorPoint={anchorPoints.RIGHT_TOP} content={this.renderMenu()}> + {/* <Flyout anchorPoint={anchorPoints.RIGHT_TOP} content={this.renderMenu()}> <button className="collectionStackingView-sectionOptionButton"> <FontAwesomeIcon icon="ellipsis-v" size="lg" /> </button> - </Flyout> + </Flyout> */} </div> )} </div> diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 8b3531da8..3edf4135f 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -1,6 +1,6 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { Toggle, ToggleType, Type } from 'browndash-components'; import { action, computed, Lambda, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; @@ -541,6 +541,7 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi autosuggestProps: { inputProps: { value: this._currentKey, + // @ts-ignore onChange: this.onKeyChange, }, getSuggestionValue: this.getSuggestionValue, diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx index ad5431c8e..ba00c4fa0 100644 --- a/src/client/views/collections/CollectionNoteTakingView.tsx +++ b/src/client/views/collections/CollectionNoteTakingView.tsx @@ -1,5 +1,4 @@ -import React = require('react'); -import { CursorProperty } from 'csstype'; +import * as React from 'react'; import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, Field, Opt } from '../../../fields/Doc'; @@ -44,7 +43,6 @@ export class CollectionNoteTakingView extends CollectionSubView() { notetakingCategoryField = 'NotetakingCategory'; public DividerWidth = 16; @observable docsDraggedRowCol: number[] = []; - @observable _cursor: CursorProperty = 'grab'; @observable _scroll = 0; @computed get chromeHidden() { return BoolCast(this.layoutDoc.chromeHidden) || this.props.onBrowseClick?.() ? true : false; diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx index 9e5f09479..9be01df18 100644 --- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable, trace } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index ad8144466..c5677e2ba 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -12,7 +12,7 @@ import { computePassLayout, computeStarburstLayout } from './collectionFreeForm' import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; import './CollectionPileView.scss'; import { CollectionSubView } from './CollectionSubView'; -import React = require('react'); +import * as React from 'react'; @observer export class CollectionPileView extends CollectionSubView() { diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 7fee1cda6..92b5470ae 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 59e0c60b9..bc428c22f 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -1,6 +1,6 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { CursorProperty } from 'csstype'; +import * as CSS from 'csstype'; import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, Opt } from '../../../fields/Doc'; @@ -59,7 +59,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection // map of node headers to their heights. Used in Masonry @observable _heightMap = new Map<string, number>(); // Assuming that this is the current css cursor style - @observable _cursor: CursorProperty = 'ew-resize'; + @observable _cursor: CSS.Property.Cursor = 'ew-resize'; // gets reset whenever we scroll. Not sure what it is @observable _scroll = 0; // used to force the document decoration to update when scrolling // does this mean whether the browser is hidden? Or is chrome something else entirely? diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 9bd412fb8..3282eb4b4 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index f082ca0da..40b2f9644 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -24,7 +24,7 @@ import { ViewBoxBaseComponent } from '../DocComponent'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { LoadingBox } from '../nodes/LoadingBox'; import { CollectionView, CollectionViewProps } from './CollectionView'; -import React = require('react'); +import * as React from 'react'; export interface SubCollectionViewProps extends CollectionViewProps { isAnyChildContentActive: () => boolean; diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 8d114761a..e65f24702 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -21,7 +21,7 @@ import { computePivotLayout, computeTimelineLayout, ViewDefBounds } from './coll import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; import { CollectionSubView } from './CollectionSubView'; import './CollectionTimeView.scss'; -import React = require('react'); +import * as React from 'react'; @observer export class CollectionTimeView extends CollectionSubView() { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 1315decb2..5c165fe70 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -26,7 +26,7 @@ import { CollectionFreeFormView } from './collectionFreeForm'; import { CollectionSubView } from './CollectionSubView'; import './CollectionTreeView.scss'; import { TreeView } from './TreeView'; -import React = require('react'); +import * as React from 'react'; const _global = (window /* browser */ || global) /* node */ as any; export type collectionTreeViewProps = { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index def4beca3..4a1d702b8 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -33,7 +33,7 @@ import { CollectionDockingView } from './CollectionDockingView'; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; import { CollectionView } from './CollectionView'; import './TabDocView.scss'; -import React = require('react'); +import * as React from 'react'; import { Docs } from '../../documents/Documents'; import { ComputedField } from '../../../fields/ScriptField'; const _global = (window /* browser */ || global) /* node */ as any; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 0de1068f7..ac79e4fef 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -24,7 +24,6 @@ import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { undoable, undoBatch, UndoManager } from '../../util/UndoManager'; import { EditableView } from '../EditableView'; -import { TREE_BULLET_WIDTH } from '../global/globalCssVariables.scss'; import { DocumentView, DocumentViewInternal, DocumentViewProps, OpenWhere, StyleProviderFunc } from '../nodes/DocumentView'; import { FieldViewProps } from '../nodes/FieldView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; @@ -35,7 +34,9 @@ import { CollectionTreeView, TreeViewType } from './CollectionTreeView'; import { CollectionView } from './CollectionView'; import { TreeSort } from './TreeSort'; import './TreeView.scss'; -import React = require('react'); +import * as React from 'react'; +// import { TREE_BULLET_WIDTH } from '../global/globalCssVariables.scss'; +const TREE_BULLET_WIDTH = '10px'; export interface TreeViewProps { treeView: CollectionTreeView; @@ -118,16 +119,16 @@ export class TreeView extends React.Component<TreeViewProps> { return this.doc._type_collection === CollectionViewType.Docking ? this.fieldKey : this.props.treeView.dashboardMode - ? this.fieldKey - : this.props.treeView.fileSysMode - ? this.doc.isFolder - ? this.fieldKey - : 'data' // file system folders display their contents (data). used to be they displayed their embeddings but now its a tree structure and not a flat list - : this.props.treeView.outlineMode || this.childDocs - ? this.fieldKey - : Doc.noviceMode - ? 'layout' - : StrCast(this.props.treeView.doc.treeView_ExpandedView, 'fields'); + ? this.fieldKey + : this.props.treeView.fileSysMode + ? this.doc.isFolder + ? this.fieldKey + : 'data' // file system folders display their contents (data). used to be they displayed their embeddings but now its a tree structure and not a flat list + : this.props.treeView.outlineMode || this.childDocs + ? this.fieldKey + : Doc.noviceMode + ? 'layout' + : StrCast(this.props.treeView.doc.treeView_ExpandedView, 'fields'); } @computed get doc() { @@ -832,14 +833,14 @@ export class TreeView extends React.Component<TreeViewProps> { ...(this.doc.isFolder ? folderOp : Doc.IsSystem(this.doc) - ? [] - : this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) - ? [openEmbedding, makeFolder] - : this.doc._type_collection === CollectionViewType.Docking - ? [] - : this.props.treeView.Document === Doc.MyRecentlyClosed - ? [reopenDoc] - : [openEmbedding, focusDoc]), + ? [] + : this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) + ? [openEmbedding, makeFolder] + : this.doc._type_collection === CollectionViewType.Docking + ? [] + : this.props.treeView.Document === Doc.MyRecentlyClosed + ? [reopenDoc] + : [openEmbedding, focusDoc]), ]; }; childContextMenuItems = () => { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx index 00505dbe3..99ee5ef4e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx @@ -2,7 +2,7 @@ import { observer } from 'mobx-react'; import { Doc } from '../../../../fields/Doc'; import { NumCast } from '../../../../fields/Types'; import './CollectionFreeFormView.scss'; -import React = require('react'); +import * as React from 'react'; export interface CollectionFreeFormViewBackgroundGridProps { panX: () => number; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx index 3af5a6c4b..3ba7aedef 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx @@ -1,7 +1,7 @@ import { IReactionDisposer, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import * as React from 'react'; import './CollectionFreeFormView.scss'; -import React = require('react'); /** * An Fsa Arc. The first array element is a test condition function that will be observed. diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx index daf1bd8a7..1265dc2de 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx @@ -4,7 +4,7 @@ import { Doc } from '../../../../fields/Doc'; import { ScriptField } from '../../../../fields/ScriptField'; import { PresBox } from '../../nodes/trails/PresBox'; import './CollectionFreeFormView.scss'; -import React = require('react'); +import * as React from 'react'; import { CollectionFreeFormView } from './CollectionFreeFormView'; import { NumCast } from '../../../../fields/Types'; import { LinkManager } from '../../../util/LinkManager'; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index d6a738084..b8c0967c1 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -5,7 +5,7 @@ import { RefField } from '../../../../fields/RefField'; import { listSpec } from '../../../../fields/Schema'; import { Cast, NumCast, StrCast } from '../../../../fields/Types'; import { aggregateBounds } from '../../../../Utils'; -import React = require('react'); +import * as React from 'react'; export interface ViewDefBounds { type: string; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 0c0d45a30..4995925c8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -13,7 +13,7 @@ import { SnappingManager } from '../../../util/SnappingManager'; import { Colors } from '../../global/globalEnums'; import { DocumentView } from '../../nodes/DocumentView'; import './CollectionFreeFormLinkView.scss'; -import React = require('react'); +import * as React from 'react'; export interface CollectionFreeFormLinkViewProps { A: DocumentView; @@ -32,7 +32,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo componentWillUnmount() { this._anchorDisposer?.(); } - @action timeout = action(() => Date.now() < this._start++ + 1000 && (this._timeout = setTimeout(this.timeout, 25))); + @action timeout: any = action(() => Date.now() < this._start++ + 1000 && (this._timeout = setTimeout(this.timeout, 25))); componentDidMount() { this._anchorDisposer = reaction( () => [ diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index 420e6a318..779a0bf96 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -5,7 +5,7 @@ import { DocumentManager } from '../../../util/DocumentManager'; import { LightboxView } from '../../LightboxView'; import './CollectionFreeFormLinksView.scss'; import { CollectionFreeFormLinkView } from './CollectionFreeFormLinkView'; -import React = require('react'); +import * as React from 'react'; @observer export class CollectionFreeFormLinksView extends React.Component { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx index 38aeea152..f54726a00 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx @@ -4,7 +4,7 @@ import { Doc } from '../../../../fields/Doc'; import { ScriptField } from '../../../../fields/ScriptField'; import { PresBox } from '../../nodes/trails/PresBox'; import './CollectionFreeFormView.scss'; -import React = require('react'); +import * as React from 'react'; import { CollectionFreeFormView } from './CollectionFreeFormView'; export interface CollectionFreeFormPannableContentsProps { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx index 9e8d92d7d..45e24bbb2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx @@ -9,8 +9,8 @@ import { listSpec } from '../../../../fields/Schema'; import { Cast } from '../../../../fields/Types'; import { CollectionViewProps } from '../CollectionView'; import './CollectionFreeFormView.scss'; -import React = require('react'); -import v5 = require('uuid/v5'); +import * as React from 'react'; +import * as uuid from 'uuid'; @observer export class CollectionFreeFormRemoteCursors extends React.Component<CollectionViewProps> { @@ -42,7 +42,7 @@ export class CollectionFreeFormRemoteCursors extends React.Component<CollectionV if (el) { const ctx = el.getContext('2d'); if (ctx) { - ctx.fillStyle = '#' + v5(metadata.id, v5.URL).substring(0, 6).toUpperCase() + '22'; + ctx.fillStyle = '#' + uuid.v5(metadata.id, uuid.v5.URL).substring(0, 6).toUpperCase() + '22'; ctx.fillRect(0, 0, 20, 20); ctx.fillStyle = 'black'; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 91617ec44..03d302f39 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -3,6 +3,7 @@ import { Colors } from 'browndash-components'; import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; +import * as React from 'react'; import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; import { DocData, Height, Width } from '../../../../fields/DocSymbols'; @@ -45,13 +46,12 @@ import { StyleProp } from '../../StyleProvider'; import { CollectionSubView } from '../CollectionSubView'; import { TreeViewType } from '../CollectionTreeView'; import { CollectionFreeFormBackgroundGrid } from './CollectionFreeFormBackgroundGrid'; +import { CollectionFreeFormInfoUI } from './CollectionFreeFormInfoUI'; import { computePassLayout, computePivotLayout, computeStarburstLayout, computeTimelineLayout, PoolData, ViewDefBounds, ViewDefResult } from './CollectionFreeFormLayoutEngines'; import { CollectionFreeFormPannableContents } from './CollectionFreeFormPannableContents'; import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCursors'; import './CollectionFreeFormView.scss'; import { MarqueeView } from './MarqueeView'; -import React = require('react'); -import { CollectionFreeFormInfoUI } from './CollectionFreeFormInfoUI'; export type collectionFreeformViewProps = { NativeWidth?: () => number; @@ -815,23 +815,26 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection eraserMax.X >= inkViewBounds.left && eraserMax.Y >= inkViewBounds.top ) - .reduce((intersections, { inkStroke, inkView }) => { - const { inkData } = inkStroke.inkScaledData(); - // Convert from screen space to ink space for the intersection. - const prevPointInkSpace = inkStroke.ptFromScreen(lastPoint); - const currPointInkSpace = inkStroke.ptFromScreen(currPoint); - for (var i = 0; i < inkData.length - 3; i += 4) { - const rawIntersects = InkField.Segment(inkData, i).intersects({ - // compute all unique intersections - p1: { x: prevPointInkSpace.X, y: prevPointInkSpace.Y }, - p2: { x: currPointInkSpace.X, y: currPointInkSpace.Y }, - }); - const intersects = Array.from(new Set(rawIntersects as (number | string)[])); // convert to more manageable union array type - // return tuples of the inkingStroke intersected, and the t value of the intersection - intersections.push(...intersects.map(t => ({ inkView, t: +t + Math.floor(i / 4) }))); // convert string t's to numbers and add start of curve segment to convert from local t value to t value along complete curve - } - return intersections; - }, [] as { t: number; inkView: DocumentView }[]); + .reduce( + (intersections, { inkStroke, inkView }) => { + const { inkData } = inkStroke.inkScaledData(); + // Convert from screen space to ink space for the intersection. + const prevPointInkSpace = inkStroke.ptFromScreen(lastPoint); + const currPointInkSpace = inkStroke.ptFromScreen(currPoint); + for (var i = 0; i < inkData.length - 3; i += 4) { + const rawIntersects = InkField.Segment(inkData, i).intersects({ + // compute all unique intersections + p1: { x: prevPointInkSpace.X, y: prevPointInkSpace.Y }, + p2: { x: currPointInkSpace.X, y: currPointInkSpace.Y }, + }); + const intersects = Array.from(new Set(rawIntersects as (number | string)[])); // convert to more manageable union array type + // return tuples of the inkingStroke intersected, and the t value of the intersection + intersections.push(...intersects.map(t => ({ inkView, t: +t + Math.floor(i / 4) }))); // convert string t's to numbers and add start of curve segment to convert from local t value to t value along complete curve + } + return intersections; + }, + [] as { t: number; inkView: DocumentView }[] + ); }; /** diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index 607f9fb95..825bd5f19 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -1,14 +1,11 @@ -import React = require('react'); import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; -import { observer } from 'mobx-react'; -import { unimplementedFunction } from '../../../../Utils'; -import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu'; import { IconButton } from 'browndash-components'; -import { StrCast } from '../../../../fields/Types'; -import { Doc } from '../../../../fields/Doc'; import { computed } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { unimplementedFunction } from '../../../../Utils'; import { SettingsManager } from '../../../util/SettingsManager'; +import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu'; @observer export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> { diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 18b9b4423..330c13e97 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -24,7 +24,7 @@ import { PreviewCursor } from '../../PreviewCursor'; import { SubCollectionViewProps } from '../CollectionSubView'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './MarqueeView.scss'; -import React = require('react'); +import * as React from 'react'; import { freeformScrollMode } from '../../../util/SettingsManager'; interface MarqueeViewProps { diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.scss b/src/client/views/collections/collectionLinear/CollectionLinearView.scss index d0c14a21d..3c2f5ccd7 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.scss +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.scss @@ -18,9 +18,9 @@ user-select: none; } - > input:not(:checked) ~ &.true { - background-color: transparent; - } + // > input:not(:checked) ~ &.true { + // background-color: transparent; + // } .collectionLinearView { display: flex; diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index a367e3e73..0ee5f3b40 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { Toggle, ToggleType, Type } from 'browndash-components'; import { action, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 030f9953c..029d39f88 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable, ObservableMap, observe } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index 65e47f441..0e37198bb 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 03697b40a..53f4a4d51 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { IconButton, Size } from 'browndash-components'; import { computed } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 0ad76db35..de29d8602 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -14,7 +14,7 @@ import { undoable, UndoManager } from '../../util/UndoManager'; import { CollectionFreeFormView } from '../collections/collectionFreeForm'; import { GestureOverlay } from '../GestureOverlay'; import { ActiveFillColor, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth, SetActiveIsInkMask } from '../InkingStroke'; -import { InkTranscription } from '../InkTranscription'; +// import { InkTranscription } from '../InkTranscription'; import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView'; import { DocumentView } from '../nodes/DocumentView'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; @@ -293,14 +293,14 @@ export function createInkGroup(inksToGroup?: Doc[], isSubGroup?: boolean) { // TODO: nda - will probably need to go through and only remove the unprocessed selected docs ffView.unprocessedDocs = []; - InkTranscription.Instance.transcribeInk(newCollection, selected, false); + // InkTranscription.Instance.transcribeInk(newCollection, selected, false); }); } CollectionFreeFormView.collectionsWithUnprocessedInk.clear(); } function setActiveTool(tool: InkTool | GestureUtils.Gestures, keepPrim: boolean, checkResult?: boolean) { - InkTranscription.Instance?.createInkGroup(); + // InkTranscription.Instance?.createInkGroup(); if (checkResult) { return (Doc.ActiveTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool ? GestureOverlay.Instance?.KeepPrimitiveMode || ![GestureUtils.Gestures.Circle, GestureUtils.Gestures.Line, GestureUtils.Gestures.Rectangle].includes(tool as GestureUtils.Gestures) diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx index 3082c632d..3d9cf1893 100644 --- a/src/client/views/linking/LinkMenu.tsx +++ b/src/client/views/linking/LinkMenu.tsx @@ -6,7 +6,7 @@ import { DocumentView } from '../nodes/DocumentView'; import { LinkDocPreview } from '../nodes/LinkDocPreview'; import './LinkMenu.scss'; import { LinkMenuGroup } from './LinkMenuGroup'; -import React = require('react'); +import * as React from 'react'; import { SettingsManager } from '../../util/SettingsManager'; interface Props { diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx index 5453ed07b..91142b90b 100644 --- a/src/client/views/linking/LinkMenuGroup.tsx +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -7,7 +7,7 @@ import { LinkManager } from '../../util/LinkManager'; import { DocumentView } from '../nodes/DocumentView'; import './LinkMenu.scss'; import { LinkMenuItem } from './LinkMenuItem'; -import React = require('react'); +import * as React from 'react'; import { DocumentType } from '../../documents/DocumentTypes'; interface LinkMenuGroupProps { diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 611771fff..12db7fa4b 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -1,6 +1,6 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import { Doc } from '../../../fields/Doc'; @@ -17,7 +17,7 @@ import { undoBatch } from '../../util/UndoManager'; import { DocumentView, DocumentViewInternal, OpenWhere } from '../nodes/DocumentView'; import { LinkDocPreview } from '../nodes/LinkDocPreview'; import './LinkMenuItem.scss'; -import React = require('react'); +import * as React from 'react'; interface LinkMenuItemProps { groupType: string; diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx index a36c8d778..5460a6daf 100644 --- a/src/client/views/linking/LinkPopup.tsx +++ b/src/client/views/linking/LinkPopup.tsx @@ -10,7 +10,7 @@ import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { SearchBox } from '../search/SearchBox'; import { DefaultStyleProvider } from '../StyleProvider'; import './LinkPopup.scss'; -import React = require('react'); +import * as React from 'react'; interface LinkPopupProps { linkFrom?: () => Doc | undefined; diff --git a/src/client/views/linking/LinkRelationshipSearch.tsx b/src/client/views/linking/LinkRelationshipSearch.tsx index 9662b2fea..3e7f5be74 100644 --- a/src/client/views/linking/LinkRelationshipSearch.tsx +++ b/src/client/views/linking/LinkRelationshipSearch.tsx @@ -1,6 +1,6 @@ import { observer } from 'mobx-react'; import './LinkEditor.scss'; -import React = require('react'); +import * as React from 'react'; interface link_relationshipSearchProps { results: string[] | undefined; diff --git a/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx b/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx index a085e4a66..23027808f 100644 --- a/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx +++ b/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx @@ -25,11 +25,13 @@ export const Recommendation = (props: IRecommendation) => { switch (type) { case 'YouTube': console.log('create ', type, 'document'); - doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript }); + doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315 }); + doc.transcript = transcript ? JSON.stringify(transcript) : undefined; break; case 'Video': console.log('create ', type, 'document'); - doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript }); + doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315 }); + doc.transcript = transcript ? JSON.stringify(transcript) : undefined; break; case 'Webpage': console.log('create ', type, 'document'); diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index dacdbe986..1fb26c99b 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -1,6 +1,6 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, computed, IReactionDisposer, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { DateField } from '../../../fields/DateField'; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 6195a155d..624f28413 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -14,7 +14,7 @@ import { DocComponent } from '../DocComponent'; import { StyleProp } from '../StyleProvider'; import './CollectionFreeFormDocumentView.scss'; import { DocumentView, DocumentViewProps, OpenWhere } from './DocumentView'; -import React = require('react'); +import * as React from 'react'; import { ScriptingGlobals } from '../../util/ScriptingGlobals'; export interface CollectionFreeFormDocumentViewWrapperProps extends DocumentViewProps { diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx index 2a20d935b..b4ba51814 100644 --- a/src/client/views/nodes/ColorBox.tsx +++ b/src/client/views/nodes/ColorBox.tsx @@ -1,9 +1,8 @@ -import React = require('react'); +import * as React from 'react'; import { action } from 'mobx'; import { observer } from 'mobx-react'; -import { ColorState, SketchPicker } from 'react-color'; +import { ColorResult, SketchPicker } from 'react-color'; import { Doc } from '../../../fields/Doc'; -import { Height } from '../../../fields/DocSymbols'; import { InkTool } from '../../../fields/InkField'; import { NumCast, StrCast } from '../../../fields/Types'; import { DashColor } from '../../../Utils'; @@ -25,7 +24,7 @@ export class ColorBox extends ViewBoxBaseComponent<FieldViewProps>() { @undoBatch @action - static switchColor(color: ColorState) { + static switchColor(color: ColorResult) { SetActiveInkColor(color.hex); SelectionManager.Views().map(view => { diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 9fd4fbcaa..72a473114 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -13,7 +13,7 @@ import './ComparisonBox.scss'; import { DocumentView, DocumentViewProps } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import { PinProps, PresBox } from './trails'; -import React = require('react'); +import * as React from 'react'; @observer export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps>() { diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx index 4dbd67485..c2e03744e 100644 --- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx @@ -1,3 +1,4 @@ +import { Checkbox } from '@mui/material'; import { ColorPicker, EditableText, Size, Type } from 'browndash-components'; import * as d3 from 'd3'; import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; @@ -12,7 +13,6 @@ import { Docs } from '../../../../documents/Documents'; import { undoable } from '../../../../util/UndoManager'; import { PinProps, PresBox } from '../../trails'; import './Chart.scss'; -import { Checkbox } from '@material-ui/core'; export interface PieChartProps { Document: Doc; @@ -277,6 +277,7 @@ export class PieChart extends React.Component<PieChartProps> { return 'slice'; } ) + // @ts-ignore .attr('d', arc) .on('click', onPointClick) .on('mouseover', onHover) diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index 9ac06cf3c..d422a7536 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -10,8 +10,9 @@ import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../../Utils'; import { DragManager } from '../../../../util/DragManager'; import { DocumentView } from '../../DocumentView'; import { DataVizView } from '../DataVizBox'; -import { DATA_VIZ_TABLE_ROW_HEIGHT } from '../../../global/globalCssVariables.scss'; import './Chart.scss'; +//import { DATA_VIZ_TABLE_ROW_HEIGHT } from '../../../global/globalCssVariables.scss'; +const DATA_VIZ_TABLE_ROW_HEIGHT = '30px'; interface TableBoxProps { Document: Doc; diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 4b58bfe48..54cfba506 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -1,6 +1,5 @@ import { computed } from 'mobx'; import { observer } from 'mobx-react'; -import { MouseEventHandler } from 'react-select'; import { Doc, Opt } from '../../../fields/Doc'; import { AclPrivate, DocData } from '../../../fields/DocSymbols'; import { ScriptField } from '../../../fields/ScriptField'; @@ -46,7 +45,7 @@ import { ScriptingBox } from './ScriptingBox'; import { PresBox } from './trails/PresBox'; import { VideoBox } from './VideoBox'; import { WebBox } from './WebBox'; -import React = require('react'); +import * as React from 'react'; import XRegExp = require('xregexp'); const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? @@ -171,7 +170,7 @@ export class DocumentContentsView extends React.Component< ...this.props, Document: this.layoutDoc ?? this.props.Document, TemplateDataDocument: templateDataDoc instanceof Promise ? undefined : templateDataDoc, - onClick: onClick as any as MouseEventHandler, // pass onClick script as if it were a real function -- it will be interpreted properly in the HTMLtag + onClick: onClick as any as React.MouseEventHandler, // pass onClick script as if it were a real function -- it will be interpreted properly in the HTMLtag onInput: onInput as any as React.FormEventHandler, }; return { diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx index 49592d993..e8d8c05e3 100644 --- a/src/client/views/nodes/DocumentIcon.tsx +++ b/src/client/views/nodes/DocumentIcon.tsx @@ -4,7 +4,7 @@ import { DocumentView } from './DocumentView'; import { DocumentManager } from '../../util/DocumentManager'; import { Transformer, ts } from '../../util/Scripting'; import { Field } from '../../../fields/Doc'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, observable } from 'mobx'; import { Id } from '../../../fields/FieldSymbols'; import { factory } from 'typescript'; diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index ce3650749..90b044374 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, computed, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc } from '../../../fields/Doc'; @@ -15,8 +15,8 @@ import { DocumentView } from './DocumentView'; import { LinkDescriptionPopup } from './LinkDescriptionPopup'; import { TaskCompletionBox } from './TaskCompletedBox'; import { PinProps } from './trails'; -import React = require('react'); -import _ = require('lodash'); +import * as React from 'react'; +import * as _ from 'lodash'; interface DocumentLinksButtonProps { View: DocumentView; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 40ae1459f..f2a910023 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -51,7 +51,7 @@ import { KeyValueBox } from './KeyValueBox'; import { LinkAnchorBox } from './LinkAnchorBox'; import { PresEffect, PresEffectDirection } from './trails'; import { PinProps, PresBox } from './trails/PresBox'; -import React = require('react'); +import * as React from 'react'; const { Howl } = require('howler'); interface Window { diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx index cd263f82a..23413b9d1 100644 --- a/src/client/views/nodes/EquationBox.tsx +++ b/src/client/views/nodes/EquationBox.tsx @@ -1,4 +1,4 @@ -import EquationEditor from 'equation-editor-react'; +import EquationEditor from './formattedText/EquationEditor'; import { action, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; diff --git a/src/client/views/nodes/FaceRectangle.tsx b/src/client/views/nodes/FaceRectangle.tsx index 20afa4565..8d03bf57a 100644 --- a/src/client/views/nodes/FaceRectangle.tsx +++ b/src/client/views/nodes/FaceRectangle.tsx @@ -1,14 +1,14 @@ -import React = require("react"); -import { observer } from "mobx-react"; -import { observable, runInAction } from "mobx"; -import { RectangleTemplate } from "./FaceRectangles"; +import * as React from 'react'; +import { observer } from 'mobx-react'; +import { observable, runInAction } from 'mobx'; +import { RectangleTemplate } from './FaceRectangles'; @observer export default class FaceRectangle extends React.Component<{ rectangle: RectangleTemplate }> { @observable private opacity = 0; componentDidMount() { - setTimeout(() => runInAction(() => this.opacity = 1), 500); + setTimeout(() => runInAction(() => (this.opacity = 1)), 500); } render() { @@ -18,12 +18,11 @@ export default class FaceRectangle extends React.Component<{ rectangle: Rectangl style={{ ...rectangle.style, opacity: this.opacity, - transition: "1s ease opacity", - position: "absolute", - borderRadius: 5 + transition: '1s ease opacity', + position: 'absolute', + borderRadius: 5, }} /> ); } - -}
\ No newline at end of file +} diff --git a/src/client/views/nodes/FaceRectangles.tsx b/src/client/views/nodes/FaceRectangles.tsx index 0d1e063af..26e720c0d 100644 --- a/src/client/views/nodes/FaceRectangles.tsx +++ b/src/client/views/nodes/FaceRectangles.tsx @@ -1,9 +1,9 @@ -import React = require("react"); -import { Doc, DocListCast } from "../../../fields/Doc"; -import { Cast, NumCast } from "../../../fields/Types"; -import { observer } from "mobx-react"; -import { Id } from "../../../fields/FieldSymbols"; -import FaceRectangle from "./FaceRectangle"; +import * as React from 'react'; +import { Doc, DocListCast } from '../../../fields/Doc'; +import { Cast, NumCast } from '../../../fields/Types'; +import { observer } from 'mobx-react'; +import { Id } from '../../../fields/FieldSymbols'; +import FaceRectangle from './FaceRectangle'; interface FaceRectanglesProps { document: Doc; @@ -18,7 +18,6 @@ export interface RectangleTemplate { @observer export class FaceRectangles extends React.Component<FaceRectanglesProps> { - render() { const faces = DocListCast(this.props.document.faces); const templates: RectangleTemplate[] = faces.map(faceDoc => { @@ -33,14 +32,15 @@ export class FaceRectangles extends React.Component<FaceRectanglesProps> { } as React.CSSProperties; return { id: rectangle[Id], - style: style + style: style, }; }); return ( <div> - {templates.map(rectangle => <FaceRectangle key={rectangle.id} rectangle={rectangle} />)} + {templates.map(rectangle => ( + <FaceRectangle key={rectangle.id} rectangle={rectangle} /> + ))} </div> ); } - -}
\ No newline at end of file +} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 219e3025a..f4c5167a5 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { computed } from 'mobx'; import { observer } from 'mobx-react'; import { DateField } from '../../../fields/DateField'; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index d28d71fe3..dbfeec1c3 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { extname } from 'path'; @@ -35,7 +35,7 @@ import { FaceRectangles } from './FaceRectangles'; import { FieldView, FieldViewProps } from './FieldView'; import './ImageBox.scss'; import { PinProps, PresBox } from './trails'; -import React = require('react'); +import * as React from 'react'; export const pageSchema = createSchema({ googlePhotosUrl: 'string', diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 0c6377c3a..d2325a807 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -20,7 +20,7 @@ import { FormattedTextBox } from './formattedText/FormattedTextBox'; import { ImageBox } from './ImageBox'; import './KeyValueBox.scss'; import { KeyValuePair } from './KeyValuePair'; -import React = require('react'); +import * as React from 'react'; export type KVPScript = { script: CompiledScript; diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 577685636..3cda70648 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -12,9 +12,9 @@ import { FieldView, FieldViewProps } from './FieldView'; import { KeyValueBox } from './KeyValueBox'; import './KeyValueBox.scss'; import './KeyValuePair.scss'; -import React = require('react'); +import * as React from 'react'; import { DocCast } from '../../../fields/Types'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { DocumentOptions, FInfo } from '../../documents/Documents'; // Represents one row in a key value plane diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index e1421878b..71f9c000b 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -84,7 +84,18 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps & LabelBoxProp return this._mouseOver ? StrCast(this.layoutDoc._hoverBackgroundColor) : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor); } - fitTextToBox = (r: any) => { + fitTextToBox = (r: any): NodeJS.Timeout | { + rotateText: null; + fontSizeFactor: number; + minimumFontSize: number; + maximumFontSize: number; + limitingDimension: string; + horizontalAlign: string; + verticalAlign: string; + textAlign: string; + singleLine: boolean; + whiteSpace: string; + } => { const singleLine = BoolCast(this.layoutDoc._singleLine, true); const params = { rotateText: null, @@ -143,9 +154,9 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps & LabelBoxProp paddingBottom: NumCast(this.layoutDoc._yPadding), width: this.props.PanelWidth(), height: this.props.PanelHeight(), - whiteSpace: typeof boxParams !== 'number' && boxParams.singleLine ? 'pre' : 'pre-wrap', + whiteSpace: !(boxParams instanceof NodeJS.Timeout) && boxParams.singleLine ? 'pre' : 'pre-wrap', }}> - <span style={{ width: typeof boxParams !== 'number' && boxParams.singleLine ? '' : '100%' }} ref={action((r: any) => this.fitTextToBox(r))}> + <span style={{ width: !(boxParams instanceof NodeJS.Timeout) && boxParams.singleLine ? '' : '100%' }} ref={action((r: any) => this.fitTextToBox(r))}> {label.startsWith('#') ? null : label.replace(/([^a-zA-Z])/g, '$1\u200b')} </span> </div> diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index cf157c3a9..1b5161e47 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -12,9 +12,9 @@ import { StyleProp } from '../StyleProvider'; import { FieldView, FieldViewProps } from './FieldView'; import './LinkAnchorBox.scss'; import { LinkDocPreview } from './LinkDocPreview'; -import React = require('react'); -import globalCssVariables = require('../global/globalCssVariables.scss'); - +import * as React from 'react'; +// import globalCssVariables = require('../global/globalCssVariables.scss'); +const MEDIUM_GRAY = 'lightGray'; @observer export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() { public static LayoutString(fieldKey: string) { @@ -77,8 +77,8 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() { const selView = SelectionManager.Views().lastElement()?.props.LayoutTemplateString?.includes('link_anchor_1') ? 'link_anchor_1' : SelectionManager.Views().lastElement()?.props.LayoutTemplateString?.includes('link_anchor_2') - ? 'link_anchor_2' - : ''; + ? 'link_anchor_2' + : ''; return ( <div ref={this._ref} @@ -97,7 +97,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() { onPointerDown={this.onPointerDown} onContextMenu={this.specificContextMenu} style={{ - border: selView && this.dataDoc[selView] === this.dataDoc[this.fieldKey] ? `solid ${globalCssVariables.MEDIUM_GRAY} 2px` : undefined, + border: selView && this.dataDoc[selView] === this.dataDoc[this.fieldKey] ? `solid ${MEDIUM_GRAY} 2px` : undefined, background, left: `calc(${x}% - ${small ? 2.5 : 7.5}px)`, top: `calc(${y}% - ${small ? 2.5 : 7.5}px)`, diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 743075c89..ed448ecfb 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { Bezier } from 'bezier-js'; import { computed, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx index c45045a8a..32300d60a 100644 --- a/src/client/views/nodes/LinkDescriptionPopup.tsx +++ b/src/client/views/nodes/LinkDescriptionPopup.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; import { Doc } from '../../../fields/Doc'; diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index ad5324b3e..4df8e792e 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import wiki from 'wikijs'; @@ -18,7 +18,7 @@ import { SettingsManager } from '../../util/SettingsManager'; import { Transform } from '../../util/Transform'; import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView'; import './LinkDocPreview.scss'; -import React = require('react'); +import * as React from 'react'; interface LinkDocPreviewProps { linkDoc?: Doc; diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx index f6680aac0..e6c1db0af 100644 --- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx +++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { IReactionDisposer, ObservableMap, reaction } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 398d1255e..69723b171 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -794,17 +794,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps /> ))} </div> - {/* <MapBoxInfoWindow - key={Docs.Create.MapMarkerDocument(NumCast(40), NumCast(40), false, [], {})[Id]} - {...OmitKeys(this.props, ['NativeWidth', 'NativeHeight', 'setContentView']).omit} - place={Docs.Create.MapMarkerDocument(NumCast(40), NumCast(40), false, [], {})} - markerMap={this.markerMap} - PanelWidth={this.infoWidth} - PanelHeight={this.infoHeight} - moveDocument={this.moveDocument} - isAnyChildContentActive={this.isAnyChildContentActive} - whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} - /> */} </div> {/* </LoadScript > */} <div className="mapBox-sidebar" style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}> diff --git a/src/client/views/nodes/MapBox/MapBox2.tsx b/src/client/views/nodes/MapBox/MapBox2.tsx index a77bfc50a..39ed6a47e 100644 --- a/src/client/views/nodes/MapBox/MapBox2.tsx +++ b/src/client/views/nodes/MapBox/MapBox2.tsx @@ -1,597 +1,597 @@ -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Autocomplete, GoogleMap, GoogleMapProps, Marker } from '@react-google-maps/api'; -import { action, computed, IReactionDisposer, observable, ObservableMap, runInAction } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; -import { Id } from '../../../../fields/FieldSymbols'; -import { NumCast, StrCast } from '../../../../fields/Types'; -import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils'; -import { Docs } from '../../../documents/Documents'; -import { DragManager } from '../../../util/DragManager'; -import { SnappingManager } from '../../../util/SnappingManager'; -import { UndoManager } from '../../../util/UndoManager'; -import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; -import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent'; -import { Colors } from '../../global/globalEnums'; -import { AnchorMenu } from '../../pdf/AnchorMenu'; -import { Annotation } from '../../pdf/Annotation'; -import { SidebarAnnos } from '../../SidebarAnnos'; -import { FieldView, FieldViewProps } from '../FieldView'; -import { PinProps } from '../trails'; -import './MapBox2.scss'; -import { MapBoxInfoWindow } from './MapBoxInfoWindow'; - -/** - * MapBox2 architecture: - * Main component: MapBox2.tsx - * Supporting Components: SidebarAnnos, CollectionStackingView - * - * MapBox2 is a node that extends the ViewBoxAnnotatableComponent. Similar to PDFBox and WebBox, it supports interaction between sidebar content and document content. - * The main body of MapBox2 uses Google Maps API to allow location retrieval, adding map markers, pan and zoom, and open street view. - * Dash Document architecture is integrated with Maps API: When drag and dropping documents with ExifData (gps Latitude and Longitude information) available, - * sidebarAddDocument function checks if the document contains lat & lng information, if it does, then the document is added to both the sidebar and the infowindow (a pop up corresponding to a map marker--pin on map). - * The lat and lng field of the document is filled when importing (spec see ConvertDMSToDD method and processFileUpload method in Documents.ts). - * A map marker is considered a document that contains a collection with stacking view of documents, it has a lat, lng location, which is passed to Maps API's custom marker (red pin) to be rendered on the google maps - */ - -// const _global = (window /* browser */ || global /* node */) as any; - -const mapContainerStyle = { - height: '100%', -}; - -const defaultCenter = { - lat: 42.360081, - lng: -71.058884, -}; - -const mapOptions = { - fullscreenControl: false, -}; - -const apiKey = process.env.GOOGLE_MAPS; - -const script = document.createElement('script'); -script.defer = true; -script.async = true; -script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places,drawing`; -console.log(script.src); -document.head.appendChild(script); - -/** - * Consider integrating later: allows for drawing, circling, making shapes on map - */ -// const drawingManager = new window.google.maps.drawing.DrawingManager({ -// drawingControl: true, -// drawingControlOptions: { -// position: google.maps.ControlPosition.TOP_RIGHT, -// drawingModes: [ -// google.maps.drawing.OverlayType.MARKER, -// // currently we are not supporting the following drawing mode on map, a thought for future development -// google.maps.drawing.OverlayType.CIRCLE, -// google.maps.drawing.OverlayType.POLYLINE, -// ], -// }, -// }); - -// options for searchbox in Google Maps Places Autocomplete API -const options = { - fields: ['formatted_address', 'geometry', 'name'], // note: level of details is charged by item per retrieval, not recommended to return all fields - strictBounds: false, - types: ['establishment'], // type pf places, subject of change according to user need -} as google.maps.places.AutocompleteOptions; - -@observer -export class MapBox2 extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps & Partial<GoogleMapProps>>() { - private _dropDisposer?: DragManager.DragDropDisposer; - private _disposers: { [name: string]: IReactionDisposer } = {}; - private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef(); - @observable private _overlayAnnoInfo: Opt<Doc>; - showInfo = action((anno: Opt<Doc>) => (this._overlayAnnoInfo = anno)); - public static LayoutString(fieldKey: string) { - return FieldView.LayoutString(MapBox2, fieldKey); - } - public get SidebarKey() { - return this.fieldKey + '_sidebar'; - } - private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void); - @computed get inlineTextAnnotations() { - return this.allMapMarkers.filter(a => a.text_inlineAnnotations); - } - - @observable private _map: google.maps.Map = null as unknown as google.maps.Map; - @observable private selectedPlace: Doc | undefined; - @observable private markerMap: { [id: string]: google.maps.Marker } = {}; - @observable private center = navigator.geolocation ? navigator.geolocation.getCurrentPosition : defaultCenter; - @observable private inputRef = React.createRef<HTMLInputElement>(); - @observable private searchMarkers: google.maps.Marker[] = []; - @observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options); - @observable private _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>(); - @computed get allSidebarDocs() { - return DocListCast(this.dataDoc[this.SidebarKey]); - } - @computed get allMapMarkers() { - return DocListCast(this.dataDoc[this.annotationKey]); - } - @observable private toggleAddMarker = false; - - @observable _showSidebar = false; - @computed get SidebarShown() { - return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false; - } - - static _canAnnotate = true; - static _hadSelection: boolean = false; - private _sidebarRef = React.createRef<SidebarAnnos>(); - private _ref: React.RefObject<HTMLDivElement> = React.createRef(); - - componentDidMount() { - this.props.setContentView?.(this); - } - - @action - private setSearchBox = (searchBox: any) => { - this.searchBox = searchBox; - }; - - // iterate allMarkers to size, center, and zoom map to contain all markers - private fitBounds = (map: google.maps.Map) => { - const curBounds = map.getBounds() ?? new window.google.maps.LatLngBounds(); - const isFitting = this.allMapMarkers.reduce((fits, place) => fits && curBounds?.contains({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), true as boolean); - !isFitting && map.fitBounds(this.allMapMarkers.reduce((bounds, place) => bounds.extend({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), new window.google.maps.LatLngBounds())); - }; - - /** - * Custom control for add marker button - * @param controlDiv - * @param map - */ - private CenterControl = () => { - const controlDiv = document.createElement('div'); - controlDiv.className = 'MapBox2-addMarker'; - // Set CSS for the control border. - const controlUI = document.createElement('div'); - controlUI.style.backgroundColor = '#fff'; - controlUI.style.borderRadius = '3px'; - controlUI.style.cursor = 'pointer'; - controlUI.style.marginTop = '10px'; - controlUI.style.borderRadius = '4px'; - controlUI.style.marginBottom = '22px'; - controlUI.style.textAlign = 'center'; - controlUI.style.position = 'absolute'; - controlUI.style.width = '32px'; - controlUI.style.height = '32px'; - controlUI.title = 'Click to toggle marker mode. In marker mode, click on map to place a marker.'; - - const plIcon = document.createElement('img'); - plIcon.src = 'https://cdn4.iconfinder.com/data/icons/wirecons-free-vector-icons/32/add-256.png'; - plIcon.style.color = 'rgb(25,25,25)'; - plIcon.style.fontFamily = 'Roboto,Arial,sans-serif'; - plIcon.style.fontSize = '16px'; - plIcon.style.lineHeight = '32px'; - plIcon.style.left = '18'; - plIcon.style.top = '15'; - plIcon.style.position = 'absolute'; - plIcon.width = 14; - plIcon.height = 14; - plIcon.innerHTML = 'Add'; - controlUI.appendChild(plIcon); - - // Set CSS for the control interior. - const markerIcon = document.createElement('img'); - markerIcon.src = 'https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678111-map-marker-1024.png'; - markerIcon.style.color = 'rgb(25,25,25)'; - markerIcon.style.fontFamily = 'Roboto,Arial,sans-serif'; - markerIcon.style.fontSize = '16px'; - markerIcon.style.lineHeight = '32px'; - markerIcon.style.left = '-2'; - markerIcon.style.top = '1'; - markerIcon.width = 30; - markerIcon.height = 30; - markerIcon.style.position = 'absolute'; - markerIcon.innerHTML = 'Add'; - controlUI.appendChild(markerIcon); - - // Setup the click event listeners - controlUI.addEventListener('click', () => { - if (this.toggleAddMarker === true) { - this.toggleAddMarker = false; - console.log('add marker button status:' + this.toggleAddMarker); - controlUI.style.backgroundColor = '#fff'; - markerIcon.style.color = 'rgb(25,25,25)'; - } else { - this.toggleAddMarker = true; - console.log('add marker button status:' + this.toggleAddMarker); - controlUI.style.backgroundColor = '#4476f7'; - markerIcon.style.color = 'rgb(255,255,255)'; - } - }); - controlDiv.appendChild(controlUI); - return controlDiv; - }; - - /** - * Place the marker on google maps & store the empty marker as a MapMarker Document in allMarkers list - * @param position - the LatLng position where the marker is placed - * @param map - */ - @action - private placeMarker = (position: google.maps.LatLng, map: google.maps.Map) => { - const marker = new google.maps.Marker({ - position: position, - map: map, - }); - map.panTo(position); - const mapMarker = Docs.Create.PushpinDocument(NumCast(position.lat()), NumCast(position.lng()), false, [], {}); - this.addDocument(mapMarker, this.annotationKey); - }; - - _loadPending = true; - /** - * store a reference to google map instance - * setup the drawing manager on the top right corner of map - * fit map bounds to contain all markers - * @param map - */ - @action - private loadHandler = (map: google.maps.Map) => { - this._map = map; - this._loadPending = true; - const centerControlDiv = this.CenterControl(); - map.controls[google.maps.ControlPosition.TOP_RIGHT].push(centerControlDiv); - //drawingManager.setMap(map); - // if (navigator.geolocation) { - // navigator.geolocation.getCurrentPosition( - // (position: Position) => { - // const pos = { - // lat: position.coords.latitude, - // lng: position.coords.longitude, - // }; - // this._map.setCenter(pos); - // } - // ); - // } else { - // alert("Your geolocation is not supported by browser.") - // }; - map.setZoom(NumCast(this.dataDoc.map_zoom, 2.5)); - map.setCenter(new google.maps.LatLng(NumCast(this.dataDoc.mapLat), NumCast(this.dataDoc.mapLng))); - setTimeout(() => { - if (this._loadPending && this._map.getBounds()) { - this._loadPending = false; - this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); - } - }, 250); - // listener to addmarker event - this._map.addListener('click', (e: MouseEvent) => { - if (this.toggleAddMarker === true) { - this.placeMarker((e as any).latLng, map); - } - }); - }; - - @action - centered = () => { - if (this._loadPending && this._map.getBounds()) { - this._loadPending = false; - this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); - } - this.dataDoc.mapLat = this._map.getCenter()?.lat(); - this.dataDoc.mapLng = this._map.getCenter()?.lng(); - }; - - @action - zoomChanged = () => { - if (this._loadPending && this._map.getBounds()) { - this._loadPending = false; - this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); - } - this.dataDoc.map_zoom = this._map.getZoom(); - }; - - /** - * Load and render all map markers - * @param marker - * @param place - */ - @action - private markerLoadHandler = (marker: google.maps.Marker, place: Doc) => { - place[Id] ? (this.markerMap[place[Id]] = marker) : null; - }; - - /** - * on clicking the map marker, set the selected place to the marker document & set infowindowopen to be true - * @param e - * @param place - */ - @action - private markerClickHandler = (e: google.maps.MapMouseEvent, place: Doc) => { - // set which place was clicked - this.selectedPlace = place; - place.infoWindowOpen = true; - }; - - /** - * Called when dragging documents into map sidebar or directly into infowindow; to create a map marker, ref to MapMarkerDocument in Documents.ts - * @param doc - * @param sidebarKey - * @returns - */ - sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => { - console.log('print all sidebar Docs'); - if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar(); - const docs = doc instanceof Doc ? [doc] : doc; - docs.forEach(doc => { - if (doc.lat !== undefined && doc.lng !== undefined) { - const existingMarker = this.allMapMarkers.find(marker => marker.lat === doc.lat && marker.lng === doc.lng); - if (existingMarker) { - Doc.AddDocToList(existingMarker, 'data', doc); - } else { - const marker = Docs.Create.PushpinDocument(NumCast(doc.lat), NumCast(doc.lng), false, [doc], {}); - this.addDocument(marker, this.annotationKey); - } - } - }); //add to annotation list - - return this.addDocument(doc, sidebarKey); // add to sidebar list - }; - - /** - * Removing documents from the sidebar - * @param doc - * @param sidebarKey - * @returns - */ - sidebarRemoveDocument = (doc: Doc | Doc[], sidebarKey?: string) => { - if (this.layoutDoc._layout_showSidebar) this.toggleSidebar(); - const docs = doc instanceof Doc ? [doc] : doc; - return this.removeDocument(doc, sidebarKey); - }; - - /** - * Toggle sidebar onclick the tiny comment button on the top right corner - * @param e - */ - sidebarBtnDown = (e: React.PointerEvent) => { - setupMoveUpEvents( - this, - e, - (e, down, delta) => - runInAction(() => { - const localDelta = this.props - .ScreenToLocalTransform() - .scale(this.props.NativeDimScaling?.() || 1) - .transformDirection(delta[0], delta[1]); - const fullWidth = NumCast(this.layoutDoc._width); - const mapWidth = fullWidth - this.sidebarWidth(); - if (this.sidebarWidth() + localDelta[0] > 0) { - this._showSidebar = true; - this.layoutDoc._width = fullWidth + localDelta[0]; - this.layoutDoc._layout_sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth + localDelta[0])).toString() + '%'; - } else { - this._showSidebar = false; - this.layoutDoc._width = mapWidth; - this.layoutDoc._layout_sidebarWidthPercent = '0%'; - } - return false; - }), - emptyFunction, - () => UndoManager.RunInBatch(this.toggleSidebar, 'toggle sidebar map') - ); - }; - - sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth(); - @computed get layout_sidebarWidthPercent() { - return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); - } - @computed get sidebarColor() { - return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this.props.fieldKey + '_backgroundColor'], '#e4e4e4')); - } - - /** - * function that reads the place inputed from searchbox, then zoom in on the location that's been autocompleted; - * add a customized temporary marker on the map - */ - @action - private handlePlaceChanged = () => { - const place = this.searchBox.getPlace(); - - if (!place.geometry || !place.geometry.location) { - // user entered the name of a place that wasn't suggested & pressed the enter key, or place details request failed - window.alert("No details available for input: '" + place.name + "'"); - return; - } - - // zoom in on the location of the search result - if (place.geometry.viewport) { - this._map.fitBounds(place.geometry.viewport); - } else { - this._map.setCenter(place.geometry.location); - this._map.setZoom(17); - } - - // customize icon => customized icon for the nature of the location selected - const icon = { - url: place.icon as string, - size: new google.maps.Size(71, 71), - origin: new google.maps.Point(0, 0), - anchor: new google.maps.Point(17, 34), - scaledSize: new google.maps.Size(25, 25), - }; - - // put temporary cutomized marker on searched location - this.searchMarkers.forEach(marker => { - marker.setMap(null); - }); - this.searchMarkers = []; - this.searchMarkers.push( - new window.google.maps.Marker({ - map: this._map, - icon, - title: place.name, - position: place.geometry.location, - }) - ); - }; - - /** - * Handles toggle of sidebar on click the little comment button - */ - @computed get sidebarHandle() { - return ( - <div - className="MapBox2-overlayButton-sidebar" - key="sidebar" - title="Toggle Sidebar" - style={{ - display: !this.props.isContentActive() ? 'none' : undefined, - top: StrCast(this.layoutDoc._layout_showTitle) === 'title' ? 20 : 5, - backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK, - }} - onPointerDown={this.sidebarBtnDown}> - <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" /> - </div> - ); - } - - // TODO: Adding highlight box layer to Maps - @action - toggleSidebar = () => { - //1.2 * w * ? = .2 * w .2/1.2 - const prevWidth = this.sidebarWidth(); - this.layoutDoc._layout_showSidebar = (this.layoutDoc._layout_sidebarWidthPercent = StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%') === '0%' ? `${(100 * 0.2) / 1.2}%` : '0%') !== '0%'; - this.layoutDoc._width = this.layoutDoc._layout_showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth); - }; - - sidebarDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), true); - }; - sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { - const bounds = this._ref.current!.getBoundingClientRect(); - this.layoutDoc._layout_sidebarWidthPercent = '' + 100 * Math.max(0, 1 - (e.clientX - bounds.left) / bounds.width) + '%'; - this.layoutDoc._layout_showSidebar = this.layoutDoc._layout_sidebarWidthPercent !== '0%'; - e.preventDefault(); - return false; - }; - - setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => (this._setPreviewCursor = func); - - addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => { - return this.addDocument(doc, annotationKey); - }; - - pointerEvents = () => { - return this.props.isContentActive() === false ? 'none' : this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && !MarqueeOptionsMenu.Instance.isShown() ? 'all' : SnappingManager.GetIsDragging() ? undefined : 'none'; - }; - @computed get annotationLayer() { - return ( - <div className="MapBox2-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}> - {this.inlineTextAnnotations - .sort((a, b) => NumCast(a.y) - NumCast(b.y)) - .map(anno => ( - <Annotation key={`${anno[Id]}-annotation`} {...this.props} fieldKey={this.annotationKey} pointerEvents={this.pointerEvents} showInfo={this.showInfo} dataDoc={this.dataDoc} anno={anno} /> - ))} - </div> - ); - } - - getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => AnchorMenu.Instance?.GetAnchor(this._savedAnnotations, addAsAnnotation) ?? this.Document; - - /** - * render contents in allMapMarkers (e.g. images with exifData) into google maps as map marker - * @returns - */ - private renderMarkers = () => { - return this.allMapMarkers.map(place => ( - <Marker key={place[Id]} position={{ lat: NumCast(place.lat), lng: NumCast(place.lng) }} onLoad={marker => this.markerLoadHandler(marker, place)} onClick={(e: google.maps.MapMouseEvent) => this.markerClickHandler(e, place)} /> - )); - }; - - // TODO: auto center on select a document in the sidebar - private handleMapCenter = (map: google.maps.Map) => { - // console.log("print the selected views in selectionManager:") - // if (SelectionManager.Views().lastElement()) { - // console.log(SelectionManager.Views().lastElement()); - // } - }; - - panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth(); - panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); - scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); - transparentFilter = () => [...this.props.childFilters(), Utils.TransparentBackgroundFilter]; - opaqueFilter = () => [...this.props.childFilters(), Utils.OpaqueBackgroundFilter]; - infoWidth = () => this.props.PanelWidth() / 5; - infoHeight = () => this.props.PanelHeight() / 5; - anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; - savedAnnotations = () => this._savedAnnotations; - - get MicrosoftMaps() { - return (window as any).Microsoft.Maps; - } - render() { - const renderAnnotations = (childFilters?: () => string[]) => null; - return ( - <div className="MapBox2" ref={this._ref}> - <div - className="MapBox2-wrapper" - onWheel={e => e.stopPropagation()} - onPointerDown={async e => { - e.button === 0 && !e.ctrlKey && e.stopPropagation(); - }} - style={{ width: `calc(100% - ${this.layout_sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}> - <div style={{ mixBlendMode: 'multiply' }}>{renderAnnotations(this.transparentFilter)}</div> - {renderAnnotations(this.opaqueFilter)} - {SnappingManager.GetIsDragging() ? null : renderAnnotations()} - {this.annotationLayer} - - <div> - <GoogleMap mapContainerStyle={mapContainerStyle} onZoomChanged={this.zoomChanged} onCenterChanged={this.centered} onLoad={this.loadHandler} options={mapOptions}> - <Autocomplete onLoad={this.setSearchBox} onPlaceChanged={this.handlePlaceChanged}> - <input className="MapBox2-input" ref={this.inputRef} type="text" onKeyDown={e => e.stopPropagation()} placeholder="Enter location" /> - </Autocomplete> - - {this.renderMarkers()} - {this.allMapMarkers - .filter(marker => marker.infoWindowOpen) - .map(marker => ( - <MapBoxInfoWindow - key={marker[Id]} - {...this.props} - setContentView={emptyFunction} - place={marker} - markerMap={this.markerMap} - PanelWidth={this.infoWidth} - PanelHeight={this.infoHeight} - moveDocument={this.moveDocument} - isAnyChildContentActive={this.isAnyChildContentActive} - whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} - /> - ))} - {/* {this.handleMapCenter(this._map)} */} - </GoogleMap> - </div> - </div> - {/* </LoadScript > */} - <div className="MapBox2-sidebar" style={{ width: `${this.layout_sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}> - <SidebarAnnos - ref={this._sidebarRef} - {...this.props} - fieldKey={this.fieldKey} - Document={this.Document} - layoutDoc={this.layoutDoc} - dataDoc={this.dataDoc} - usePanelWidth={true} - showSidebar={this.SidebarShown} - nativeWidth={NumCast(this.layoutDoc._nativeWidth)} - whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} - PanelWidth={this.sidebarWidth} - sidebarAddDocument={this.sidebarAddDocument} - moveDocument={this.moveDocument} - removeDocument={this.sidebarRemoveDocument} - /> - </div> - {this.sidebarHandle} - </div> - ); - } -} +// import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +// import { Autocomplete, GoogleMap, GoogleMapProps, Marker } from '@react-google-maps/api'; +// import { action, computed, IReactionDisposer, observable, ObservableMap, runInAction } from 'mobx'; +// import { observer } from 'mobx-react'; +// import * as React from 'react'; +// import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; +// import { Id } from '../../../../fields/FieldSymbols'; +// import { NumCast, StrCast } from '../../../../fields/Types'; +// import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils'; +// import { Docs } from '../../../documents/Documents'; +// import { DragManager } from '../../../util/DragManager'; +// import { SnappingManager } from '../../../util/SnappingManager'; +// import { UndoManager } from '../../../util/UndoManager'; +// import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; +// import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent'; +// import { Colors } from '../../global/globalEnums'; +// import { AnchorMenu } from '../../pdf/AnchorMenu'; +// import { Annotation } from '../../pdf/Annotation'; +// import { SidebarAnnos } from '../../SidebarAnnos'; +// import { FieldView, FieldViewProps } from '../FieldView'; +// import { PinProps } from '../trails'; +// import './MapBox2.scss'; +// import { MapBoxInfoWindow } from './MapBoxInfoWindow'; + +// /** +// * MapBox2 architecture: +// * Main component: MapBox2.tsx +// * Supporting Components: SidebarAnnos, CollectionStackingView +// * +// * MapBox2 is a node that extends the ViewBoxAnnotatableComponent. Similar to PDFBox and WebBox, it supports interaction between sidebar content and document content. +// * The main body of MapBox2 uses Google Maps API to allow location retrieval, adding map markers, pan and zoom, and open street view. +// * Dash Document architecture is integrated with Maps API: When drag and dropping documents with ExifData (gps Latitude and Longitude information) available, +// * sidebarAddDocument function checks if the document contains lat & lng information, if it does, then the document is added to both the sidebar and the infowindow (a pop up corresponding to a map marker--pin on map). +// * The lat and lng field of the document is filled when importing (spec see ConvertDMSToDD method and processFileUpload method in Documents.ts). +// * A map marker is considered a document that contains a collection with stacking view of documents, it has a lat, lng location, which is passed to Maps API's custom marker (red pin) to be rendered on the google maps +// */ + +// // const _global = (window /* browser */ || global /* node */) as any; + +// const mapContainerStyle = { +// height: '100%', +// }; + +// const defaultCenter = { +// lat: 42.360081, +// lng: -71.058884, +// }; + +// const mapOptions = { +// fullscreenControl: false, +// }; + +// const apiKey = process.env.GOOGLE_MAPS; + +// const script = document.createElement('script'); +// script.defer = true; +// script.async = true; +// script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places,drawing`; +// console.log(script.src); +// document.head.appendChild(script); + +// /** +// * Consider integrating later: allows for drawing, circling, making shapes on map +// */ +// // const drawingManager = new window.google.maps.drawing.DrawingManager({ +// // drawingControl: true, +// // drawingControlOptions: { +// // position: google.maps.ControlPosition.TOP_RIGHT, +// // drawingModes: [ +// // google.maps.drawing.OverlayType.MARKER, +// // // currently we are not supporting the following drawing mode on map, a thought for future development +// // google.maps.drawing.OverlayType.CIRCLE, +// // google.maps.drawing.OverlayType.POLYLINE, +// // ], +// // }, +// // }); + +// // options for searchbox in Google Maps Places Autocomplete API +// const options = { +// fields: ['formatted_address', 'geometry', 'name'], // note: level of details is charged by item per retrieval, not recommended to return all fields +// strictBounds: false, +// types: ['establishment'], // type pf places, subject of change according to user need +// } as google.maps.places.AutocompleteOptions; + +// @observer +// export class MapBox2 extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps & Partial<GoogleMapProps>>() { +// private _dropDisposer?: DragManager.DragDropDisposer; +// private _disposers: { [name: string]: IReactionDisposer } = {}; +// private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef(); +// @observable private _overlayAnnoInfo: Opt<Doc>; +// showInfo = action((anno: Opt<Doc>) => (this._overlayAnnoInfo = anno)); +// public static LayoutString(fieldKey: string) { +// return FieldView.LayoutString(MapBox2, fieldKey); +// } +// public get SidebarKey() { +// return this.fieldKey + '_sidebar'; +// } +// private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void); +// @computed get inlineTextAnnotations() { +// return this.allMapMarkers.filter(a => a.text_inlineAnnotations); +// } + +// @observable private _map: google.maps.Map = null as unknown as google.maps.Map; +// @observable private selectedPlace: Doc | undefined; +// @observable private markerMap: { [id: string]: google.maps.Marker } = {}; +// @observable private center = navigator.geolocation ? navigator.geolocation.getCurrentPosition : defaultCenter; +// @observable private inputRef = React.createRef<HTMLInputElement>(); +// @observable private searchMarkers: google.maps.Marker[] = []; +// @observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options); +// @observable private _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>(); +// @computed get allSidebarDocs() { +// return DocListCast(this.dataDoc[this.SidebarKey]); +// } +// @computed get allMapMarkers() { +// return DocListCast(this.dataDoc[this.annotationKey]); +// } +// @observable private toggleAddMarker = false; + +// @observable _showSidebar = false; +// @computed get SidebarShown() { +// return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false; +// } + +// static _canAnnotate = true; +// static _hadSelection: boolean = false; +// private _sidebarRef = React.createRef<SidebarAnnos>(); +// private _ref: React.RefObject<HTMLDivElement> = React.createRef(); + +// componentDidMount() { +// this.props.setContentView?.(this); +// } + +// @action +// private setSearchBox = (searchBox: any) => { +// this.searchBox = searchBox; +// }; + +// // iterate allMarkers to size, center, and zoom map to contain all markers +// private fitBounds = (map: google.maps.Map) => { +// const curBounds = map.getBounds() ?? new window.google.maps.LatLngBounds(); +// const isFitting = this.allMapMarkers.reduce((fits, place) => fits && curBounds?.contains({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), true as boolean); +// !isFitting && map.fitBounds(this.allMapMarkers.reduce((bounds, place) => bounds.extend({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), new window.google.maps.LatLngBounds())); +// }; + +// /** +// * Custom control for add marker button +// * @param controlDiv +// * @param map +// */ +// private CenterControl = () => { +// const controlDiv = document.createElement('div'); +// controlDiv.className = 'MapBox2-addMarker'; +// // Set CSS for the control border. +// const controlUI = document.createElement('div'); +// controlUI.style.backgroundColor = '#fff'; +// controlUI.style.borderRadius = '3px'; +// controlUI.style.cursor = 'pointer'; +// controlUI.style.marginTop = '10px'; +// controlUI.style.borderRadius = '4px'; +// controlUI.style.marginBottom = '22px'; +// controlUI.style.textAlign = 'center'; +// controlUI.style.position = 'absolute'; +// controlUI.style.width = '32px'; +// controlUI.style.height = '32px'; +// controlUI.title = 'Click to toggle marker mode. In marker mode, click on map to place a marker.'; + +// const plIcon = document.createElement('img'); +// plIcon.src = 'https://cdn4.iconfinder.com/data/icons/wirecons-free-vector-icons/32/add-256.png'; +// plIcon.style.color = 'rgb(25,25,25)'; +// plIcon.style.fontFamily = 'Roboto,Arial,sans-serif'; +// plIcon.style.fontSize = '16px'; +// plIcon.style.lineHeight = '32px'; +// plIcon.style.left = '18'; +// plIcon.style.top = '15'; +// plIcon.style.position = 'absolute'; +// plIcon.width = 14; +// plIcon.height = 14; +// plIcon.innerHTML = 'Add'; +// controlUI.appendChild(plIcon); + +// // Set CSS for the control interior. +// const markerIcon = document.createElement('img'); +// markerIcon.src = 'https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678111-map-marker-1024.png'; +// markerIcon.style.color = 'rgb(25,25,25)'; +// markerIcon.style.fontFamily = 'Roboto,Arial,sans-serif'; +// markerIcon.style.fontSize = '16px'; +// markerIcon.style.lineHeight = '32px'; +// markerIcon.style.left = '-2'; +// markerIcon.style.top = '1'; +// markerIcon.width = 30; +// markerIcon.height = 30; +// markerIcon.style.position = 'absolute'; +// markerIcon.innerHTML = 'Add'; +// controlUI.appendChild(markerIcon); + +// // Setup the click event listeners +// controlUI.addEventListener('click', () => { +// if (this.toggleAddMarker === true) { +// this.toggleAddMarker = false; +// console.log('add marker button status:' + this.toggleAddMarker); +// controlUI.style.backgroundColor = '#fff'; +// markerIcon.style.color = 'rgb(25,25,25)'; +// } else { +// this.toggleAddMarker = true; +// console.log('add marker button status:' + this.toggleAddMarker); +// controlUI.style.backgroundColor = '#4476f7'; +// markerIcon.style.color = 'rgb(255,255,255)'; +// } +// }); +// controlDiv.appendChild(controlUI); +// return controlDiv; +// }; + +// /** +// * Place the marker on google maps & store the empty marker as a MapMarker Document in allMarkers list +// * @param position - the LatLng position where the marker is placed +// * @param map +// */ +// @action +// private placeMarker = (position: google.maps.LatLng, map: google.maps.Map) => { +// const marker = new google.maps.Marker({ +// position: position, +// map: map, +// }); +// map.panTo(position); +// const mapMarker = Docs.Create.PushpinDocument(NumCast(position.lat()), NumCast(position.lng()), false, [], {}); +// this.addDocument(mapMarker, this.annotationKey); +// }; + +// _loadPending = true; +// /** +// * store a reference to google map instance +// * setup the drawing manager on the top right corner of map +// * fit map bounds to contain all markers +// * @param map +// */ +// @action +// private loadHandler = (map: google.maps.Map) => { +// this._map = map; +// this._loadPending = true; +// const centerControlDiv = this.CenterControl(); +// map.controls[google.maps.ControlPosition.TOP_RIGHT].push(centerControlDiv); +// //drawingManager.setMap(map); +// // if (navigator.geolocation) { +// // navigator.geolocation.getCurrentPosition( +// // (position: Position) => { +// // const pos = { +// // lat: position.coords.latitude, +// // lng: position.coords.longitude, +// // }; +// // this._map.setCenter(pos); +// // } +// // ); +// // } else { +// // alert("Your geolocation is not supported by browser.") +// // }; +// map.setZoom(NumCast(this.dataDoc.map_zoom, 2.5)); +// map.setCenter(new google.maps.LatLng(NumCast(this.dataDoc.mapLat), NumCast(this.dataDoc.mapLng))); +// setTimeout(() => { +// if (this._loadPending && this._map.getBounds()) { +// this._loadPending = false; +// this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); +// } +// }, 250); +// // listener to addmarker event +// this._map.addListener('click', (e: MouseEvent) => { +// if (this.toggleAddMarker === true) { +// this.placeMarker((e as any).latLng, map); +// } +// }); +// }; + +// @action +// centered = () => { +// if (this._loadPending && this._map.getBounds()) { +// this._loadPending = false; +// this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); +// } +// this.dataDoc.mapLat = this._map.getCenter()?.lat(); +// this.dataDoc.mapLng = this._map.getCenter()?.lng(); +// }; + +// @action +// zoomChanged = () => { +// if (this._loadPending && this._map.getBounds()) { +// this._loadPending = false; +// this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); +// } +// this.dataDoc.map_zoom = this._map.getZoom(); +// }; + +// /** +// * Load and render all map markers +// * @param marker +// * @param place +// */ +// @action +// private markerLoadHandler = (marker: google.maps.Marker, place: Doc) => { +// place[Id] ? (this.markerMap[place[Id]] = marker) : null; +// }; + +// /** +// * on clicking the map marker, set the selected place to the marker document & set infowindowopen to be true +// * @param e +// * @param place +// */ +// @action +// private markerClickHandler = (e: google.maps.MapMouseEvent, place: Doc) => { +// // set which place was clicked +// this.selectedPlace = place; +// place.infoWindowOpen = true; +// }; + +// /** +// * Called when dragging documents into map sidebar or directly into infowindow; to create a map marker, ref to MapMarkerDocument in Documents.ts +// * @param doc +// * @param sidebarKey +// * @returns +// */ +// sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => { +// console.log('print all sidebar Docs'); +// if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar(); +// const docs = doc instanceof Doc ? [doc] : doc; +// docs.forEach(doc => { +// if (doc.lat !== undefined && doc.lng !== undefined) { +// const existingMarker = this.allMapMarkers.find(marker => marker.lat === doc.lat && marker.lng === doc.lng); +// if (existingMarker) { +// Doc.AddDocToList(existingMarker, 'data', doc); +// } else { +// const marker = Docs.Create.PushpinDocument(NumCast(doc.lat), NumCast(doc.lng), false, [doc], {}); +// this.addDocument(marker, this.annotationKey); +// } +// } +// }); //add to annotation list + +// return this.addDocument(doc, sidebarKey); // add to sidebar list +// }; + +// /** +// * Removing documents from the sidebar +// * @param doc +// * @param sidebarKey +// * @returns +// */ +// sidebarRemoveDocument = (doc: Doc | Doc[], sidebarKey?: string) => { +// if (this.layoutDoc._layout_showSidebar) this.toggleSidebar(); +// const docs = doc instanceof Doc ? [doc] : doc; +// return this.removeDocument(doc, sidebarKey); +// }; + +// /** +// * Toggle sidebar onclick the tiny comment button on the top right corner +// * @param e +// */ +// sidebarBtnDown = (e: React.PointerEvent) => { +// setupMoveUpEvents( +// this, +// e, +// (e, down, delta) => +// runInAction(() => { +// const localDelta = this.props +// .ScreenToLocalTransform() +// .scale(this.props.NativeDimScaling?.() || 1) +// .transformDirection(delta[0], delta[1]); +// const fullWidth = NumCast(this.layoutDoc._width); +// const mapWidth = fullWidth - this.sidebarWidth(); +// if (this.sidebarWidth() + localDelta[0] > 0) { +// this._showSidebar = true; +// this.layoutDoc._width = fullWidth + localDelta[0]; +// this.layoutDoc._layout_sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth + localDelta[0])).toString() + '%'; +// } else { +// this._showSidebar = false; +// this.layoutDoc._width = mapWidth; +// this.layoutDoc._layout_sidebarWidthPercent = '0%'; +// } +// return false; +// }), +// emptyFunction, +// () => UndoManager.RunInBatch(this.toggleSidebar, 'toggle sidebar map') +// ); +// }; + +// sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth(); +// @computed get layout_sidebarWidthPercent() { +// return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); +// } +// @computed get sidebarColor() { +// return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this.props.fieldKey + '_backgroundColor'], '#e4e4e4')); +// } + +// /** +// * function that reads the place inputed from searchbox, then zoom in on the location that's been autocompleted; +// * add a customized temporary marker on the map +// */ +// @action +// private handlePlaceChanged = () => { +// const place = this.searchBox.getPlace(); + +// if (!place.geometry || !place.geometry.location) { +// // user entered the name of a place that wasn't suggested & pressed the enter key, or place details request failed +// window.alert("No details available for input: '" + place.name + "'"); +// return; +// } + +// // zoom in on the location of the search result +// if (place.geometry.viewport) { +// this._map.fitBounds(place.geometry.viewport); +// } else { +// this._map.setCenter(place.geometry.location); +// this._map.setZoom(17); +// } + +// // customize icon => customized icon for the nature of the location selected +// const icon = { +// url: place.icon as string, +// size: new google.maps.Size(71, 71), +// origin: new google.maps.Point(0, 0), +// anchor: new google.maps.Point(17, 34), +// scaledSize: new google.maps.Size(25, 25), +// }; + +// // put temporary cutomized marker on searched location +// this.searchMarkers.forEach(marker => { +// marker.setMap(null); +// }); +// this.searchMarkers = []; +// this.searchMarkers.push( +// new window.google.maps.Marker({ +// map: this._map, +// icon, +// title: place.name, +// position: place.geometry.location, +// }) +// ); +// }; + +// /** +// * Handles toggle of sidebar on click the little comment button +// */ +// @computed get sidebarHandle() { +// return ( +// <div +// className="MapBox2-overlayButton-sidebar" +// key="sidebar" +// title="Toggle Sidebar" +// style={{ +// display: !this.props.isContentActive() ? 'none' : undefined, +// top: StrCast(this.layoutDoc._layout_showTitle) === 'title' ? 20 : 5, +// backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK, +// }} +// onPointerDown={this.sidebarBtnDown}> +// <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" /> +// </div> +// ); +// } + +// // TODO: Adding highlight box layer to Maps +// @action +// toggleSidebar = () => { +// //1.2 * w * ? = .2 * w .2/1.2 +// const prevWidth = this.sidebarWidth(); +// this.layoutDoc._layout_showSidebar = (this.layoutDoc._layout_sidebarWidthPercent = StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%') === '0%' ? `${(100 * 0.2) / 1.2}%` : '0%') !== '0%'; +// this.layoutDoc._width = this.layoutDoc._layout_showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth); +// }; + +// sidebarDown = (e: React.PointerEvent) => { +// setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), true); +// }; +// sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { +// const bounds = this._ref.current!.getBoundingClientRect(); +// this.layoutDoc._layout_sidebarWidthPercent = '' + 100 * Math.max(0, 1 - (e.clientX - bounds.left) / bounds.width) + '%'; +// this.layoutDoc._layout_showSidebar = this.layoutDoc._layout_sidebarWidthPercent !== '0%'; +// e.preventDefault(); +// return false; +// }; + +// setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => (this._setPreviewCursor = func); + +// addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => { +// return this.addDocument(doc, annotationKey); +// }; + +// pointerEvents = () => { +// return this.props.isContentActive() === false ? 'none' : this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && !MarqueeOptionsMenu.Instance.isShown() ? 'all' : SnappingManager.GetIsDragging() ? undefined : 'none'; +// }; +// @computed get annotationLayer() { +// return ( +// <div className="MapBox2-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}> +// {this.inlineTextAnnotations +// .sort((a, b) => NumCast(a.y) - NumCast(b.y)) +// .map(anno => ( +// <Annotation key={`${anno[Id]}-annotation`} {...this.props} fieldKey={this.annotationKey} pointerEvents={this.pointerEvents} showInfo={this.showInfo} dataDoc={this.dataDoc} anno={anno} /> +// ))} +// </div> +// ); +// } + +// getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => AnchorMenu.Instance?.GetAnchor(this._savedAnnotations, addAsAnnotation) ?? this.Document; + +// /** +// * render contents in allMapMarkers (e.g. images with exifData) into google maps as map marker +// * @returns +// */ +// private renderMarkers = () => { +// return this.allMapMarkers.map(place => ( +// <Marker key={place[Id]} position={{ lat: NumCast(place.lat), lng: NumCast(place.lng) }} onLoad={marker => this.markerLoadHandler(marker, place)} onClick={(e: google.maps.MapMouseEvent) => this.markerClickHandler(e, place)} /> +// )); +// }; + +// // TODO: auto center on select a document in the sidebar +// private handleMapCenter = (map: google.maps.Map) => { +// // console.log("print the selected views in selectionManager:") +// // if (SelectionManager.Views().lastElement()) { +// // console.log(SelectionManager.Views().lastElement()); +// // } +// }; + +// panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth(); +// panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); +// scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); +// transparentFilter = () => [...this.props.childFilters(), Utils.TransparentBackgroundFilter]; +// opaqueFilter = () => [...this.props.childFilters(), Utils.OpaqueBackgroundFilter]; +// infoWidth = () => this.props.PanelWidth() / 5; +// infoHeight = () => this.props.PanelHeight() / 5; +// anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; +// savedAnnotations = () => this._savedAnnotations; + +// get MicrosoftMaps() { +// return (window as any).Microsoft.Maps; +// } +// render() { +// const renderAnnotations = (childFilters?: () => string[]) => null; +// return ( +// <div className="MapBox2" ref={this._ref}> +// <div +// className="MapBox2-wrapper" +// onWheel={e => e.stopPropagation()} +// onPointerDown={async e => { +// e.button === 0 && !e.ctrlKey && e.stopPropagation(); +// }} +// style={{ width: `calc(100% - ${this.layout_sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}> +// <div style={{ mixBlendMode: 'multiply' }}>{renderAnnotations(this.transparentFilter)}</div> +// {renderAnnotations(this.opaqueFilter)} +// {SnappingManager.GetIsDragging() ? null : renderAnnotations()} +// {this.annotationLayer} + +// <div> +// <GoogleMap mapContainerStyle={mapContainerStyle} onZoomChanged={this.zoomChanged} onCenterChanged={this.centered} onLoad={this.loadHandler} options={mapOptions}> +// <Autocomplete onLoad={this.setSearchBox} onPlaceChanged={this.handlePlaceChanged}> +// <input className="MapBox2-input" ref={this.inputRef} type="text" onKeyDown={e => e.stopPropagation()} placeholder="Enter location" /> +// </Autocomplete> + +// {this.renderMarkers()} +// {this.allMapMarkers +// .filter(marker => marker.infoWindowOpen) +// .map(marker => ( +// <MapBoxInfoWindow +// key={marker[Id]} +// {...this.props} +// setContentView={emptyFunction} +// place={marker} +// markerMap={this.markerMap} +// PanelWidth={this.infoWidth} +// PanelHeight={this.infoHeight} +// moveDocument={this.moveDocument} +// isAnyChildContentActive={this.isAnyChildContentActive} +// whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} +// /> +// ))} +// {/* {this.handleMapCenter(this._map)} */} +// </GoogleMap> +// </div> +// </div> +// {/* </LoadScript > */} +// <div className="MapBox2-sidebar" style={{ width: `${this.layout_sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}> +// <SidebarAnnos +// ref={this._sidebarRef} +// {...this.props} +// fieldKey={this.fieldKey} +// Document={this.Document} +// layoutDoc={this.layoutDoc} +// dataDoc={this.dataDoc} +// usePanelWidth={true} +// showSidebar={this.SidebarShown} +// nativeWidth={NumCast(this.layoutDoc._nativeWidth)} +// whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} +// PanelWidth={this.sidebarWidth} +// sidebarAddDocument={this.sidebarAddDocument} +// moveDocument={this.moveDocument} +// removeDocument={this.sidebarRemoveDocument} +// /> +// </div> +// {this.sidebarHandle} +// </div> +// ); +// } +// } diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx index 415a9d776..a9c6ba22c 100644 --- a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx +++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx @@ -1,95 +1,95 @@ -import { InfoWindow } from '@react-google-maps/api'; -import { action } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import { Doc } from '../../../../fields/Doc'; -import { Id } from '../../../../fields/FieldSymbols'; -import { emptyFunction, returnAll, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents } from '../../../../Utils'; -import { Docs } from '../../../documents/Documents'; -import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; -import { CollectionNoteTakingView } from '../../collections/CollectionNoteTakingView'; -import { CollectionStackingView } from '../../collections/CollectionStackingView'; -import { ViewBoxAnnotatableProps } from '../../DocComponent'; -import { FieldViewProps } from '../FieldView'; -import { FormattedTextBox } from '../formattedText/FormattedTextBox'; -import './MapBox.scss'; +// import { InfoWindow } from '@react-google-maps/api'; +// import { action } from 'mobx'; +// import { observer } from 'mobx-react'; +// import * as React from 'react'; +// import { Doc } from '../../../../fields/Doc'; +// import { Id } from '../../../../fields/FieldSymbols'; +// import { emptyFunction, returnAll, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents } from '../../../../Utils'; +// import { Docs } from '../../../documents/Documents'; +// import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; +// import { CollectionNoteTakingView } from '../../collections/CollectionNoteTakingView'; +// import { CollectionStackingView } from '../../collections/CollectionStackingView'; +// import { ViewBoxAnnotatableProps } from '../../DocComponent'; +// import { FieldViewProps } from '../FieldView'; +// import { FormattedTextBox } from '../formattedText/FormattedTextBox'; +// import './MapBox.scss'; -interface MapBoxInfoWindowProps { - place: Doc; - renderDepth: number; - markerMap: { [id: string]: google.maps.Marker }; - isAnyChildContentActive: () => boolean; -} -@observer -export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & ViewBoxAnnotatableProps & FieldViewProps> { - @action - private handleInfoWindowClose = () => { - if (this.props.place.infoWindowOpen) { - this.props.place.infoWindowOpen = false; - } - this.props.place.infoWindowOpen = false; - }; +// interface MapBoxInfoWindowProps { +// place: Doc; +// renderDepth: number; +// markerMap: { [id: string]: google.maps.Marker }; +// isAnyChildContentActive: () => boolean; +// } +// @observer +// export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & ViewBoxAnnotatableProps & FieldViewProps> { +// @action +// private handleInfoWindowClose = () => { +// if (this.props.place.infoWindowOpen) { +// this.props.place.infoWindowOpen = false; +// } +// this.props.place.infoWindowOpen = false; +// }; - addNoteClick = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => { - const newDoc = Docs.Create.TextDocument('Note', { _layout_autoHeight: true }); - FormattedTextBox.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed - Doc.AddDocToList(this.props.place, 'data', newDoc); - this._stack?.scrollToBottom(); - e.stopPropagation(); - e.preventDefault(); - }); - }; +// addNoteClick = (e: React.PointerEvent) => { +// setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => { +// const newDoc = Docs.Create.TextDocument('Note', { _layout_autoHeight: true }); +// FormattedTextBox.SetSelectOnLoad(newDoc); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed +// Doc.AddDocToList(this.props.place, 'data', newDoc); +// this._stack?.scrollToBottom(); +// e.stopPropagation(); +// e.preventDefault(); +// }); +// }; - _stack: CollectionStackingView | CollectionNoteTakingView | null | undefined; - childLayoutFitWidth = (doc: Doc) => doc.type === DocumentType.RTF; - addDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.AddDocToList(this.props.place, 'data', d), true as boolean); - removeDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.RemoveDocFromList(this.props.place, 'data', d), true as boolean); - render() { - return ( - <InfoWindow - // anchor={this.props.markerMap[this.props.place[Id]]} - onCloseClick={this.handleInfoWindowClose}> - <div className="mapbox-infowindow"> - <div style={{ width: this.props.PanelWidth(), height: this.props.PanelHeight() }}> - <CollectionStackingView - ref={r => (this._stack = r)} - {...this.props} - setContentView={emptyFunction} - Document={this.props.place} - TemplateDataDocument={undefined} - fieldKey="data" - NativeWidth={returnZero} - NativeHeight={returnZero} - childFilters={returnEmptyFilter} - setHeight={emptyFunction} - isAnnotationOverlay={false} - select={emptyFunction} - NativeDimScaling={returnOne} - isContentActive={returnTrue} - chromeHidden={true} - childHideResizeHandles={true} - childHideDecorationTitle={true} - childLayoutFitWidth={this.childLayoutFitWidth} - // childDocumentsActive={returnFalse} - removeDocument={this.removeDoc} - addDocument={this.addDoc} - renderDepth={this.props.renderDepth + 1} - type_collection={CollectionViewType.Stacking} - pointerEvents={returnAll} - /> - </div> - <hr /> - <div - onPointerDown={this.addNoteClick} - onClick={e => { - e.stopPropagation(); - e.preventDefault(); - }}> - Add Note - </div> - </div> - </InfoWindow> - ); - } -} +// _stack: CollectionStackingView | CollectionNoteTakingView | null | undefined; +// childLayoutFitWidth = (doc: Doc) => doc.type === DocumentType.RTF; +// addDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.AddDocToList(this.props.place, 'data', d), true as boolean); +// removeDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.RemoveDocFromList(this.props.place, 'data', d), true as boolean); +// render() { +// return ( +// <InfoWindow +// // anchor={this.props.markerMap[this.props.place[Id]]} +// onCloseClick={this.handleInfoWindowClose}> +// <div className="mapbox-infowindow"> +// <div style={{ width: this.props.PanelWidth(), height: this.props.PanelHeight() }}> +// <CollectionStackingView +// ref={r => (this._stack = r)} +// {...this.props} +// setContentView={emptyFunction} +// Document={this.props.place} +// TemplateDataDocument={undefined} +// fieldKey="data" +// NativeWidth={returnZero} +// NativeHeight={returnZero} +// childFilters={returnEmptyFilter} +// setHeight={emptyFunction} +// isAnnotationOverlay={false} +// select={emptyFunction} +// NativeDimScaling={returnOne} +// isContentActive={returnTrue} +// chromeHidden={true} +// childHideResizeHandles={true} +// childHideDecorationTitle={true} +// childLayoutFitWidth={this.childLayoutFitWidth} +// // childDocumentsActive={returnFalse} +// removeDocument={this.removeDoc} +// addDocument={this.addDoc} +// renderDepth={this.props.renderDepth + 1} +// type_collection={CollectionViewType.Stacking} +// pointerEvents={returnAll} +// /> +// </div> +// <hr /> +// <div +// onPointerDown={this.addNoteClick} +// onClick={e => { +// e.stopPropagation(); +// e.preventDefault(); +// }}> +// Add Note +// </div> +// </div> +// </InfoWindow> +// ); +// } +// } diff --git a/src/client/views/nodes/MapBox/MapPushpinBox.tsx b/src/client/views/nodes/MapBox/MapPushpinBox.tsx index 56f0a49b8..590f8735c 100644 --- a/src/client/views/nodes/MapBox/MapPushpinBox.tsx +++ b/src/client/views/nodes/MapBox/MapPushpinBox.tsx @@ -2,7 +2,7 @@ import { observer } from 'mobx-react'; // import { SettingsManager } from '../../../util/SettingsManager'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { FieldView, FieldViewProps } from '../FieldView'; -import React = require('react'); +import * as React from 'react'; import { computed } from 'mobx'; import { MapBox } from './MapBox'; diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 9787de0ab..8de8498d7 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -31,7 +31,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { ImageBox } from './ImageBox'; import './PDFBox.scss'; import { PinProps, PresBox } from './trails'; -import React = require('react'); +import * as React from 'react'; @observer export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps>() { diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx index cd1ff17dd..c498a58d6 100644 --- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx +++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx @@ -15,11 +15,11 @@ import { ViewBoxAnnotatableComponent } from '../../DocComponent'; import { FieldView, FieldViewProps } from './../FieldView'; import './PhysicsSimulationBox.scss'; import InputField from './PhysicsSimulationInputField'; -import * as questions from './PhysicsSimulationQuestions.json'; -import * as tutorials from './PhysicsSimulationTutorial.json'; +import questions from './PhysicsSimulationQuestions.json'; +import tutorials from './PhysicsSimulationTutorial.json'; import Wall from './PhysicsSimulationWall'; import Weight from './PhysicsSimulationWeight'; -import React = require('react'); +import * as React from 'react'; interface IWallProps { length: number; diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationInputField.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationInputField.tsx index d595a499e..c704863f5 100644 --- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationInputField.tsx +++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationInputField.tsx @@ -1,6 +1,6 @@ import { TextField, InputAdornment } from '@mui/material'; import { Doc } from '../../../../fields/Doc'; -import React = require('react'); +import * as React from 'react'; import TaskAltIcon from '@mui/icons-material/TaskAlt'; import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; import { isNumber } from 'lodash'; diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWall.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWall.tsx index 8cc1d0fbf..696352296 100644 --- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWall.tsx +++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWall.tsx @@ -1,34 +1,33 @@ -import React = require('react'); +import * as React from 'react'; export interface Force { - magnitude: number; - directionInDegrees: number; + magnitude: number; + directionInDegrees: number; } export interface IWallProps { - length: number; - xPos: number; - yPos: number; - angleInDegrees: number; + length: number; + xPos: number; + yPos: number; + angleInDegrees: number; } export default class Wall extends React.Component<IWallProps> { + constructor(props: any) { + super(props); + } - constructor(props: any) { - super(props) - } + wallStyle = { + width: this.props.angleInDegrees == 0 ? this.props.length + '%' : '5px', + height: this.props.angleInDegrees == 0 ? '5px' : this.props.length + '%', + position: 'absolute' as 'absolute', + left: this.props.xPos + '%', + top: this.props.yPos + '%', + backgroundColor: '#6c7b8b', + margin: 0, + padding: 0, + }; - wallStyle = { - width: this.props.angleInDegrees == 0 ? this.props.length + "%" : "5px", - height: this.props.angleInDegrees == 0 ? "5px" : this.props.length + "%", - position: "absolute" as "absolute", - left: this.props.xPos + "%", - top: this.props.yPos + "%", - backgroundColor: "#6c7b8b", - margin: 0, - padding: 0, - }; - - render () { - return (<div style={this.wallStyle}></div>); - } -}; + render() { + return <div style={this.wallStyle}></div>; + } +} diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx index 2165c8ba9..99333991f 100644 --- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx +++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx @@ -1,7 +1,7 @@ import { computed, IReactionDisposer, reaction } from 'mobx'; import { observer } from 'mobx-react'; import './PhysicsSimulationBox.scss'; -import React = require('react'); +import * as React from 'react'; interface IWallProps { length: number; diff --git a/src/client/views/nodes/RadialMenu.tsx b/src/client/views/nodes/RadialMenu.tsx index 7f0956e51..191877cb5 100644 --- a/src/client/views/nodes/RadialMenu.tsx +++ b/src/client/views/nodes/RadialMenu.tsx @@ -1,8 +1,8 @@ -import React = require("react"); -import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; -import { observer } from "mobx-react"; -import "./RadialMenu.scss"; -import { RadialMenuItem, RadialMenuProps } from "./RadialMenuItem"; +import * as React from 'react'; +import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; +import { observer } from 'mobx-react'; +import './RadialMenu.scss'; +import { RadialMenuItem, RadialMenuProps } from './RadialMenuItem'; @observer export class RadialMenu extends React.Component { @@ -23,11 +23,10 @@ export class RadialMenu extends React.Component { public used: boolean = false; - catchTouch = (te: React.TouchEvent) => { te.stopPropagation(); te.preventDefault(); - } + }; @action onPointerDown = (e: PointerEvent) => { @@ -35,8 +34,8 @@ export class RadialMenu extends React.Component { this._mouseX = e.clientX; this._mouseY = e.clientY; this.used = false; - document.addEventListener("pointermove", this.onPointerMove); - } + document.addEventListener('pointermove', this.onPointerMove); + }; @observable private _closest: number = -1; @@ -60,11 +59,10 @@ export class RadialMenu extends React.Component { } } this._closest = closest; - } - else { + } else { this._closest = -1; } - } + }; @action onPointerUp = (e: PointerEvent) => { this.used = true; @@ -75,43 +73,41 @@ export class RadialMenu extends React.Component { this._shouldDisplay = false; } this._shouldDisplay && (this._display = true); - document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener('pointermove', this.onPointerMove); if (this._closest !== -1 && this._items?.length > this._closest) { this._items[this._closest].event(); } - } + }; componentWillUnmount() { - document.removeEventListener("pointerdown", this.onPointerDown); + document.removeEventListener('pointerdown', this.onPointerDown); - document.removeEventListener("pointerup", this.onPointerUp); + document.removeEventListener('pointerup', this.onPointerUp); this._reactionDisposer && this._reactionDisposer(); } @action componentDidMount = () => { - document.addEventListener("pointerdown", this.onPointerDown); - document.addEventListener("pointerup", this.onPointerUp); + document.addEventListener('pointerdown', this.onPointerDown); + document.addEventListener('pointerup', this.onPointerUp); this.previewcircle(); this._reactionDisposer = reaction( () => this._shouldDisplay, - () => this._shouldDisplay && !this._mouseDown && runInAction(() => this._display = true) + () => this._shouldDisplay && !this._mouseDown && runInAction(() => (this._display = true)) ); - } + }; componentDidUpdate = () => { this.previewcircle(); - } + }; @observable private _pageX: number = 0; @observable private _pageY: number = 0; @observable _display: boolean = false; @observable private _yRelativeToTop: boolean = true; - @observable private _width: number = 0; @observable private _height: number = 0; - getItems() { return this._items; } @@ -133,7 +129,7 @@ export class RadialMenu extends React.Component { this._mouseX = x; this._mouseY = y; this._shouldDisplay = true; - } + }; // @computed // get pageX() { // const x = this._pageX; @@ -168,7 +164,7 @@ export class RadialMenu extends React.Component { this.clearItems(); this._display = false; this._shouldDisplay = false; - } + }; @action openMenu = (x: number, y: number) => { @@ -176,56 +172,52 @@ export class RadialMenu extends React.Component { this._pageY = y; this._shouldDisplay; this._display = true; - } + }; @action clearItems() { this._items = []; } - previewcircle() { - if (document.getElementById("newCanvas") !== null) { - const c: any = document.getElementById("newCanvas"); + if (document.getElementById('newCanvas') !== null) { + const c: any = document.getElementById('newCanvas'); if (c.getContext) { - const ctx = c.getContext("2d"); + const ctx = c.getContext('2d'); ctx.beginPath(); ctx.arc(150, 150, 50, 0, 2 * Math.PI); - ctx.fillStyle = "white"; + ctx.fillStyle = 'white'; ctx.fill(); - ctx.font = "12px Arial"; - ctx.fillStyle = "black"; - ctx.textAlign = "center"; - let description = ""; + ctx.font = '12px Arial'; + ctx.fillStyle = 'black'; + ctx.textAlign = 'center'; + let description = ''; if (this._closest !== -1) { description = this._items[this._closest].description; } if (description.length > 15) { description = description.slice(0, 12); - description += "..."; + description += '...'; } ctx.fillText(description, 150, 150, 90); } } } - render() { if (!this._display) { return null; } - const style = this._yRelativeToTop ? { left: this._pageX - 130, top: this._pageY - 130 } : - { left: this._pageX - 130, top: this._pageY - 130 }; + const style = this._yRelativeToTop ? { left: this._pageX - 130, top: this._pageY - 130 } : { left: this._pageX - 130, top: this._pageY - 130 }; return ( - <div className="radialMenu-cont" onTouchStart={this.catchTouch} style={style}> - <canvas id="newCanvas" style={{ position: "absolute" }} height="300" width="300"> Your browser does not support the HTML5 canvas tag.</canvas> + <canvas id="newCanvas" style={{ position: 'absolute' }} height="300" width="300"> + {' '} + Your browser does not support the HTML5 canvas tag. + </canvas> {this.menuItems} </div> - ); } - - -}
\ No newline at end of file +} diff --git a/src/client/views/nodes/RadialMenuItem.tsx b/src/client/views/nodes/RadialMenuItem.tsx index 8876b4879..c931202f1 100644 --- a/src/client/views/nodes/RadialMenuItem.tsx +++ b/src/client/views/nodes/RadialMenuItem.tsx @@ -1,8 +1,8 @@ -import React = require("react"); +import * as React from 'react'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { observer } from "mobx-react"; -import { UndoManager } from "../../util/UndoManager"; +import { observer } from 'mobx-react'; +import { UndoManager } from '../../util/UndoManager'; export interface RadialMenuProps { description: string; @@ -15,17 +15,15 @@ export interface RadialMenuProps { selected: number; } - @observer export class RadialMenuItem extends React.Component<RadialMenuProps> { - componentDidMount = () => { this.setcircle(); - } + }; componentDidUpdate = () => { this.setcircle(); - } + }; handleEvent = async (e: React.PointerEvent) => { this.props.closeMenu && this.props.closeMenu(); @@ -35,38 +33,36 @@ export class RadialMenuItem extends React.Component<RadialMenuProps> { } await this.props.event({ x: e.clientX, y: e.clientY }); batch && batch.end(); - } - + }; setcircle() { let circlemin = 0; let circlemax = 1; - this.props.min ? circlemin = this.props.min : null; - this.props.max ? circlemax = this.props.max : null; - if (document.getElementById("myCanvas") !== null) { - const c: any = document.getElementById("myCanvas"); - let color = "white"; + this.props.min ? (circlemin = this.props.min) : null; + this.props.max ? (circlemax = this.props.max) : null; + if (document.getElementById('myCanvas') !== null) { + const c: any = document.getElementById('myCanvas'); + let color = 'white'; switch (circlemin % 3) { case 1: - color = "#c2c2c5"; + color = '#c2c2c5'; break; case 0: - color = "#f1efeb"; + color = '#f1efeb'; break; case 2: - color = "lightgray"; + color = 'lightgray'; break; } if (circlemax % 3 === 1 && circlemin === circlemax - 1) { - color = "#c2c2c5"; + color = '#c2c2c5'; } if (this.props.selected === this.props.min) { - color = "#808080"; - + color = '#808080'; } if (c.getContext) { - const ctx = c.getContext("2d"); + const ctx = c.getContext('2d'); ctx.beginPath(); ctx.arc(150, 150, 150, (circlemin / circlemax) * 2 * Math.PI, ((circlemin + 1) / circlemax) * 2 * Math.PI); ctx.arc(150, 150, 50, ((circlemin + 1) / circlemax) * 2 * Math.PI, (circlemin / circlemax) * 2 * Math.PI, true); @@ -79,35 +75,36 @@ export class RadialMenuItem extends React.Component<RadialMenuProps> { calculatorx() { let circlemin = 0; let circlemax = 1; - this.props.min ? circlemin = this.props.min : null; - this.props.max ? circlemax = this.props.max : null; - const avg = ((circlemin / circlemax) + ((circlemin + 1) / circlemax)) / 2; + this.props.min ? (circlemin = this.props.min) : null; + this.props.max ? (circlemax = this.props.max) : null; + const avg = (circlemin / circlemax + (circlemin + 1) / circlemax) / 2; const degrees = 360 * avg; - const x = 100 * Math.cos(degrees * Math.PI / 180); - const y = -125 * Math.sin(degrees * Math.PI / 180); + const x = 100 * Math.cos((degrees * Math.PI) / 180); + const y = -125 * Math.sin((degrees * Math.PI) / 180); return x; } calculatory() { - let circlemin = 0; let circlemax = 1; - this.props.min ? circlemin = this.props.min : null; - this.props.max ? circlemax = this.props.max : null; - const avg = ((circlemin / circlemax) + ((circlemin + 1) / circlemax)) / 2; + this.props.min ? (circlemin = this.props.min) : null; + this.props.max ? (circlemax = this.props.max) : null; + const avg = (circlemin / circlemax + (circlemin + 1) / circlemax) / 2; const degrees = 360 * avg; - const x = 125 * Math.cos(degrees * Math.PI / 180); - const y = -100 * Math.sin(degrees * Math.PI / 180); + const x = 125 * Math.cos((degrees * Math.PI) / 180); + const y = -100 * Math.sin((degrees * Math.PI) / 180); return y; } - render() { return ( - <div className={"radialMenu-item" + (this.props.selected ? " radialMenu-itemSelected" : "")} onPointerUp={this.handleEvent}> - <canvas id="myCanvas" height="300" width="300"> Your browser does not support the HTML5 canvas tag.</canvas> - <FontAwesomeIcon icon={this.props.icon} size="3x" style={{ position: "absolute", left: this.calculatorx() + 150 - 19, top: this.calculatory() + 150 - 19 }} /> + <div className={'radialMenu-item' + (this.props.selected ? ' radialMenu-itemSelected' : '')} onPointerUp={this.handleEvent}> + <canvas id="myCanvas" height="300" width="300"> + {' '} + Your browser does not support the HTML5 canvas tag. + </canvas> + <FontAwesomeIcon icon={this.props.icon} size="3x" style={{ position: 'absolute', left: this.calculatorx() + 150 - 19, top: this.calculatory() + 150 - 19 }} /> </div> ); } -}
\ No newline at end of file +} diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index c2e204eab..7c21b1893 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; // import { Canvas } from '@react-three/fiber'; import { computed, observable, runInAction } from 'mobx'; diff --git a/src/client/views/nodes/ScriptingBox.scss b/src/client/views/nodes/ScriptingBox.scss index 8d76f2b1d..9789da55a 100644 --- a/src/client/views/nodes/ScriptingBox.scss +++ b/src/client/views/nodes/ScriptingBox.scss @@ -32,7 +32,7 @@ .scriptingBox-wrapper { width: 100%; height: 100%; - max-height: calc(100%-30px); + max-height: calc(100% - 30px); display: flex; flex-direction: row; overflow: auto; @@ -42,7 +42,8 @@ overflow: hidden; } - .scriptingBox-textArea, .scriptingBox-textArea-inputs { + .scriptingBox-textArea, + .scriptingBox-textArea-inputs { flex: 70; height: 100%; max-width: 95%; @@ -110,7 +111,7 @@ cursor: pointer; } - .rta__entity>* { + .rta__entity > * { padding-left: 4px; padding-right: 4px; } @@ -125,7 +126,7 @@ .scriptingBox-textArea-inputs { max-width: 100%; height: 40%; - width: 100%; + width: 100%; resize: none; } .scriptingBox-textArea-script { @@ -194,8 +195,8 @@ .scriptingBox-errorMessage { overflow: auto; - background: "red"; - background-color: "red"; + background: 'red'; + background-color: 'red'; height: 45px; } @@ -221,4 +222,4 @@ width: 25%; } } -}
\ No newline at end of file +} diff --git a/src/client/views/nodes/TaskCompletedBox.tsx b/src/client/views/nodes/TaskCompletedBox.tsx index 2a3dd8d2d..9aab8c5a9 100644 --- a/src/client/views/nodes/TaskCompletedBox.tsx +++ b/src/client/views/nodes/TaskCompletedBox.tsx @@ -1,13 +1,11 @@ -import React = require("react"); -import { observer } from "mobx-react"; -import "./TaskCompletedBox.scss"; -import { observable, action } from "mobx"; -import { Fade } from "@material-ui/core"; - +import * as React from 'react'; +import { observer } from 'mobx-react'; +import './TaskCompletedBox.scss'; +import { observable, action } from 'mobx'; +import { Fade } from '@mui/material'; @observer export class TaskCompletionBox extends React.Component<{}> { - @observable public static taskCompleted: boolean = false; @observable public static popupX: number = 500; @observable public static popupY: number = 150; @@ -16,15 +14,20 @@ export class TaskCompletionBox extends React.Component<{}> { @action public static toggleTaskCompleted = () => { TaskCompletionBox.taskCompleted = !TaskCompletionBox.taskCompleted; - } + }; render() { - return <Fade in={TaskCompletionBox.taskCompleted}> - <div className="taskCompletedBox-fade" - style={{ - left: TaskCompletionBox.popupX ? TaskCompletionBox.popupX : 500, - top: TaskCompletionBox.popupY ? TaskCompletionBox.popupY : 150, - }}>{TaskCompletionBox.textDisplayed}</div> - </Fade>; + return ( + <Fade in={TaskCompletionBox.taskCompleted}> + <div + className="taskCompletedBox-fade" + style={{ + left: TaskCompletionBox.popupX ? TaskCompletionBox.popupX : 500, + top: TaskCompletionBox.popupY ? TaskCompletionBox.popupY : 150, + }}> + {TaskCompletionBox.textDisplayed} + </div> + </Fade> + ); } -}
\ No newline at end of file +} diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 0f6c6724a..04780155d 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, untracked } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index b3afe6ba0..d02e5f3e8 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -36,7 +36,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { LinkDocPreview } from './LinkDocPreview'; import { PinProps, PresBox } from './trails'; import './WebBox.scss'; -import React = require('react'); +import * as React from 'react'; const { CreateImage } = require('./WebBoxRenderer'); const _global = (window /* browser */ || global) /* node */ as any; const htmlToText = require('html-to-text'); diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx index aa269d8d6..d6b053c8e 100644 --- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx +++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx @@ -2,7 +2,7 @@ import { TextSelection } from 'prosemirror-state'; import * as ReactDOM from 'react-dom/client'; import { Doc } from '../../../../fields/Doc'; import { DocServer } from '../../../DocServer'; -import React = require('react'); +import * as React from 'react'; // creates an inline comment in a note when '>>' is typed. // the comment sits on the right side of the note and vertically aligns with its anchor in the text. diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index 95743a036..4384c8958 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -11,7 +11,7 @@ import { Docs, DocUtils } from '../../../documents/Documents'; import { Transform } from '../../../util/Transform'; import { DocFocusOptions, DocumentView } from '../DocumentView'; import { FormattedTextBox } from './FormattedTextBox'; -import React = require('react'); +import * as React from 'react'; export class DashDocView { dom: HTMLSpanElement; // container for label and value diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index a914084f9..a395296d0 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, computed, IReactionDisposer, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as ReactDOM from 'react-dom/client'; @@ -16,7 +16,7 @@ import { SchemaTableCell } from '../../collections/collectionSchema/SchemaTableC import { OpenWhere } from '../DocumentView'; import './DashFieldView.scss'; import { FormattedTextBox } from './FormattedTextBox'; -import React = require('react'); +import * as React from 'react'; import { Transform } from '../../../util/Transform'; export class DashFieldView { diff --git a/src/client/views/nodes/formattedText/EquationEditor.tsx b/src/client/views/nodes/formattedText/EquationEditor.tsx new file mode 100644 index 000000000..bde6c1315 --- /dev/null +++ b/src/client/views/nodes/formattedText/EquationEditor.tsx @@ -0,0 +1,87 @@ +import React, { Component, createRef } from 'react'; + +// Import JQuery, required for the functioning of the equation editor +import $ from 'jquery'; + +// Import the styles from the Mathquill editor +import 'mathquill/build/mathquill.css'; + +// eslint-disable-next-line @typescript-eslint/ban-ts-ignore +// @ts-ignore +window.jQuery = $; + +// eslint-disable-next-line @typescript-eslint/ban-ts-ignore +// @ts-ignore +require('mathquill/build/mathquill'); + +type EquationEditorProps = { + onChange(latex: string): void; + value: string; + spaceBehavesLikeTab?: boolean; + autoCommands: string; + autoOperatorNames: string; + onEnter?(): void; +}; + +/** + * @typedef {EquationEditorProps} props + * @prop {Function} onChange Triggered when content of the equation editor changes + * @prop {string} value Content of the equation handler + * @prop {boolean}[false] spaceBehavesLikeTab Whether spacebar should simulate tab behavior + * @prop {string} autoCommands List of commands for which you only have to type the name of the + * command with a \ in front of it. Examples: pi theta rho sum + * @prop {string} autoOperatorNames List of operators for which you only have to type the name of the + * operator with a \ in front of it. Examples: sin cos tan + * @prop {Function} onEnter Triggered when enter is pressed in the equation editor + * @extends {Component<EquationEditorProps>} + */ +class EquationEditor extends Component<EquationEditorProps> { + element: any; + mathField: any; + ignoreEditEvents: number; + + // Element needs to be in the class format and thus requires a constructor. The steps that are run + // in the constructor is to make sure that React can succesfully communicate with the equation + // editor. + constructor(props: EquationEditorProps) { + super(props); + + this.element = createRef(); + this.mathField = null; + + // MathJax apparently fire 2 edit events on startup. + this.ignoreEditEvents = 2; + } + + componentDidMount() { + const { onChange, value, spaceBehavesLikeTab, autoCommands, autoOperatorNames, onEnter } = this.props; + + const config = { + handlers: { + edit: () => { + if (this.ignoreEditEvents > 0) { + this.ignoreEditEvents -= 1; + return; + } + if (this.mathField.latex() !== value) { + onChange(this.mathField.latex()); + } + }, + enter: onEnter, + }, + spaceBehavesLikeTab, + autoCommands, + autoOperatorNames, + }; + + // @ts-ignore + this.mathField = (MathQuill as any).MathField(this.element.current, config); + this.mathField.latex(value || ''); + } + + render() { + return <span ref={this.element} style={{ border: '0px', boxShadow: 'None' }} />; + } +} + +export default EquationEditor; diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx index 5e62d94c2..5ee5d25c3 100644 --- a/src/client/views/nodes/formattedText/EquationView.tsx +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -1,4 +1,4 @@ -import EquationEditor from 'equation-editor-react'; +import EquationEditor from './EquationEditor'; import { IReactionDisposer, trace } from 'mobx'; import { observer } from 'mobx-react'; import { TextSelection } from 'prosemirror-state'; @@ -7,7 +7,7 @@ import { Doc } from '../../../../fields/Doc'; import { StrCast } from '../../../../fields/Types'; import './DashFieldView.scss'; import { FormattedTextBox } from './FormattedTextBox'; -import React = require('react'); +import * as React from 'react'; export class EquationView { dom: HTMLDivElement; // container for label and value @@ -101,7 +101,7 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal> <EquationEditor ref={this._ref} value={StrCast(this._textBoxDoc[this._fieldKey], 'y=')} - onChange={str => (this._textBoxDoc[this._fieldKey] = str)} + onChange={(str: any) => (this._textBoxDoc[this._fieldKey] = str)} autoCommands="pi theta sqrt sum prod alpha beta gamma rho" autoOperatorNames="sin cos tan" spaceBehavesLikeTab={true} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 42e8ace6e..4f8e8769a 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1,7 +1,6 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; -import { setCORS } from 'google-translate-api-browser'; +import { Tooltip } from '@mui/material'; import { isEqual } from 'lodash'; import { action, computed, IReactionDisposer, observable, ObservableSet, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; @@ -71,10 +70,8 @@ import { RichTextMenu, RichTextMenuPlugin } from './RichTextMenu'; import { RichTextRules } from './RichTextRules'; import { schema } from './schema_rts'; import { SummaryView } from './SummaryView'; -import applyDevTools = require('prosemirror-dev-tools'); -import React = require('react'); -// setting up cors-anywhere server address -const translate = setCORS('http://cors-anywhere.herokuapp.com/'); +// import * as applyDevTools from 'prosemirror-dev-tools'; +import * as React from 'react'; export const GoogleRef = 'googleDocId'; type PullHandler = (exportState: Opt<GoogleApiClientUtils.Docs.ImportResult>, dataDoc: Doc) => void; @@ -797,7 +794,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps ?.trim() .split(' ') .filter(h => h); - const anchorDoc = Array.from(hrefs).lastElement().replace(Doc.localServerPath(), '').split('?')[0]; + const anchorDoc = Array.from(hrefs ?? []) + .lastElement() + .replace(Doc.localServerPath(), '') + .split('?')[0]; const deleteMarkups = undoBatch(() => { const sel = editor.state.selection; editor.dispatch(editor.state.tr.removeMark(sel.from, sel.to, editor.state.schema.marks.linkAnchor)); @@ -1308,7 +1308,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps if (this._editorView && reference) { const content = await RichTextUtils.GoogleDocs.Export(this._editorView.state); const response = await GoogleApiClientUtils.Docs.write({ reference, content, mode }); - response && (this.dataDoc[GoogleRef] = response.documentId); + response?.documentId && (this.dataDoc[GoogleRef] = response.documentId); const pushSuccess = response !== undefined && !('errors' in response); dataDoc.googleDocUnchanged = pushSuccess; DocumentButtonBar.Instance.startPushOutcome(pushSuccess); @@ -1783,23 +1783,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps const state = this._editorView!.state; const curText = state.doc.textBetween(0, state.doc.content.size, ' \n'); - if (this.layoutDoc[this.SidebarKey + '_type_collection'] === 'translation' && !this.fieldKey.includes('translation') && curText.endsWith(' ') && curText !== this._lastText) { - try { - translate(curText, { from: 'en', to: 'es' }).then((result1: any) => { - setTimeout( - () => - translate(result1.text, { from: 'es', to: 'en' }).then((result: any) => { - const tb = this._sidebarTagRef.current as FormattedTextBox; - tb._editorView?.dispatch(tb._editorView!.state.tr.insertText(result1.text + '\r\n\r\n' + result.text)); - }), - 1000 - ); - }); - } catch (e: any) { - console.log(e.message); - } - this._lastText = curText; - } if (StrCast(this.Document.title).startsWith('@') && !this.dataDoc.title_custom) { UndoManager.RunInBatch(() => { this.dataDoc.title_custom = true; @@ -1954,7 +1937,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } @computed get sidebarCollection() { const renderComponent = (tag: string) => { - const ComponentTag = tag === CollectionViewType.Freeform ? CollectionFreeFormView : tag === CollectionViewType.Tree ? CollectionTreeView : tag === 'translation' ? FormattedTextBox : CollectionStackingView; + const ComponentTag: any = tag === CollectionViewType.Freeform ? CollectionFreeFormView : tag === CollectionViewType.Tree ? CollectionTreeView : tag === 'translation' ? FormattedTextBox : CollectionStackingView; return ComponentTag === CollectionStackingView ? ( <SidebarAnnos ref={this._sidebarRef} diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 791a1bfe7..7ce06cf7f 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -1,6 +1,6 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { lift, wrapIn } from 'prosemirror-commands'; diff --git a/src/client/views/nodes/formattedText/SummaryView.tsx b/src/client/views/nodes/formattedText/SummaryView.tsx index 3355e4529..7ec296ed2 100644 --- a/src/client/views/nodes/formattedText/SummaryView.tsx +++ b/src/client/views/nodes/formattedText/SummaryView.tsx @@ -1,7 +1,7 @@ import { TextSelection } from 'prosemirror-state'; import { Fragment, Node, Slice } from 'prosemirror-model'; import * as ReactDOM from 'react-dom/client'; -import React = require('react'); +import * as React from 'react'; // an elidable textblock that collapses when its '<-' is clicked and expands when its '...' anchor is clicked. // this node actively edits prosemirror (as opposed to just changing how things are rendered) and thus doesn't diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts index 4faef26e2..a342285b0 100644 --- a/src/client/views/nodes/formattedText/marks_rts.ts +++ b/src/client/views/nodes/formattedText/marks_rts.ts @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { DOMOutputSpec, Fragment, MarkSpec, Node, NodeSpec, Schema, Slice } from 'prosemirror-model'; import { Doc } from '../../../../fields/Doc'; diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts index 4cd2cee52..d023020e1 100644 --- a/src/client/views/nodes/formattedText/nodes_rts.ts +++ b/src/client/views/nodes/formattedText/nodes_rts.ts @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { DOMOutputSpec, Node, NodeSpec } from 'prosemirror-model'; import { listItem, orderedList } from 'prosemirror-schema-list'; import { ParagraphNodeSpec, toParagraphDOM, getParagraphNodeAttrs } from './ParagraphNodeSpec'; diff --git a/src/client/views/nodes/generativeFill/GenerativeFill.tsx b/src/client/views/nodes/generativeFill/GenerativeFill.tsx index 2b0927148..87e1b69c3 100644 --- a/src/client/views/nodes/generativeFill/GenerativeFill.tsx +++ b/src/client/views/nodes/generativeFill/GenerativeFill.tsx @@ -21,7 +21,7 @@ import { activeColor, canvasSize, eraserColor, freeformRenderSize, newCollection import { CursorData, ImageDimensions, Point } from './generativeFillUtils/generativeFillInterfaces'; import { APISuccess, ImageUtility } from './generativeFillUtils/ImageHandler'; import { PointerHandler } from './generativeFillUtils/PointerHandler'; -import React = require('react'); +import * as React from 'react'; enum BrushStyle { ADD, @@ -438,7 +438,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD // disable once edited has been clicked (doesn't make sense to change after first edit) disabled={edited} checked={isNewCollection} - onChange={e => { + onChange={() => { setIsNewCollection(prev => !prev); }} /> @@ -513,7 +513,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD defaultValue={150} size="small" valueLabelDisplay="auto" - onChange={(e, val) => { + onChange={(e: any, val: any) => { setCursorData(prev => ({ ...prev, width: val as number })); }} /> @@ -571,7 +571,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD <div> <TextField value={input} - onChange={e => setInput(e.target.value)} + onChange={(e: any) => setInput(e.target.value)} disabled={isBrushing} type="text" label="Prompt" diff --git a/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx b/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx index 10eca358e..185ba2280 100644 --- a/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx +++ b/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx @@ -1,5 +1,5 @@ import './GenerativeFillButtons.scss'; -import React = require('react'); +import * as React from 'react'; import ReactLoading from 'react-loading'; import { activeColor } from './generativeFillUtils/generativeFillConstants'; import { Button, IconButton, Type } from 'browndash-components'; diff --git a/src/client/views/nodes/importBox/ImportElementBox.tsx b/src/client/views/nodes/importBox/ImportElementBox.tsx index c4c89d8b1..9dc0c5180 100644 --- a/src/client/views/nodes/importBox/ImportElementBox.tsx +++ b/src/client/views/nodes/importBox/ImportElementBox.tsx @@ -7,7 +7,7 @@ import { ViewBoxBaseComponent } from '../../DocComponent'; import { DefaultStyleProvider } from '../../StyleProvider'; import { DocumentView, DocumentViewInternal } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; -import React = require('react'); +import * as React from 'react'; @observer export class ImportElementBox extends ViewBoxBaseComponent<FieldViewProps>() { diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 2303e4126..1317ca814 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -1,6 +1,6 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, computed, IReactionDisposer, observable, ObservableSet, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, DocListCast, FieldResult, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index f8aebd021..cd6beac57 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; @@ -24,7 +24,7 @@ import { StyleProp } from '../../StyleProvider'; import { PresBox } from './PresBox'; import './PresElementBox.scss'; import { PresMovement } from './PresEnums'; -import React = require('react'); +import * as React from 'react'; /** * This class models the view a document added to presentation will have in the presentation. * It involves some functionality for its buttons and options. diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index d68859e88..2d8e9e2a2 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -1,9 +1,9 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { ColorPicker, Group, IconButton, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components'; import { action, computed, IReactionDisposer, observable, ObservableMap, reaction } from 'mobx'; import { observer } from 'mobx-react'; -import { ColorState } from 'react-color'; +import { ColorResult } from 'react-color'; import { Doc, Opt } from '../../../fields/Doc'; import { returnFalse, setupMoveUpEvents, unimplementedFunction, Utils } from '../../../Utils'; import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT'; @@ -139,13 +139,10 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> { } @action changeHighlightColor = (color: string) => { - const col: ColorState = { + const col: ColorResult = { hex: color, - hsl: { a: 0, h: 0, s: 0, l: 0, source: '' }, - hsv: { a: 0, h: 0, s: 0, v: 0, source: '' }, - rgb: { a: 0, r: 0, b: 0, g: 0, source: '' }, - oldHue: 0, - source: '', + hsl: { a: 0, h: 0, s: 0, l: 0 }, + rgb: { a: 0, r: 0, b: 0, g: 0 }, }; this.highlightColor = Utils.colorString(col); }; diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index e1e87763c..cf19ff6bc 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { action, computed } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index 038c45582..0cda36509 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -1,10 +1,10 @@ -import React = require('react'); +import * as React from 'react'; import './GPTPopup.scss'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; import ReactLoading from 'react-loading'; -import Typist from 'react-typist'; +import { TypeAnimation } from 'react-type-animation'; import { Doc } from '../../../../fields/Doc'; import { DocUtils, Docs } from '../../../documents/Documents'; import { Button, IconButton, Type } from 'browndash-components'; @@ -218,17 +218,18 @@ export class GPTPopup extends React.Component<GPTPopupProps> { <div className="content-wrapper"> {!this.loading && (!this.done ? ( - <Typist - key={this.text} - avgTypingDelay={15} - cursor={{ hideWhenDone: true }} - onTypingDone={() => { - setTimeout(() => { - this.setDone(true); - }, 500); - }}> - {this.text} - </Typist> + <TypeAnimation + speed={50} + sequence={[ + this.text, + () => { + setTimeout(() => { + this.setDone(true); + }, 500); + }, + ]} + //cursor={{ hideWhenDone: true }} + /> ) : ( this.text ))} diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 33a336de3..b2373b190 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -23,7 +23,7 @@ import { AnchorMenu } from './AnchorMenu'; import { Annotation } from './Annotation'; import { GPTPopup } from './GPTPopup/GPTPopup'; import './PDFViewer.scss'; -import React = require('react'); +import * as React from 'react'; const PDFJSViewer = require('pdfjs-dist/web/pdf_viewer'); const pdfjsLib = require('pdfjs-dist'); const _global = (window /* browser */ || global) /* node */ as any; diff --git a/src/client/views/search/IconButton.tsx b/src/client/views/search/IconButton.tsx index 6cf3a5f72..e12e4511c 100644 --- a/src/client/views/search/IconButton.tsx +++ b/src/client/views/search/IconButton.tsx @@ -1,29 +1,27 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import * as _ from "lodash"; +import * as _ from 'lodash'; import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { DocumentType } from "../../documents/DocumentTypes"; +import { DocumentType } from '../../documents/DocumentTypes'; import '../global/globalCssVariables.scss'; import { IconBar } from './IconBar'; -import "./IconButton.scss"; -import "./SearchBox.scss"; -import { Font } from '@react-pdf/renderer'; +import './IconButton.scss'; +import './SearchBox.scss'; -interface IconButtonProps { +interface iconButtonProps { type: string; } @observer -export class IconButton extends React.Component<IconButtonProps>{ - +export class IconButton extends React.Component<iconButtonProps> { @observable private _isSelected: boolean = IconBar.Instance.getIcons().indexOf(this.props.type) !== -1; @observable private _hover = false; private _resetReaction?: IReactionDisposer; private _selectAllReaction?: IReactionDisposer; static Instance: IconButton; - constructor(props: IconButtonProps) { + constructor(props: iconButtonProps) { super(props); IconButton.Instance = this; } @@ -40,7 +38,7 @@ export class IconButton extends React.Component<IconButtonProps>{ IconBar.Instance._resetClicked = false; } } - }), + }) ); this._selectAllReaction = reaction( @@ -54,25 +52,25 @@ export class IconButton extends React.Component<IconButtonProps>{ IconBar.Instance._selectAllClicked = false; } } - }), + }) ); - } + }; @action.bound getIcon() { switch (this.props.type) { - case (DocumentType.NONE): return "ban"; - case (DocumentType.AUDIO): return "music"; - case (DocumentType.COL): return "object-group"; - case (DocumentType.IMG): return "image"; - case (DocumentType.LINK): return "link"; - case (DocumentType.PDF): return "file-pdf"; - case (DocumentType.RTF): return "sticky-note"; - case (DocumentType.VID): return "video"; - case (DocumentType.WEB): return "globe-asia"; - case (DocumentType.MAP): return "map-marker-alt"; - default: return "caret-down"; - } + case DocumentType.NONE: return 'ban'; + case DocumentType.AUDIO: return 'music'; + case DocumentType.COL: return 'object-group'; + case DocumentType.IMG: return 'image'; + case DocumentType.LINK: return 'link'; + case DocumentType.PDF: return 'file-pdf'; + case DocumentType.RTF: return 'sticky-note'; + case DocumentType.VID: return 'video'; + case DocumentType.WEB: return 'globe-asia'; + case DocumentType.MAP: return 'map-marker-alt'; + default: return 'caret-down'; + } // prettier-ignore } @action.bound @@ -82,45 +80,39 @@ export class IconButton extends React.Component<IconButtonProps>{ if (!this._isSelected) { this._isSelected = true; newList.push(this.props.type); - } - else { + } else { this._isSelected = false; _.pull(newList, this.props.type); } IconBar.Instance.updateIcon(newList); - } + }; selected = { opacity: 1, - backgroundColor: "#121721", + backgroundColor: '#121721', //backgroundColor: "rgb(128, 128, 128)" }; notSelected = { opacity: 0.2, - backgroundColor: "#121721", + backgroundColor: '#121721', }; hoverStyle = { opacity: 1, - backgroundColor: "rgb(128, 128, 128)" + backgroundColor: 'rgb(128, 128, 128)', //backgroundColor: "rgb(178, 206, 248)" //$medium-blue }; render() { return ( - <div className="type-outer" id={this.props.type + "-filter"} - onMouseEnter={() => this._hover = true} - onMouseLeave={() => this._hover = false} - onClick={this.onClick}> - <div className="type-icon" id={this.props.type + "-icon"} - style={this._hover ? this.hoverStyle : this._isSelected ? this.selected : this.notSelected} - > + <div className="type-outer" id={this.props.type + '-filter'} onMouseEnter={() => (this._hover = true)} onMouseLeave={() => (this._hover = false)} onClick={this.onClick}> + <div className="type-icon" id={this.props.type + '-icon'} style={this._hover ? this.hoverStyle : this._isSelected ? this.selected : this.notSelected}> <FontAwesomeIcon className="fontawesome-icon" icon={this.getIcon()} /> </div> {/* <div className="filter-description">{this.props.type}</div> */} </div> ); } -}
\ No newline at end of file +} diff --git a/src/client/views/search/NaviconButton.scss b/src/client/views/search/NaviconButton.scss index 8a70b29de..13d31bbe9 100644 --- a/src/client/views/search/NaviconButton.scss +++ b/src/client/views/search/NaviconButton.scss @@ -1,4 +1,4 @@ -@import "../global/globalCssVariables"; +@import '../global/globalCssVariables'; $height-icon: 15px; $width-line: 30px; @@ -6,7 +6,7 @@ $height-line: 4px; $transition-time: 0.4s; $rotation: 45deg; -$translateY: ($height-icon / 2); +$translateY: calc($height-icon / 2); $translateX: 0; #hamburger-icon { @@ -25,7 +25,7 @@ $translateX: 0; height: $height-line; position: absolute; left: 0; - border-radius: ($height-line / 2); + border-radius: calc($height-line / 2); transition: all $transition-time; -webkit-transition: all $transition-time; -moz-transition: all $transition-time; @@ -66,4 +66,4 @@ $translateX: 0; transform: scale(1.1); -webkit-transform: scale(1.1); -moz-transform: scale(1.1); -}
\ No newline at end of file +} diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 74464181f..3172ff9c0 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -1,4 +1,4 @@ -import { Tooltip } from '@material-ui/core'; +import { Tooltip } from '@mui/material'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; diff --git a/src/client/views/selectedDoc/SelectedDocView.tsx b/src/client/views/selectedDoc/SelectedDocView.tsx index 2139919e0..39e778b76 100644 --- a/src/client/views/selectedDoc/SelectedDocView.tsx +++ b/src/client/views/selectedDoc/SelectedDocView.tsx @@ -1,4 +1,4 @@ -import React = require('react'); +import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { ListBox } from 'browndash-components'; import { computed } from 'mobx'; diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx index 524492226..093806127 100644 --- a/src/client/views/webcam/DashWebRTCVideo.tsx +++ b/src/client/views/webcam/DashWebRTCVideo.tsx @@ -11,7 +11,7 @@ import { DocumentView } from '../nodes/DocumentView'; import { FieldView, FieldViewProps } from '../nodes/FieldView'; import './DashWebRTCVideo.scss'; import { hangup, initialize, refreshVideos } from './WebCamLogic'; -import React = require('react'); +import * as React from 'react'; /** * This models the component that will be rendered, that can be used as a doc that will reflect the video cams. |