From 1585ae672a6e01886fe029de87fe56992d04e0e0 Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Wed, 4 Sep 2024 23:05:38 -0400 Subject: code changes and comments --- src/client/util/Scripting.ts | 4 +- src/client/views/GestureOverlay.tsx | 152 +++++++++++++++++++-------------- src/client/views/InkTranscription.tsx | 78 ++++++++--------- src/client/views/nodes/DiagramBox.scss | 2 - src/client/views/nodes/DiagramBox.tsx | 145 ++++--------------------------- 5 files changed, 138 insertions(+), 243 deletions(-) (limited to 'src') diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index c63d3d7cb..68dab8f99 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -1,7 +1,7 @@ // export const ts = (window as any).ts; // import * as typescriptlib from '!!raw-loader!../../../node_modules/typescript/lib/lib.d.ts' // import * as typescriptes5 from '!!raw-loader!../../../node_modules/typescript/lib/lib.es5.d.ts' -import typescriptlib from 'type_decls.d'; +//import typescriptlib from 'type_decls.d'; import * as ts from 'typescript'; import { Doc, FieldType } from '../../fields/Doc'; import { RefField } from '../../fields/RefField'; @@ -248,7 +248,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp const funcScript = `(function(${paramString})${reqTypes} { ${body} })`; host.writeFile('file.ts', funcScript); - if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib); + //if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib); const program = ts.createProgram(['file.ts'], {}, host); const testResult = program.emit(); const outputText = host.readFile('file.js'); diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 0c797adf2..c1ac3ab06 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -33,8 +33,6 @@ import { returnEmptyDocViewList } from './StyleProvider'; import { ActiveFillColor, DocumentView } from './nodes/DocumentView'; import { CollectionFreeFormView } from './collections/collectionFreeForm'; import { InkingStroke } from './InkingStroke'; -import { NullLiteral } from 'typescript'; -import { isNull } from 'lodash'; export enum ToolglassTools { InkToText = 'inktotext', IgnoreGesture = 'ignoregesture', @@ -45,10 +43,12 @@ interface GestureOverlayProps { isActive: boolean; } @observer +/** + * class for gestures. will determine if what the user drew is a gesture, and will transform the ink stroke into the shape the user + * drew or perform the gesture's action + */ export class GestureOverlay extends ObservableReactComponent> { - // eslint-disable-next-line no-use-before-define static Instance: GestureOverlay; - // eslint-disable-next-line no-use-before-define static Instances: GestureOverlay[] = []; @observable public InkShape: Opt = undefined; @@ -131,20 +131,24 @@ export class GestureOverlay extends ObservableReactComponent view.ComponentView instanceof CollectionFreeFormView); - const points = this._points.map(p => ({ X: p.X, Y: p.Y })); - const cuspArray = this.getNumberOfCusps(points); - let cuspBooleanArray: boolean[] = []; - let docsToDelete: Doc[] = []; + const cuspArray = this.getCusps(); + const cuspBooleanArray: boolean[] = []; + const docsToDelete: Doc[] = []; const childDocs = (ffView?.ComponentView as CollectionFreeFormView).childDocs; childDocs.filter(doc => doc.type === 'ink').map(doc => DocumentView.getDocumentView(doc, DocumentView.getDocumentView(doc))); if ((ffView?.ComponentView as CollectionFreeFormView).childDocs) { + //how many cusps the scribble hsa if (cuspArray.length > 4) { - console.log('there are enough cusps'); for (let i = 0; i < cuspArray.length - 2; i++) { let hasDocInTriangle = false; - for (let doc of childDocs) { + for (const doc of childDocs) { const point1 = cuspArray[i]; const point2 = cuspArray[i + 1]; const point3 = cuspArray[i + 2]; @@ -152,9 +156,6 @@ export class GestureOverlay extends ObservableReactComponent otherInk.ptToScreen(point)); - console.log(otherScreenPts); - console.log((DocumentView.getDocumentView(doc)?.ComponentView as InkingStroke).inkScaledData().inkData.map(point => ({ X: point.X, Y: point.Y }))); - console.log(triangleObject); if (doc.title === 'line') { if (this.doesLineIntersectTriangle(otherScreenPts, triangleObject)) { docsToDelete.push(doc); @@ -182,6 +183,12 @@ export class GestureOverlay extends ObservableReactComponent value).length; const percentageTrues = trueCount / cuspBooleanArray.length; - if (percentageTrues > 0.65 || hasObjectInFirstAndLast25) { - console.log('requirements are met'); - } return percentageTrues > 0.65 || hasObjectInFirstAndLast25; } + /** + * determines if two rectangles are overlapping each other + * @param rect1 the rectangle object has has a minX,maxX,minY, and maxY + * @param rect2 + * @returns + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any isRectangleOverlap(rect1: any, rect2: any): boolean { const noOverlap = rect1.maxX < rect2.minX || rect1.minX > rect2.maxX || rect1.maxY < rect2.minY || rect1.minY > rect2.maxY; return !noOverlap; } - isPointInTriangle(pt: { X: number; Y: number }, triangle: any): boolean { + /** + * determines if there is a point in a triangle used to determine what triangles in the scribble have an object + * @param pt the point in question + * @param triangle the triangle with 3 points + * @returns true or false if point is in triangle + */ + isPointInTriangle(pt: { X: number; Y: number }, triangle: { p1: { X: number; Y: number }; p2: { X: number; Y: number }; p3: { X: number; Y: number } }): boolean { const area = (v1: { X: number; Y: number }, v2: { X: number; Y: number }, v3: { X: number; Y: number }) => Math.abs((v1.X * (v2.Y - v3.Y) + v2.X * (v3.Y - v1.Y) + v3.X * (v1.Y - v2.Y)) / 2.0); const A = area(triangle.p1, triangle.p2, triangle.p3); @@ -218,16 +233,29 @@ export class GestureOverlay extends ObservableReactComponent { - console.log('pointer up'); DocumentView.DownDocView = undefined; if (this._points.length > 1) { const B = this.svgBounds; @@ -277,7 +312,6 @@ export class GestureOverlay extends ObservableReactComponent 2 && GestureUtils.GestureRecognizer.Recognize([points]); let actionPerformed = false; - //console.log(result); if (Doc.UserDoc().recognizeGestures && result && result.Score > 0.7) { switch (result.Name) { case Gestures.Line: @@ -286,21 +320,17 @@ export class GestureOverlay extends ObservableReactComponent 4 && dist < 10) controlPoints[controlPoints.length - 1] = controlPoints[0]; this._points.length = 0; this._points.push(...controlPoints); @@ -333,9 +362,12 @@ export class GestureOverlay extends ObservableReactComponent view.ComponentView instanceof CollectionFreeFormView); - let docsToBeConverted: Doc[] = []; let minX = 999999999; let maxX = -999999999; let minY = 999999999; @@ -345,15 +377,9 @@ export class GestureOverlay extends ObservableReactComponent { if (typeof doc.width === 'number' && typeof doc.height === 'number' && typeof doc.x === 'number' && typeof doc.y === 'number') { const bounds = DocumentView.getDocumentView(doc)?.getBounds; - console.log(DocumentView.getDocumentView(doc)); - console.log(bounds); if (bounds) { const rect1 = { minX: bounds.left, maxX: bounds.right, minY: bounds.top, maxY: bounds.bottom }; - console.log(rect1); - console.log(this.getExtremeCoordinates(this._points)); - const points = this._points.map(p => ({ X: p.X, Y: p.Y })); - console.log(points); - if (this.isRectangleOverlap(rect1, this.getExtremeCoordinates(this._points))) { + if (this.isRectangleOverlap(rect1, this.getExtremeCoordinates())) { if (doc.x < minX) { minX = doc.x; } @@ -373,35 +399,23 @@ export class GestureOverlay extends ObservableReactComponent ({ X: p.X, Y: p.Y })); + const arrayOfPoints: { X: number; Y: number }[] = []; arrayOfPoints.push(points[0]); for (let i = 0; i < points.length - 2; i++) { const point1 = points[i]; const point2 = points[i + 1]; const point3 = points[i + 2]; - // console.log(point1); - // console.log(point2); - // console.log(point3); - // console.log(this.find_angle(point1, point2, point3)); if (this.find_angle(point1, point2, point3) < 90) { arrayOfPoints.push(point2); } @@ -409,7 +423,12 @@ export class GestureOverlay extends ObservableReactComponent { @@ -636,7 +660,6 @@ export class GestureOverlay extends ObservableReactComponent { const b = { left: -20000, right: 20000, top: -20000, bottom: 20000, width: 40000, height: 40000 }; // this.getBounds(l, true); return ( - // eslint-disable-next-line react/no-array-index-key {InteractionUtils.CreatePolyline( l, @@ -758,7 +781,6 @@ export class GestureOverlay extends ObservableReactComponent { GestureOverlay.Instance.SavedColor = ActiveInkColor(); @@ -771,7 +793,6 @@ ScriptingGlobals.add(function setPen(width: string, color: string, fill: string, SetActiveDash(dash); }); }); -// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function resetPen() { runInAction(() => { SetActiveInkColor(GestureOverlay.Instance.SavedColor ?? 'rgb(0, 0, 0)'); @@ -779,7 +800,6 @@ ScriptingGlobals.add(function resetPen() { }); }, 'resets the pen tool'); ScriptingGlobals.add( - // eslint-disable-next-line prefer-arrow-callback function createText(text: string, X: number, Y: number) { GestureOverlay.Instance.dispatchGesture(Gestures.Text, [{ X, Y }], text); }, diff --git a/src/client/views/InkTranscription.tsx b/src/client/views/InkTranscription.tsx index 93f054462..d2589b139 100644 --- a/src/client/views/InkTranscription.tsx +++ b/src/client/views/InkTranscription.tsx @@ -3,7 +3,7 @@ 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, ImageCast, NumCast, StrCast } from '../../fields/Types'; +import { Cast, DateCast, ImageCast, NumCast } from '../../fields/Types'; import { aggregateBounds } from '../../Utils'; import { DocumentType } from '../documents/DocumentTypes'; import { CollectionFreeFormView } from './collections/collectionFreeForm'; @@ -11,11 +11,8 @@ import { InkingStroke } from './InkingStroke'; import './InkTranscription.scss'; import { Docs } from '../documents/Documents'; import { DocumentView } from './nodes/DocumentView'; -import { Number } from 'mongoose'; -import { NumberArray } from 'd3'; import { ImageField } from '../../fields/URLField'; import { gptHandwriting } from '../apis/gpt/GPT'; -import * as fs from 'fs'; import { URLField } from '../../fields/URLField'; /** * Class component that handles inking in writing mode @@ -23,16 +20,22 @@ import { URLField } from '../../fields/URLField'; export class InkTranscription extends React.Component { static Instance: InkTranscription; + // eslint-disable-next-line @typescript-eslint/no-explicit-any @observable _mathRegister: any = undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any @observable _mathRef: any = undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any @observable _textRegister: any = undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any @observable _textRef: any = undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any @observable iinkEditor: any = undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any private lastJiix: any; private currGroup?: Doc; private collectionFreeForm?: CollectionFreeFormView; - constructor(props: Readonly<{}>) { + constructor(props: Readonly) { super(props); InkTranscription.Instance = this; @@ -44,9 +47,9 @@ export class InkTranscription extends React.Component { } @action + // eslint-disable-next-line @typescript-eslint/no-explicit-any setMathRef = async (r: any) => { if (!this._textRegister && r) { - let editor; const options = { configuration: { server: { @@ -61,21 +64,22 @@ export class InkTranscription extends React.Component { }, }, }; - - editor = new iink.Editor(r, options as any); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const editor = new iink.Editor(r, options as any); await editor.initialize(); this._textRegister = r; + // eslint-disable-next-line @typescript-eslint/no-explicit-any r?.addEventListener('exported', (e: any) => this.exportInk(e, this._textRef)); return (this._textRef = r); } }; @action + // eslint-disable-next-line @typescript-eslint/no-explicit-any setTextRef = async (r: any) => { if (!this._textRegister && r) { - let editor; const options = { configuration: { server: { @@ -90,12 +94,13 @@ export class InkTranscription extends React.Component { }, }, }; - - editor = new iink.Editor(r, options as any); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const editor = new iink.Editor(r, options as any); await editor.initialize(); this.iinkEditor = editor; this._textRegister = r; + // eslint-disable-next-line @typescript-eslint/no-explicit-any r?.addEventListener('exported', (e: any) => this.exportInk(e, this._textRef)); return (this._textRef = r); @@ -124,28 +129,9 @@ export class InkTranscription extends React.Component { strokes.push(d.inkData.map(pd => inkStroke.ptToScreen({ X: pd.X, Y: pd.Y }))); times.push(DateCast(i.author_date).getDate().getTime()); }); - console.log(strokes); - console.log( - `this.Multistrokes.push( - new Multistroke( - Gestures.Scribble, - useBoundedRotationInvariance, - new Array([ - ` + - this.convertPointsToString(strokes) + - ` - ]) - ) - ) - ` - ); - //console.log(this.convertPointsToString(strokes)); - //console.log(this.convertPointsToString2(strokes)); this.currGroup = groupDoc; const pointerData = strokes.map((stroke, i) => this.inkJSON(stroke, times[i])); - const processGestures = false; if (math) { - console.log('math'); this.iinkEditor.importPointEvents(pointerData); } else { this.iinkEditor.importPointEvents(pointerData); @@ -172,9 +158,9 @@ export class InkTranscription extends React.Component { t: number; p: number; } - let strokeObjects: strokeData[] = []; + const strokeObjects: strokeData[] = []; stroke.forEach(point => { - let tempObject: strokeData = { + const tempObject: strokeData = { x: point.X, y: point.Y, t: time, @@ -220,6 +206,7 @@ export class InkTranscription extends React.Component { * @param e the event objects * @param ref the ref to the editor */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any exportInk = async (e: any, ref: any) => { const exports = e.detail['application/vnd.myscript.jiix']; if (exports) { @@ -236,6 +223,7 @@ export class InkTranscription extends React.Component { this.lastJiix = JSON.parse(exports['application/vnd.myscript.jiix']); // map timestamp to strokes const timestampWord = new Map(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any this.lastJiix.words.map((word: any) => { if (word.items) { word.items.forEach((i: { id: string; timestamp: string; X: Array; Y: Array; F: Array }) => { @@ -271,10 +259,7 @@ export class InkTranscription extends React.Component { if (this.currGroup && text) { DocumentView.getDocumentView(this.currGroup)?.ComponentView?.updateIcon?.(); - let image = await this.getIcon(); - const pathname = image?.url.href as string; - console.log(image?.url); - console.log(image); + const image = await this.getIcon(); const { href } = (image as URLField).url; const hrefParts = href.split('.'); const hrefComplete = `${hrefParts[0]}_o.${hrefParts[1]}`; @@ -282,9 +267,8 @@ export class InkTranscription extends React.Component { try { const hrefBase64 = await this.imageUrlToBase64(hrefComplete); response = await gptHandwriting(hrefBase64); - console.log(response); - } catch (error) { - console.log('bad things have happened'); + } catch { + console.error('Error getting image'); } const textBoxText = 'iink: ' + text + '\n' + '\n' + 'ChatGPT: ' + response; this.currGroup.transcription = response; @@ -300,16 +284,22 @@ export class InkTranscription extends React.Component { } } }; + /** + * gets the icon of the collection that was just made + * @returns the image of the collection + */ async getIcon() { const docView = DocumentView.getDocumentView(this.currGroup); - console.log(this.currGroup); if (docView) { - console.log(docView); docView.ComponentView?.updateIcon?.(); return new Promise(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 1000)); } return undefined; } + /** + * converts the image to base url formate + * @param imageUrl imageurl taken from the collection icon + */ imageUrlToBase64 = async (imageUrl: string): Promise => { try { const response = await fetch(imageUrl); @@ -413,8 +403,8 @@ export class InkTranscription extends React.Component { } // nda - bug: when deleting a stroke before leaving writing mode, delete the stroke from unprocessed ink docs - newCollection && docView.props.addDocument?.(newCollection); if (newCollection) { + docView.props.addDocument?.(newCollection); newCollection.hasTextBox = false; } return newCollection; @@ -423,8 +413,8 @@ export class InkTranscription extends React.Component { render() { return (
-
-
+
+
); } diff --git a/src/client/views/nodes/DiagramBox.scss b/src/client/views/nodes/DiagramBox.scss index b43f961d0..8a7863c14 100644 --- a/src/client/views/nodes/DiagramBox.scss +++ b/src/client/views/nodes/DiagramBox.scss @@ -21,7 +21,6 @@ justify-content: center; align-items: center; width: 100%; - height: $searchbarHeight; padding: 10px; input[type='text'] { @@ -40,7 +39,6 @@ justify-content: center; align-items: center; width: 100%; - height: calc(100% - $searchbarHeight); .diagramBox { flex: 1; display: flex; diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 79cf39152..0d755fdbe 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -1,5 +1,3 @@ -/* eslint-disable prettier/prettier */ -/* eslint-disable jsx-a11y/control-has-associated-label */ import mermaid from 'mermaid'; import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; @@ -20,7 +18,9 @@ import { InkingStroke } from '../InkingStroke'; import './DiagramBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; - +/** + * this is a class for the diagram box doc type that can be found in the tools section of the side bar + */ @observer export class DiagramBox extends ViewBoxAnnotatableComponent() { public static LayoutString(fieldKey: string) { @@ -37,23 +37,12 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() { super(props); makeObservable(this); } - @observable renderDiv: React.ReactNode; - @observable inputValue = ''; - @observable createInputValue = ''; - @observable loading = false; - @observable errorMessage = ''; - @observable mermaidCode = ''; - @observable isExampleMenuOpen = false; + @observable _showCode = false; @observable _inputValue = ''; @observable _generating = false; @observable _errorMessage = ''; - @action handleInputChange = (e: React.ChangeEvent) => { - this.inputValue = e.target.value; - console.log(e.target.value); - }; - @computed get mermaidcode() { return Cast(this.Document[DocData].text, RichTextField, null)?.Text ?? ''; } @@ -74,14 +63,21 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() { { fireImmediately: true } ); } + /** + * helper method for renderMermaidAsync + * @param str string containing the mermaid code + * @returns + */ renderMermaid = (str: string) => { try { return mermaid.render('graph' + Date.now(), str); - } catch (error) { + } catch { return { svg: '', bindFunctions: undefined }; } }; - + /** + * will update the div containing the mermaid diagram to render the new mermaidCode + */ renderMermaidAsync = async (mermaidCode: string, dashDiv: HTMLDivElement) => { try { const { svg, bindFunctions } = await this.renderMermaid(mermaidCode); @@ -112,7 +108,9 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() { res ); }, 'set mermaid code'); - + /** + * will generate mermaid code with GPT based on what the user requested + */ generateMermaidCode = action(() => { this._generating = true; const prompt = 'Write this in mermaid code and only give me the mermaid code: ' + this._inputValue; @@ -212,117 +210,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() { ); } - exampleButton = () => { - if (this.isExampleMenuOpen) { - this.isExampleMenuOpen = false; - } else { - this.isExampleMenuOpen = true; - } - }; - flowButton = () => { - this.createInputValue = `flowchart TD - A[Christmas] -->|Get money| B(Go shopping) - B --> C{Let me think} - C -->|One| D[Laptop] - C -->|Two| E[iPhone] - C -->|Three| F[fa:fa-car Car]`; - }; - pieButton = () => { - this.createInputValue = `pie title Pets adopted by volunteers - "Dogs" : 386 - "Cats" : 85 - "Rats" : 15`; - }; - timelineButton = () => { - this.createInputValue = `gantt - title A Gantt Diagram - dateFormat YYYY-MM-DD - section Section - A task :a1, 2014-01-01, 30d - Another task :after a1 , 20d - section Another - Task in sec :2014-01-12 , 12d - another task : 24d`; - }; - classButton = () => { - this.createInputValue = `classDiagram - Animal <|-- Duck - Animal <|-- Fish - Animal <|-- Zebra - Animal : +int age - Animal : +String gender - Animal: +isMammal() - Animal: +mate() - class Duck{ - +String beakColor - +swim() - +quack() - } - class Fish{ - -int sizeInFeet - -canEat() - } - class Zebra{ - +bool is_wild - +run() - }`; - }; - mindmapButton = () => { - this.createInputValue = `mindmap - root((mindmap)) - Origins - Long history - ::icon(fa fa-book) - Popularisation - British popular psychology author Tony Buzan - Research - On effectivness
and features - On Automatic creation - Uses - Creative techniques - Strategic planning - Argument mapping - Tools - Pen and paper - Mermaid`; - }; - handleInputChangeEditor = (e: React.ChangeEvent) => { - if (typeof e.target.value === 'string') { - this.createInputValue = e.target.value; - } - }; - removeWhitespace(str: string): string { - return str.replace(/\s+/g, ''); - } - autoResize(element: HTMLTextAreaElement): void { - element.style.height = '5px'; - element.style.height = element.scrollHeight + 'px'; - } - timeline = `gantt - title College Timeline - dateFormat YYYY-MM-DD - section Semester 1 - Orientation :done, des1, 2023-08-01, 2023-08-03 - Classes Start :active, des2, 2023-08-04, 2023-12-15 - Midterm Exams : des3, 2023-10-15, 2023-10-20 - End of Semester : des4, 2023-12-16, 2023-12-20 - section Semester 2 - Classes Start : des5, 2024-01-10, 2024-05-15 - Spring Break : des6, 2024-03-15, 2024-03-22 - Midterm Exams : des7, 2024-03-25, 2024-03-30 - Final Exams : des8, 2024-05-10, 2024-05-15 - section Summer Break - Internship : des9, 2024-06-01, 2024-08-31 - section Semester 3 - Classes Start : des10, 2024-09-01, 2025-12-15 - Midterm Exams : des11, 2024-11-15, 2024-11-20 - End of Semester : des12, 2025-12-16, 2025-12-20 - section Semester 4 - Classes Start : des13, 2025-01-10, 2025-05-15 - Spring Break : des14, 2025-03-15, 2025-03-22 - Midterm Exams : des15, 2025-03-25, 2025-03-30 - Final Exams : des16, 2025-05-10, 2025-05-15 - Graduation : des17, 2025-05-20, 2025-05-21`; } Docs.Prototypes.TemplateMap.set(DocumentType.DIAGRAM, { -- cgit v1.2.3-70-g09d2