diff options
Diffstat (limited to 'src/client/views/nodes/ImageBox.tsx')
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 98 |
1 files changed, 79 insertions, 19 deletions
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 37827a43a..32b9e20a4 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -36,7 +36,7 @@ import { DocCast, NumCast, RTFCast, StrCast, ImageCast, Cast, toList } from '../ import './ImageBox.scss'; import { OpenWhere } from './OpenWhere'; import { URLField } from '../../../fields/URLField'; -import { gptImageLabel } from '../../apis/gpt/GPT'; +import { gptAPICall, GPTCallType, gptImageLabel } from '../../apis/gpt/GPT'; import ReactLoading from 'react-loading'; import { FollowLinkScript } from '../../documents/DocUtils'; import { basename } from 'path'; @@ -48,6 +48,12 @@ import axios from 'axios'; import { TupleType } from 'typescript'; // import stringSimilarity from 'string-similarity'; +enum quizMode { + SMART = 'smart', + NORMAL = 'normal', + NONE = 'none', +} + export class ImageEditorData { // eslint-disable-next-line no-use-before-define private static _instance: ImageEditorData; @@ -92,7 +98,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @observable private _width: number = 0; @observable private _height: number = 0; @observable private searchInput = ''; - @observable private _quizMode = false; + @observable private _quizMode = quizMode.NONE; @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>(); @observable _curSuffix = ''; @observable _error = ''; @@ -359,11 +365,14 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } }; - pushInfo = async () => { - this._quizMode = true; + pushInfo = async (quiz: quizMode) => { + this._quizMode = quiz; + this._loading = true; + console.log('JHSDKFJHKSDJFHKSJDHFKJSDHFKJHSDKF'); const img = { file: this.paths[0], + smart: quiz, }; const response = await axios.post('http://localhost:105/labels/', img, { headers: { @@ -399,8 +408,10 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { newCol.zIndex = 1000; newCol.forceActive = true; newCol.quiz = text; + newCol.showQuiz = false; this._quizBoxes.push(newCol); this.addDocument(newCol); + this._loading = false; } }; // static imageUrlToBase64 = async (imageUrl: string): Promise<string> => { @@ -496,25 +507,61 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { return distance <= threshold; }; + extractHexAndSentences = (inputString: string) => { + // Regular expression to match a hexadecimal number at the beginning followed by a period and sentences + const regex = /^#([0-9A-Fa-f]+)\.\s*(.+)$/s; + const match = inputString.match(regex); + + if (match) { + const hexNumber = match[1]; + const sentences = match[2].trim(); + return { hexNumber, sentences }; + } else { + return { error: 'The input string does not match the expected format.' }; + } + }; + check = () => { - this._quizBoxes.forEach(doc => { + this._loading = true; + this._quizBoxes.forEach(async doc => { const input = StrCast(RTFCast(DocCast(doc).text)?.Text); console.log('INP: ' + StrCast(input) + '; DOC: ' + StrCast(doc.quiz)); - const match = this.compareWords(input, StrCast(doc.quiz)); - doc.backgroundColor = match ? '#11c249' : '#eb2d2d'; + if (this._quizMode == quizMode.SMART && input) { + const questionText = 'Question: What was labeled in this image?'; + const rubricText = ' Rubric: ' + StrCast(doc.quiz); + // const queryText = 'RealAnswer: ' + StrCast(doc.quiz) + '. UserAnswer: ' + input + '.'; + const queryText = + questionText + + ' UserAnswer: ' + + input + + '. ' + + rubricText + + '. One sentence and evaluate based on meaning, not wording. Provide a hex color at the beginning with a period after it on a scale of green (minor details missed) to red (big error) for how correct the answer is. Example: "#FFFFFF. Pasta is delicious."'; + const response = await gptAPICall(queryText, GPTCallType.QUIZ); + const hexSent = this.extractHexAndSentences(response); + console.log(hexSent.hexNumber); + doc.quiz = hexSent.sentences; + doc.backgroundColor = '#' + hexSent.hexNumber; + } else { + const match = this.compareWords(input, StrCast(doc.quiz)); + doc.backgroundColor = match ? '#11c249' : '#eb2d2d'; + } + doc.showQuiz = true; // console.log(this.compareWords(input, StrCast(doc.quiz)) ? 'Match' : 'No Match'); }); + this._loading = false; }; redo = () => { this._quizBoxes.forEach(doc => { DocCast(doc)[DocData].text = ''; doc.backgroundColor = '#e4e4e4'; + doc.showQuiz = false; }); }; exitQuizMode = () => { - this._quizMode = false; + this._quizMode = quizMode.NONE; this._quizBoxes.forEach(doc => { // this._props.removeDocument?.(DocCast(doc)); // this._props.DocumentView?.()._props.removeDocument?.(doc); @@ -531,16 +578,28 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const field = Cast(this.dataDoc[this.fieldKey], ImageField); if (field) { const funcs: ContextMenuProps[] = []; + const quizes: ContextMenuProps[] = []; // funcs.push({ description: 'Create ai flashcards', event: () => this.getImageDesc(), icon: 'id-card' }); - funcs.push({ - description: 'Quiz Mode', - event: !this._quizMode - ? this.pushInfo - : () => { - this._quizMode = false; - }, - icon: 'redo-alt', + quizes.push({ + description: 'Smart Check', + event: this._quizMode == quizMode.NONE ? () => this.pushInfo(quizMode.SMART) : this.exitQuizMode, + icon: 'pen-to-square', + }); + quizes.push({ + description: 'Normal', + event: this._quizMode == quizMode.NONE ? () => this.pushInfo(quizMode.NORMAL) : this.exitQuizMode, + icon: 'pencil', }); + // funcs.push({ description: 'Quiz Mode', subitems: optionItems, icon: 'eye' }); + // funcs.push({ + // description: 'Quiz Mode', + // event: !this._quizMode + // ? () => this.pushInfo(false) + // : () => { + // this._quizMode = false; + // }, + // icon: 'redo-alt', + // }); // funcs.push({ description: 'Get Text', event: this.check, icon: 'redo-alt' }); // funcs.push({ description: 'Get Labels2', event: this.getImageLabels2, icon: 'redo-alt' }); // funcs.push({ description: 'Get Labels', event: this.getImageLabels, icon: 'redo-alt' }); @@ -558,6 +617,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }), icon: 'pencil-alt', }); + ContextMenu.Instance?.addItem({ description: 'Quiz Mode', subitems: quizes, icon: 'file-pen' }); ContextMenu.Instance?.addItem({ description: 'Options...', subitems: funcs, icon: 'asterisk' }); } }; @@ -689,8 +749,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { )} </div> {this.overlayImageIcon} - {this._quizMode ? this.checkIcon : null} - {this._quizMode ? this.redoIcon : null} </div> ); } @@ -762,7 +820,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { height: this._props.PanelWidth() ? undefined : `100%`, pointerEvents: this.layoutDoc._lockedPosition ? 'none' : undefined, borderRadius, - overflow: this.layoutDoc.layout_fitWidth || this._props.fitWidth?.(this.Document) ? 'auto' : undefined, + overflow: this.layoutDoc.layout_fitWidth || this._props.fitWidth?.(this.Document) ? 'auto' : 'hidden', }}> <CollectionFreeFormView ref={this._ffref} @@ -816,6 +874,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { // anchorMenuFlashcard={() => this.getImageDesc()} /> )} + {this._quizMode != quizMode.NONE ? this.checkIcon : null} + {this._quizMode != quizMode.NONE ? this.redoIcon : null} </div> ); } |