diff options
author | alyssaf16 <alyssa_feinberg@brown.edu> | 2024-07-24 15:23:46 -0400 |
---|---|---|
committer | alyssaf16 <alyssa_feinberg@brown.edu> | 2024-07-24 15:23:46 -0400 |
commit | 54c5ef5774b001e8acd4feb2e44e010d050cc687 (patch) | |
tree | e763c28edbb6fff2482d3e0641dab950d06cebcd /src | |
parent | e82c95293bb2d9db32fc9901f57f1997b74597c1 (diff) |
drag boxes
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 45 | ||||
-rw-r--r-- | src/client/views/nodes/LabelBox.tsx | 17 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 7 | ||||
-rw-r--r-- | src/client/views/pdf/AnchorMenu.tsx | 2 |
4 files changed, 45 insertions, 26 deletions
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 32b9e20a4..22e242f77 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -250,6 +250,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this.dataDoc._freeform_panX_min = this.dataDoc._freeform_panX_min ? nw * NumCast(this.dataDoc._freeform_panX_min) : undefined; this.dataDoc._freeform_panY_max = this.dataDoc._freeform_panY_max ? nw * NumCast(this.dataDoc._freeform_panY_max) : undefined; this.dataDoc._freeform_panY_min = this.dataDoc._freeform_panY_min ? nw * NumCast(this.dataDoc._freeform_panY_min) : undefined; + return nw; }); @undoBatch rotate = action(() => { @@ -365,13 +366,13 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } }; - pushInfo = async (quiz: quizMode) => { + pushInfo = async (quiz: quizMode, i?: string) => { this._quizMode = quiz; this._loading = true; console.log('JHSDKFJHKSDJFHKSJDHFKJSDHFKJHSDKF'); const img = { - file: this.paths[0], + file: i ? i : this.paths[0], smart: quiz, }; const response = await axios.post('http://localhost:105/labels/', img, { @@ -387,6 +388,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { }; createBoxes = (boxes: [[[number, number]]], texts: [string]) => { + const nscale = NumCast(this._props.PanelWidth()) * NumCast(this.layoutDoc._freeform_scale, 1); + const nw = nscale / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']); for (var i = 0; i < boxes.length; i++) { const coords = boxes[i] ? boxes[i] : []; const width = coords[1][0] - coords[0][0]; @@ -401,10 +404,11 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { _layout_fitWidth: true, // _layout_autoHeight: true, }); - newCol.x = coords[0][0]; - newCol.y = coords[0][1]; - // newCol.x = x * NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']); - // newCol.y = y * NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']); + const scaling = 1 / (this._props.NativeDimScaling?.() || 1); + newCol.x = coords[0][0] + NumCast(this._marqueeref.current?.left) * scaling; + newCol.y = coords[0][1] + NumCast(this._marqueeref.current?.top) * scaling; + // newCol[DocData].text_fontSize = height + 'px'; + newCol.zIndex = 1000; newCol.forceActive = true; newCol.quiz = text; @@ -414,22 +418,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this._loading = false; } }; - // static imageUrlToBase64 = async (imageUrl: string): Promise<string> => { - // try { - // const response = await fetch(imageUrl); - // const blob = await response.blob(); - - // return new Promise((resolve, reject) => { - // const reader = new FileReader(); - // reader.readAsDataURL(blob); - // reader.onloadend = () => resolve(reader.result as string); - // reader.onerror = error => reject(error); - // }); - // } catch (error) { - // console.error('Error:', error); - // throw error; - // } - // }; getImageDesc = async () => { this._loading = true; @@ -444,6 +432,16 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this._loading = false; }; + makeLabels = async () => { + this._loading = true; + try { + const hrefBase64 = await this.createCanvas(); + this.pushInfo(quizMode.NORMAL, hrefBase64); + } catch (error) { + console.log('Error'); + } + }; + levenshteinDistance = (a: string, b: string) => { const an = a.length; const bn = b.length; @@ -540,7 +538,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const response = await gptAPICall(queryText, GPTCallType.QUIZ); const hexSent = this.extractHexAndSentences(response); console.log(hexSent.hexNumber); - doc.quiz = hexSent.sentences; + doc.quiz = hexSent.sentences?.replace(/UserAnswer/g, "user's answer").replace(/Rubric/g, 'rubric'); doc.backgroundColor = '#' + hexSent.hexNumber; } else { const match = this.compareWords(input, StrCast(doc.quiz)); @@ -789,6 +787,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this._getAnchor = AnchorMenu.Instance?.GetAnchor; AnchorMenu.Instance.gptFlashcards = this.getImageDesc; AnchorMenu.Instance.addToCollection = this._props.DocumentView?.()._props.addDocument; + AnchorMenu.Instance.makeLabels = this.makeLabels; AnchorMenu.Instance.marqueeWidth = this._marqueeref.current?.Width ?? 0; AnchorMenu.Instance.marqueeHeight = this._marqueeref.current?.Height ?? 0; this._marqueeref.current?.onTerminateSelection(); diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index f80ff5f94..9c86fafcc 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -119,7 +119,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() { singleLine: boolean; whiteSpace: string; } => { - const singleLine = BoolCast(this.layoutDoc._singleLine, true); + const singleLine = BoolCast(this.layoutDoc._singleLine, true); // bcz: this is ugly--- should default ot false?? const params = { rotateText: null, fontSizeFactor: 1, @@ -150,6 +150,8 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() { BigText(r, params); return params; }; + _divRef: HTMLDivElement | null = null; + // (!missingParams || !missingParams.length ? "" : "(" + missingParams.map(m => m + ":").join(" ") + ")") render() { const boxParams = this.fitTextToBox(null); // this causes mobx to trigger re-render when data changes @@ -172,6 +174,13 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() { style={{ boxShadow: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BoxShadow) }}> <div className="labelBox-mainButton" + contentEditable + ref={r => (this._divRef = r)} + onKeyDown={e => e.stopPropagation()} + onKeyUp={e => { + e.stopPropagation(); + e.key === 'Enter' && (this.dataDoc.text = this._divRef?.textContent ?? ''); + }} style={{ backgroundColor: this.hoverColor, fontSize: StrCast(this.layoutDoc._text_fontSize), @@ -187,7 +196,11 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() { height: this._props.PanelHeight(), whiteSpace: 'singleLine' in boxParams && boxParams.singleLine ? 'pre' : 'pre-wrap', }}> - <span style={{ width: 'singleLine' in boxParams ? '' : '100%' }} ref={action((r: any) => this.fitTextToBox(r))}> + <span + style={{ width: 'singleLine' in boxParams ? '' : '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/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index b00437cf2..1aeb90286 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -2095,7 +2095,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB @computed get answerIcon() { return ( - <Tooltip title={<div className="answer-tooltip">{StrCast(this.Document.quiz)}</div>}> + <Tooltip + title={ + <div className="answer-tooltip" style={{ minWidth: '200px' }}> + {StrCast(this.Document.quiz)} + </div> + }> <div className="answer-tool-tip"> <FontAwesomeIcon className="q-icon" icon="circle" color="white" /> <FontAwesomeIcon className="answer-icon" icon="question" /> diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index 31941a299..9fefaa26d 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -72,6 +72,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> { public ShowTargetTrail: () => void = unimplementedFunction; public IsTargetToggler: () => boolean = returnFalse; public gptFlashcards: () => void = unimplementedFunction; + public makeLabels: () => void = unimplementedFunction; public marqueeWidth = 0; public marqueeHeight = 0; public get Active() { @@ -247,6 +248,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> { )} {/* Adds a create flashcards option to the anchor menu, which calls the gptFlashcard method. */} <IconButton tooltip="Create flashcards" onPointerDown={this.gptFlashcards} icon={<FontAwesomeIcon icon="id-card" size="lg" />} color={SettingsManager.userColor} /> + <IconButton tooltip="Create labels" onPointerDown={this.makeLabels} icon={<FontAwesomeIcon icon="id-card" size="lg" />} color={SettingsManager.userColor} /> {AnchorMenu.Instance.OnAudio === unimplementedFunction ? null : ( <IconButton tooltip="Click to Record Annotation" // |