diff options
author | alyssaf16 <alyssa_feinberg@brown.edu> | 2024-09-29 15:54:49 -0400 |
---|---|---|
committer | alyssaf16 <alyssa_feinberg@brown.edu> | 2024-09-29 15:54:49 -0400 |
commit | ef2a1037a418ad9fa35d6c60feba914d828d5b84 (patch) | |
tree | 311081f05d6fba0d9d023168b4e11c9e6f7d66f1 /src | |
parent | fa10d872b2a63f5a53461c8fb5473706e78af4e9 (diff) |
clean up
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/collections/CollectionCarouselView.tsx | 16 | ||||
-rw-r--r-- | src/client/views/nodes/AudioBox.tsx | 19 | ||||
-rw-r--r-- | src/client/views/nodes/ComparisonBox.tsx | 55 | ||||
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 49 |
4 files changed, 73 insertions, 66 deletions
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 91a7c6514..04a0320fc 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -254,15 +254,6 @@ export class CollectionCarouselView extends CollectionSubView() { addFlashcard() { const newDoc = Docs.Create.ComparisonDocument('', { _layout_isFlashcard: true, _width: 300, _height: 300 }); this.addDocument?.(newDoc); - // DocUtils.copyDragFactory(newDoc); - // this._props.addDocument?.(); - // newDoc.layout = this.layoutDoc; - // newDoc.data = this.dataDoc; - // Doc.AddDocToList() - // this._props.parent._props.addDocument(); - // this.childLayoutPairs.push({ newDoc.layout, newDoc.data}); - // this._props.addDocument?.(newDoc); - // console.log('HERE'); } @computed get buttons() { @@ -275,11 +266,6 @@ export class CollectionCarouselView extends CollectionSubView() { <FontAwesomeIcon icon="star" color={this.carouselItems[this.carouselIndex]?.[this.starField] ? 'yellow' : 'gray'} size="1x" /> </div> </Tooltip> - {/* <Tooltip title="add new flashcard to pile"> - <div key="add" className="carouselView-add" onClick={this.addFlashcard}> - <FontAwesomeIcon icon="plus" color={this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout[this.starField] ? 'yellow' : 'gray'} size="1x" /> - </div> - </Tooltip> */} </div> <div key="back" className="carouselView-back" onClick={this.goback}> <FontAwesomeIcon icon="chevron-left" size="2x" /> @@ -287,7 +273,7 @@ export class CollectionCarouselView extends CollectionSubView() { <div key="fwd" className="carouselView-fwd" onClick={this.advance}> <FontAwesomeIcon icon="chevron-right" size="2x" /> </div> - {this.practiceMode ? ( + {this.practiceMode == practiceMode.PRACTICE ? ( <div> <Tooltip title="Incorrect. View again later."> <div key="remove" className="carouselView-remove" onClick={e => this.setPracticeVal(e, practiceVal.MISSED)}> diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 63a126aec..8056ced1e 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -300,10 +300,29 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { console.log('RESPONSE: ' + response.data['transcription']); }; + youtubeUpload = async () => { + console.log('Here'); + const audio = { + file: 'Cd2ch4XV84s&t=373s', + }; + const response = await axios.post('http://localhost:105/youtube/', audio, { + headers: { + 'Content-Type': 'application/json', + }, + }); + console.log('RESPONSE: ' + response.data['transcription']); + }; + // context menu specificContextMenu = (): void => { const funcs: ContextMenuProps[] = []; // funcs.push({ description: 'Push info', event: this.pushInfo, icon: 'redo-alt' }); + + funcs.push({ + description: 'Youtube', + event: this.youtubeUpload, // prettier-ignore + icon: 'expand-arrows-alt', + }); funcs.push({ description: (this.layoutDoc.hideAnchors ? "Don't hide" : 'Hide') + ' anchors', event: () => { this.layoutDoc.hideAnchors = !this.layoutDoc.hideAnchors; }, // prettier-ignore diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index a410f4994..df127f0d5 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -246,8 +246,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() remDoc = (doc: Doc, which: string) => { if (this.dataDoc[which] === doc) { this._isEmpty = true; - // this.dataDoc[which] = 'empty'; - console.log('HEREEEE'); this.dataDoc[which] = undefined; return true; } @@ -302,7 +300,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() 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(); setTimeout( action(() => { @@ -384,6 +381,24 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() console.log('RESPONSE: ' + response.data['transcription']); }; + getYouTubeVideoId = (url: string) => { + const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=|\?v=)([^#\&\?]*).*/; + const match = url.match(regExp); + return match && match[2].length === 11 ? match[2] : null; + }; + + youtubeUpload = async () => { + const audio = { + file: this.getYouTubeVideoId(StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text)), + }; + const response = await axios.post('http://localhost:105/youtube/', audio, { + headers: { + 'Content-Type': 'application/json', + }, + }); + return response.data['transcription']; + }; + createFlashcardPile(collectionArr: Doc[], gpt: boolean) { const newCol = Docs.Create.CarouselDocument(collectionArr, { _width: NumCast(this.layoutDoc['_' + this._props.fieldKey + '_width'], 250) + 50, @@ -394,6 +409,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() newCol['x'] = this.layoutDoc['x']; newCol['y'] = NumCast(this.layoutDoc['y']) + 50; newCol.type_collection = 'carousel'; + for (var i = 0; i < collectionArr.length; i++) { + DocCast(collectionArr[i])[DocData].embedContainer = newCol; + } if (gpt) { this._props.DocumentView?.()._props.addDocument?.(newCol); @@ -405,6 +423,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() } } + /** + * Transfers the content of flashcards into a flashcard pile. + */ gptFlashcardPile = async () => { var text = await this.askGPT(GPTCallType.STACK); var senArr = text?.split('Question: '); @@ -441,17 +462,28 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() DocCast(newDoc)[DocData][this.fieldKey + '_1'] = textDoc1; DocCast(newDoc)[DocData][this.fieldKey + '_0'] = Docs.Create.TextDocument(question[0].includes('Answer: ') ? question[0].split('Answer: ')[1] : question[1]); } + collectionArr.push(newDoc); } this.createFlashcardPile(collectionArr, true); }; + /** + * Calls GPT for each flashcard type. + */ askGPT = async (callType: GPTCallType): Promise<string | undefined> => { - const questionText = 'Question: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text); + let 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; this._loading = true; const doc = DocCast(this.dataDoc[this.props.fieldKey + '_0']); + + // if (true) { + // const s = await this.youtubeUpload(); + + // questionText = 'Question: ' + s; + // } + if (callType == GPTCallType.CHATCARD) { if (StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text) === '') { this._loading = false; @@ -461,7 +493,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() } try { console.log(queryText); - const res = await gptAPICall(callType == GPTCallType.QUIZ ? queryText : questionText, callType); + const res = await gptAPICall(questionText, GPTCallType.FLASHCARD); if (!res) { console.error('GPT call failed'); return; @@ -647,7 +679,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() const clearButton = (which: string) => ( <Tooltip title={<div className="dash-tooltip">remove</div>}> <div - // style={{ position: 'relative', top: '0px', left: '10px' }} ref={this._closeRef} className={`clear-button ${which}`} onPointerDown={e => this.closeDown(e, which)} // prevent triggering slider movement in registerSliding @@ -660,18 +691,13 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() const whichDoc = DocCast(this.dataDoc[whichSlot]); const targetDoc = DocCast(whichDoc?.annotationOn, whichDoc); const layoutString = targetDoc ? '' : this.testForTextFields(whichSlot); - // whichDoc['backgroundColor'] = this.layoutDoc['backgroundColor']; return targetDoc || layoutString ? ( - // <MathJaxContext config={this.mathJaxConfig}> - // <MathJax> <> <DocumentView // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} fitWidth={undefined} - NativeHeight={returnZero} - NativeWidth={returnZero} ignoreUsePath={layoutString ? true : undefined} renderDepth={this.props.renderDepth + 1} LayoutTemplateString={layoutString} @@ -679,6 +705,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() containerViewPath={this._props.docViewPath} moveDocument={whichSlot.endsWith('1') ? this.moveDoc1 : this.moveDoc2} removeDocument={whichSlot.endsWith('1') ? this.remDoc1 : this.remDoc2} + NativeWidth={this.layoutWidth} + NativeHeight={this.layoutHeight} isContentActive={() => this.childActive} isDocumentActive={returnFalse} dontSelect={returnTrue} @@ -687,9 +715,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() hideLinkButton pointerEvents={this.childActive ? undefined : returnNone} /> - {/* </MathJax> */} - {/* <div style={{ position: 'absolute', top: '-5px', left: '2px' }}>{layoutString ? null : clearButton(whichSlot)}</div> */} - {/* </MathJaxContext> // placeholder image if doc is missingleft: `${NumCast(this.layoutDoc.width, 200) - 33}px` */} </> ) : ( <div className="placeholder"> @@ -708,7 +733,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() }} ref={ele => this.createDropTarget(ele, which, index)}> {!this._isEmpty ? displayDoc(which) : null} - {/* {this.dataDoc[this.fieldKey + '_0'] !== 'empty' ? displayDoc(which) : null} */} </div> ); @@ -716,7 +740,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>() const side = this.frontSide ? 1 : 0; // add text box to each side when comparison box is first created - // (!this.dataDoc[this.fieldKey + '_0'] && this.dataDoc[this._props.fieldKey + '_0'] !== 'empty') if (!this.dataDoc[this.fieldKey + '_0'] && !this._isEmpty) { const dataSplit = StrCast(this.dataDoc.data).includes('Keyword: ') ? StrCast(this.dataDoc.data).split('Keyword: ') : StrCast(this.dataDoc.data).split('Answer: '); const newDoc = Docs.Create.TextDocument(dataSplit[1]); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index ed79888ae..45301247b 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -168,11 +168,12 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { Object.values(this._disposers).forEach(disposer => disposer?.()); } + /** + * Find images from the unsplash api to add to flashcards. + */ fetchImages = async () => { try { const { data } = await axios.get(`${API_URL}?query=${this._searchInput}&page=1&per_page=${1}&client_id=${process.env.VITE_API_KEY}`); - console.log('data', data); - console.log(data.results); const imageSnapshot = Docs.Create.ImageDocument(data.results[0].urls.small, { _nativeWidth: Doc.NativeWidth(this.layoutDoc), _nativeHeight: Doc.NativeHeight(this.layoutDoc), @@ -326,8 +327,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { if (ctx) { this._imageRef && ctx.drawImage(this._imageRef, NumCast(this._marqueeref.current?.left) * scaling, NumCast(this._marqueeref.current?.top) * scaling, w, h, 0, 0, w, h); } - // canvas.style.zIndex = '2000000'; - // document.body.appendChild(canvas); const blob = await ImageUtility.canvasToBlob(canvas); return ImageBox.selectUrlToBase64(blob); }; @@ -350,7 +349,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { Doc.SetNativeHeight(imageSnapshot[DocData], Doc.NativeHeight(this.layoutDoc)); this._props.addDocument?.(imageSnapshot); DocUtils.MakeLink(imageSnapshot, this.getAnchor(true), { link_relationship: 'video snapshot' }); - // link && (DocCast(link.link_anchor_2)[DocData].timecodeToHide = NumCast(DocCast(link.link_anchor_2).timecodeToShow) + 3); // do we need to set an end time? should default to +0.1 setTimeout(() => downX !== undefined && downY !== undefined && DocumentView.getFirstDocumentView(imageSnapshot)?.startDragging(downX, downY, dropActionType.move, true)); }; @@ -371,7 +369,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { pushInfo = async (quiz: quizMode, i?: string) => { this._quizMode = quiz; this._loading = true; - console.log('JHSDKFJHKSDJFHKSJDHFKJSDHFKJHSDKF'); const img = { file: i ? i : this.paths[0], @@ -383,10 +380,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { 'Content-Type': 'application/json', }, }); - - console.log('RESPONSE:'); - console.log(response.data['boxes']); - console.log(response.data['text']); if (response.data['boxes'].length != 0) { this.createBoxes(response.data['boxes'], response.data['text']); } else { @@ -394,6 +387,11 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } }; + /** + * Creates label boxes over text on the image to be filled in. + * @param boxes + * @param texts + */ 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']); @@ -405,17 +403,13 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const newCol = Docs.Create.LabelDocument({ _width: width, - //width * NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']), _height: height, - //height * NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']), _layout_fitWidth: true, title: '', - // _layout_autoHeight: true, }); 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; @@ -428,12 +422,14 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } }; + /** + * Create flashcards from an image. + */ getImageDesc = async () => { this._loading = true; try { const hrefBase64 = await this.createCanvas(); const response = await gptImageLabel(hrefBase64, 'Make flashcards out of this image with each question and answer labeled as "question" and "answer". Do not label each flashcard and do not include asterisks: '); - console.log(response); AnchorMenu.Instance.transferToFlashcard(response, NumCast(this.layoutDoc['x']), NumCast(this.layoutDoc['y'])); } catch (error) { console.log('Error'); @@ -535,15 +531,16 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } }; + /** + * Check whether the contents of the label boxes on an image are correct. + */ check = () => { this._loading = true; this._quizBoxes.forEach(async doc => { const input = StrCast(doc[DocData].title); - console.log('INP: ' + StrCast(input) + '; DOC: ' + StrCast(doc.quiz)); 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: ' + @@ -553,7 +550,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { '. 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?.replace(/UserAnswer/g, "user's answer").replace(/Rubric/g, 'rubric'); doc.backgroundColor = '#' + hexSent.hexNumber; } else { @@ -561,7 +557,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { doc.backgroundColor = match ? '#11c249' : '#eb2d2d'; } doc.showQuiz = true; - // console.log(this.compareWords(input, StrCast(doc.quiz)) ? 'Match' : 'No Match'); }); this._loading = false; }; @@ -577,8 +572,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { exitQuizMode = () => { this._quizMode = quizMode.NONE; this._quizBoxes.forEach(doc => { - // this._props.removeDocument?.(DocCast(doc)); - // this._props.DocumentView?.()._props.removeDocument?.(doc); this.removeDocument?.(doc); }); this._quizBoxes = []; @@ -595,7 +588,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { if (field) { const funcs: ContextMenuProps[] = []; const quizes: ContextMenuProps[] = []; - // funcs.push({ description: 'Create ai flashcards', event: () => this.getImageDesc(), icon: 'id-card' }); quizes.push({ description: 'Smart Check', event: this._quizMode == quizMode.NONE ? () => this.pushInfo(quizMode.SMART) : this.exitQuizMode, @@ -606,19 +598,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { 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' }); funcs.push({ description: 'Rotate Clockwise 90', event: this.rotate, icon: 'redo-alt' }); funcs.push({ description: `Show ${this.layoutDoc._showFullRes ? 'Dynamic Res' : 'Full Res'}`, event: this.resolution, icon: 'expand' }); funcs.push({ description: 'Set Native Pixel Size', event: this.setNativeSize, icon: 'expand-arrows-alt' }); |