aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/ImageBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/ImageBox.tsx')
-rw-r--r--src/client/views/nodes/ImageBox.tsx98
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>
);
}