From 3163ba1c1711000aac58af9c9ede1739334ea995 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 3 Jun 2024 22:22:27 -0400 Subject: updated pdfViewer worker. fixed PDFbox action to set pdfcache. cleaned up messagecomponent --- .../views/nodes/ChatBox/MessageComponent.tsx | 110 ++++++++------------- src/client/views/nodes/PDFBox.tsx | 8 +- src/client/views/pdf/PDFViewer.tsx | 4 +- 3 files changed, 49 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/ChatBox/MessageComponent.tsx b/src/client/views/nodes/ChatBox/MessageComponent.tsx index fced0b4d5..ccdf1ae24 100644 --- a/src/client/views/nodes/ChatBox/MessageComponent.tsx +++ b/src/client/views/nodes/ChatBox/MessageComponent.tsx @@ -1,11 +1,24 @@ +/* eslint-disable jsx-a11y/control-has-associated-label */ /* eslint-disable react/require-default-props */ -import React from 'react'; -import { observer } from 'mobx-react'; import { MathJax, MathJaxContext } from 'better-react-mathjax'; +import { observer } from 'mobx-react'; +import React from 'react'; +import * as Tb from 'react-icons/tb'; import ReactMarkdown from 'react-markdown'; -import { TbCircle0Filled, TbCircle1Filled, TbCircle2Filled, TbCircle3Filled, TbCircle4Filled, TbCircle5Filled, TbCircle6Filled, TbCircle7Filled, TbCircle8Filled, TbCircle9Filled } from 'react-icons/tb'; import { AssistantMessage } from './types'; +const TbCircles = [ + Tb.TbCircleNumber0Filled, + Tb.TbCircleNumber1Filled, + Tb.TbCircleNumber2Filled, + Tb.TbCircleNumber3Filled, + Tb.TbCircleNumber4Filled, + Tb.TbCircleNumber5Filled, + Tb.TbCircleNumber6Filled, + Tb.TbCircleNumber7Filled, + Tb.TbCircleNumber8Filled, + Tb.TbCircleNumber9Filled, +]; interface MessageComponentProps { message: AssistantMessage; toggleToolLogs: (index: number) => void; @@ -17,89 +30,52 @@ interface MessageComponentProps { isCurrent?: boolean; } -const MessageComponent: React.FC = function ({ message, toggleToolLogs, expandedLogIndex, goToLinkedDoc, index, showModal, setCurrentFile, isCurrent = false }) { - // const messageClass = `${message.role} ${isCurrent ? 'current-message' : ''}`; - - const LinkRenderer = ({ href, children }: { href: string; children: React.ReactNode }) => { - // console.log(href + " " + children) - const regex = /([a-zA-Z0-9_.!-]+)~~~(citation|file_path)/; - const matches = href.match(regex); - // console.log(href) - // console.log(matches) - const url = matches ? matches[1] : href; - const linkType = matches ? matches[2] : null; - if (linkType === 'citation') { - switch (children) { - case '0': - children = ; - break; - case '1': - children = ; - break; - case '2': - children = ; - break; - case '3': - children = ; - break; - case '4': - children = ; - break; - case '5': - children = ; - break; - case '6': - children = ; - break; - case '7': - children = ; - break; - case '8': - children = ; - break; - case '9': - children = ; - break; - default: - break; - } - } - // console.log(linkType) - const style = { - color: 'lightblue', - verticalAlign: linkType === 'citation' ? 'super' : 'baseline', - fontSize: linkType === 'citation' ? 'smaller' : 'inherit', - }; +function LinkRendererWrapper(goToLinkedDoc: any, showModal: any, setCurrentFile: any) { + function LinkRenderer({ href, children }: { href?: string; children?: React.ReactNode }) { + const [, url, linkType] = href?.match(/([a-zA-Z0-9_.!-]+)~~~(citation|file_path)/) ?? [undefined, href, null]; + const Children = linkType === 'citation' ? null : TbCircles[Number(children)]; return ( + // eslint-disable-next-line jsx-a11y/anchor-is-valid { e.preventDefault(); - if (linkType === 'citation') { - goToLinkedDoc(url); - } else if (linkType === 'file_path') { - showModal(); - setCurrentFile({ url }); + switch (linkType) { + case 'citation': + goToLinkedDoc(url); + break; + case 'file_path': + showModal(); + setCurrentFile({ url }); + break; + default: } }} - style={style}> - {children} + style={{ + color: 'lightblue', + verticalAlign: linkType === 'citation' ? 'super' : 'baseline', + fontSize: linkType === 'citation' ? 'smaller' : 'inherit', + }}> + {Children ? : null} ); - }; - + } + return LinkRenderer; +} +const MessageComponent: React.FC = function ({ message, toggleToolLogs, expandedLogIndex, goToLinkedDoc, index, showModal, setCurrentFile, isCurrent = false }) { + // const messageClass = `${message.role} ${isCurrent ? 'current-message' : ''}`; return (
- {message.text ? message.text : ''} + {message.text} {message.image && }
{message.tool_logs && ( - )} diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 7a89b143b..8db68ddfe 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -655,9 +655,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { ); else { if (!PDFBox.pdfpromise.get(href)) PDFBox.pdfpromise.set(href, Pdfjs.getDocument(href).promise); - PDFBox.pdfpromise.get(href)?.then((pdf: any) => { - PDFBox.pdfcache.set(href, (this._pdf = pdf)); - }); + PDFBox.pdfpromise.get(href)?.then( + action((pdf: any) => { + PDFBox.pdfcache.set(href, (this._pdf = pdf)); + }) + ); } } return pdfView ?? this.renderTitleBox; diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 6c1617c38..db47a84e1 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -24,18 +24,16 @@ import { FieldViewProps } from '../nodes/FieldView'; import { FocusViewOptions } from '../nodes/FocusViewOptions'; import { LinkInfo } from '../nodes/LinkDocPreview'; import { PDFBox } from '../nodes/PDFBox'; -import { ComparisonBox } from '../nodes/ComparisonBox'; import { ObservableReactComponent } from '../ObservableReactComponent'; import { StyleProp } from '../StyleProp'; import { AnchorMenu } from './AnchorMenu'; import { Annotation } from './Annotation'; import { GPTPopup } from './GPTPopup/GPTPopup'; -import { Docs } from '../../documents/Documents'; import './PDFViewer.scss'; // pdfjsLib.GlobalWorkerOptions.workerSrc = `/assets/pdf.worker.js`; // The workerSrc property shall be specified. -Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.2.67/build/pdf.worker.mjs'; +Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.3.136/build/pdf.worker.mjs'; interface IViewerProps extends FieldViewProps { pdfBox: PDFBox; -- cgit v1.2.3-70-g09d2 From 2e9ec2e32cdbe78df8cde0803335739964e88f9d Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 3 Jun 2024 23:31:29 -0400 Subject: comparisonbox cleanup. --- src/client/views/nodes/ComparisonBox.tsx | 119 +++++++++++++------------------ 1 file changed, 51 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index adb380f12..fc4d7ab35 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -30,41 +30,23 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() return FieldView.LayoutString(ComparisonBox, fieldKey); } private _disposers: (DragManager.DragDropDisposer | undefined)[] = [undefined, undefined]; + private _closeRef = React.createRef(); + @observable _inputValue = ''; + @observable _outputValue = ''; + @observable _loading = false; + @observable _errorMessage = ''; + @observable _outputMessage = ''; + @observable _animating = ''; + constructor(props: FieldViewProps) { super(props); makeObservable(this); } - @observable inputValue = ''; - @observable outputValue = ''; - @observable loading = false; - @observable errorMessage = ''; - @observable outputMessage = ''; - - @action handleInputChange = (e: React.ChangeEvent) => { - this.inputValue = e.target.value; - console.log(this.inputValue); - }; - - @observable _animating = ''; - - @computed get clipWidth() { - return NumCast(this.layoutDoc[this.clipWidthKey], 50); - } - get clipWidthKey() { - return '_' + this._props.fieldKey + '_clipWidth'; - } - - @computed get clipHeight() { - return NumCast(this.layoutDoc[this.clipHeightKey], 200); - } - get clipHeightKey() { - return '_' + this._props.fieldKey + '_clipHeight'; - } - componentDidMount() { this._props.setContentViewBox?.(this); } + protected createDropTarget = (ele: HTMLDivElement | null, fieldKey: string, disposerId: number) => { this._disposers[disposerId]?.(); if (ele) { @@ -72,7 +54,13 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() } }; - private internalDrop = undoable((e: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => { + @computed get revealOp() { return this.layoutDoc[`_${this.fieldKey}_revealOp`] as ('flip'|'hover'|undefined); } // prettier-ignore + @computed get clipWidth() { return NumCast(this.layoutDoc[`_${this.fieldKey}_clipWidth`], 50); } // prettier-ignore + set clipWidth(width: number) { this.layoutDoc[`_${this.fieldKey}_clipWidth`] = width; } // prettier-ignore + @computed get useAlternate() { return this.layoutDoc[`_${this.fieldKey}_usePath`] === 'alternate'; } // prettier-ignore + set useAlternate(alt: boolean) { this.layoutDoc[`_${this.fieldKey}_usePath`] = alt ? 'alternate' : undefined; } // prettier-ignore + + internalDrop = undoable((e: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => { if (dropEvent.complete.docDragData) { const { droppedDocuments } = dropEvent.complete.docDragData; const added = dropEvent.complete.docDragData.moveDocument?.(droppedDocuments, this.Document, (doc: Doc | Doc[]) => this.addDoc(toList(doc).lastElement(), fieldKey)); @@ -84,7 +72,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() return undefined; }, 'internal drop'); - private registerSliding = (e: React.PointerEvent, targetWidth: number) => { + registerSliding = (e: React.PointerEvent, targetWidth: number) => { if (e.button !== 2) { setupMoveUpEvents( this, @@ -96,16 +84,18 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() this._isAnyChildContentActive = true; if (!this.dataDoc[this.fieldKey + '_1'] && !this.dataDoc[this.fieldKey]) this.dataDoc[this.fieldKey + '_1'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc); if (!this.dataDoc[this.fieldKey + '_2'] && !this.dataDoc[this.fieldKey + '_alternate']) this.dataDoc[this.fieldKey + '_2'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc); + // DocumentView.addViewRenderedCb(DocCast(this.dataDoc[this.fieldKey + '_1']), dv => { + // dv?.select(false); + // }); } }), - false, + true, undefined, action(() => { if (this._isAnyChildContentActive) return; this._animating = 'all 200ms'; // on click, animate slider movement to the targetWidth - this.layoutDoc[this.clipWidthKey] = (targetWidth * 100) / this._props.PanelWidth(); - // this.layoutDoc[this.clipHeightKey] = (targetWidth * 100) / this._props.PanelHeight(); + this.clipWidth = (targetWidth * 100) / this._props.PanelWidth(); setTimeout( action(() => { @@ -118,11 +108,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() } }; - @action - private onPointerMove = ({ movementX }: PointerEvent) => { + onPointerMove = ({ movementX }: PointerEvent) => { const width = movementX * this.ScreenToLocalBoxXf().Scale + (this.clipWidth / 100) * this._props.PanelWidth(); if (width && width > 5 && width < this._props.PanelWidth()) { - this.layoutDoc[this.clipWidthKey] = (width * 100) / this._props.PanelWidth(); + this.clipWidth = (width * 100) / this._props.PanelWidth(); } return false; }; @@ -180,8 +169,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() ); }; docStyleProvider = (doc: Opt, props: Opt, property: string): any => { - if (property === StyleProp.PointerEvents) return 'none'; - return this._props.styleProvider?.(doc, props, property); + switch (property) { + case StyleProp.PointerEvents: return 'none'; + default: return this._props.styleProvider?.(doc, props, property); + } // prettier-ignore }; moveDoc1 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true); moveDoc2 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true); @@ -220,36 +211,31 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() return layoutTemplateString; }; - _closeRef = React.createRef(); - /** * Flips a flashcard to the alternate side for the user to view. */ flipFlashcard = () => { - const usePath = this.layoutDoc[`_${this._props.fieldKey}_usePath`]; - this.layoutDoc[`_${this._props.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : undefined; + this.useAlternate = !this.useAlternate; }; /** * Changes the view option to hover for a flashcard. */ - hoverFlip = (side: string | undefined) => { - if (this.layoutDoc[`_${this._props.fieldKey}_revealOp`] === 'hover') this.layoutDoc[`_${this._props.fieldKey}_usePath`] = side; + hoverFlip = (alternate: boolean) => { + if (this.revealOp === 'hover') this.useAlternate = alternate; }; /** * Creates the button used to flip the flashcards. */ @computed get overlayAlternateIcon() { - const usepath = this.layoutDoc[`_${this._props.fieldKey}_usePath`]; return ( flip
}>
setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, () => { - console.log(this.layoutDoc[`_${this._props.fieldKey}_revealOp`]); - if (!this.layoutDoc[`_${this._props.fieldKey}_revealOp`] || this.layoutDoc[`_${this._props.fieldKey}_revealOp`] === 'flip') { + if (!this.revealOp || this.revealOp === 'flip') { this.flipFlashcard(); console.log('Print Front of cards: ' + (RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text ?? '')); console.log('Print Back of cards: ' + (RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text ?? '')); @@ -257,8 +243,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() }) } style={{ - background: usepath === 'alternate' ? 'white' : 'black', - color: usepath === 'alternate' ? 'black' : 'white', + background: this.useAlternate ? 'white' : 'black', + color: this.useAlternate ? 'black' : 'white', }}>
@@ -268,14 +254,14 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() @action handleRenderGPTClick = () => { // Call the GPT model and get the output - this.layoutDoc[`_${this._props.fieldKey}_usePath`] = 'alternate'; - this.outputValue = ''; - if (this.inputValue) this.askGPT(); + this.useAlternate = true; + this._outputValue = ''; + if (this._inputValue) this.askGPT(); }; @action handleRenderClick = () => { // Call the GPT model and get the output - this.layoutDoc[`_${this._props.fieldKey}_usePath`] = undefined; + this.useAlternate = false; }; /** @@ -285,7 +271,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() askGPT = async (): Promise => { const questionText = 'Question: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text); const rubricText = ' Rubric: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text); - const queryText = questionText + ' UserAnswer: ' + this.inputValue + '. ' + rubricText; + const queryText = questionText + ' UserAnswer: ' + this._inputValue + '. ' + rubricText; try { const res = await gptAPICall(queryText, GPTCallType.QUIZ); @@ -293,8 +279,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() console.error('GPT call failed'); return; } - this.outputValue = res; - console.log(res); + this._outputValue = res; } catch (err) { console.error('GPT call failed'); } @@ -355,7 +340,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() ); if (this.Document._layout_isFlashcard) { - const side = this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 1 : 0; + const side = this.useAlternate ? 1 : 0; // add text box to each side when comparison box is first created if (!(this.dataDoc[this.fieldKey + '_0'] || this.dataDoc[this.fieldKey + '_0'] === 'empty')) { @@ -383,17 +368,19 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() {/* {StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text)} */}