diff options
| author | bobzel <zzzman@gmail.com> | 2025-02-26 18:31:13 -0500 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2025-02-26 18:31:13 -0500 |
| commit | 2e03c9bf1af2796faef8b81b326b48f4cd136d95 (patch) | |
| tree | 1a368765f65dfbb123de1a2b8b0014b7e47279a7 /src/client/views/pdf/GPTPopup | |
| parent | 2d73f20b38424119c9419b7b85799eb3aff6c17f (diff) | |
fixed toggling number dropdown. Added firefly to gpt popup menu.
Diffstat (limited to 'src/client/views/pdf/GPTPopup')
| -rw-r--r-- | src/client/views/pdf/GPTPopup/GPTPopup.tsx | 90 |
1 files changed, 65 insertions, 25 deletions
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index 2cf39bec4..efddfb841 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -3,6 +3,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { AiOutlineSend } from 'react-icons/ai'; import { CgCornerUpLeft } from 'react-icons/cg'; import ReactLoading from 'react-loading'; import { TypeAnimation } from 'react-type-animation'; @@ -16,14 +17,15 @@ import { Docs } from '../../../documents/Documents'; import { SettingsManager } from '../../../util/SettingsManager'; import { SnappingManager } from '../../../util/SnappingManager'; import { undoable } from '../../../util/UndoManager'; +import { DictationButton } from '../../DictationButton'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { TagItem } from '../../TagsView'; import { ChatSortField, docSortings } from '../../collections/CollectionSubView'; import { DocumentView } from '../../nodes/DocumentView'; +import { SmartDrawHandler } from '../../smartdraw/SmartDrawHandler'; import { AnchorMenu } from '../AnchorMenu'; import './GPTPopup.scss'; -import { DictationButton } from '../../DictationButton'; -import { AiOutlineSend } from 'react-icons/ai'; +import { FireflyImageDimensions } from '../../smartdraw/FireflyConstants'; export enum GPTPopupMode { SUMMARY, // summary of seleted document text @@ -32,6 +34,7 @@ export enum GPTPopupMode { GPT_MENU, // menu for choosing type of prompts user will provide USER_PROMPT, // user prompts for sorting,filtering and asking about docs QUIZ_RESPONSE, // user definitions or explanations to be evaluated by GPT + FIREFLY, // firefly image generation } @observer @@ -93,6 +96,7 @@ export class GPTPopup extends ObservableReactComponent<object> { } @observable private _conversationArray: string[] = ['Hi! In this pop up, you can ask ChatGPT questions about your documents and filter / sort them. ']; + @observable private _fireflyArray: string[] = ['Hi! In this pop up, you can ask Firefly to create images. ']; @observable private _chatEnabled: boolean = false; @action private setChatEnabled = (start: boolean) => (this._chatEnabled = start); @observable private _gptProcessing: boolean = false; @@ -197,6 +201,21 @@ export class GPTPopup extends ObservableReactComponent<object> { .catch(err => console.error('GPT call failed', err)) )) // prettier-ignore + generateFireflyImage = (imgDesc: string) => { + // if (this._fireflyRefStrength) { + // DrawingFillHandler.drawingToImage(this.props.Document, this._fireflyRefStrength, this._regenInput || StrCast(this.Document.title), this.Document)?.then( + // action(() => { + // this._regenerateLoading = false; + // }) + // ); + // } else∂ + return SmartDrawHandler.CreateWithFirefly(imgDesc, FireflyImageDimensions.Square, 0) + .then(action(() => (this._userPrompt = ''))) + .catch(e => { + alert(e); + return undefined; + }); + }; /** * Generates a response to the user's question about the docs in the collection. * The type of response depends on the chat's analysis of the type of their question @@ -339,6 +358,21 @@ export class GPTPopup extends ObservableReactComponent<object> { gptMenu = () => ( <div className="btns-wrapper-gpt"> <Button + tooltip="Ask Firefly to create images" + text="Ask Firefly" + onClick={() => this.setMode(GPTPopupMode.FIREFLY)} + color={StrCast(Doc.UserDoc().userVariantColor)} + type={Type.TERT} + style={{ + width: '100%', + height: '40%', + textAlign: 'center', + color: '#ffffff', + fontSize: '16px', + marginBottom: '10px', + }} + /> + <Button tooltip="Ask GPT to sort, tag, define, or filter your Docs!" text="Ask GPT" onClick={() => this.setMode(GPTPopupMode.USER_PROMPT)} @@ -365,32 +399,37 @@ export class GPTPopup extends ObservableReactComponent<object> { type={Type.TERT} style={{ width: '100%', + height: '40%', textAlign: 'center', color: '#ffffff', fontSize: '16px', - height: '40%', }} /> </div> ); - callGpt = (isUserPrompt: boolean) => { + callGpt = action((mode: GPTPopupMode) => { this.setGptProcessing(true); - if (isUserPrompt) { - this._conversationArray.push(this._userPrompt); - return this.generateUserPromptResponse(this._userPrompt).then(action(() => (this._userPrompt = ''))); + switch (mode) { + case GPTPopupMode.FIREFLY: + this._fireflyArray.push(this._userPrompt); + return this.generateFireflyImage(this._userPrompt).then(action(() => (this._userPrompt = ''))); + case GPTPopupMode.USER_PROMPT: + this._conversationArray.push(this._userPrompt); + return this.generateUserPromptResponse(this._userPrompt).then(action(() => (this._userPrompt = ''))); + case GPTPopupMode.QUIZ_RESPONSE: + this._conversationArray.push(this._quizAnswer); + return this.generateQuizAnswerAnalysis(DocumentView.SelectedDocs().lastElement(), this._quizAnswer).then(action(() => (this._quizAnswer = ''))); } - this._conversationArray.push(this._quizAnswer); - return this.generateQuizAnswerAnalysis(DocumentView.SelectedDocs().lastElement(), this._quizAnswer).then(action(() => (this._quizAnswer = ''))); - }; + }); @action - handleKeyPress = async (e: React.KeyboardEvent, isUserPrompt: boolean) => { + handleKeyPress = async (e: React.KeyboardEvent, mode: GPTPopupMode) => { this._askDictation?.stopDictation(); if (e.key === 'Enter') { e.stopPropagation(); - this.callGpt(isUserPrompt).then(() => { + this.callGpt(mode)?.then(() => { this.setGptProcessing(false); this.scrollToBottom(); }); @@ -401,7 +440,7 @@ export class GPTPopup extends ObservableReactComponent<object> { <div className="btns-wrapper-gpt"> <div className="chat-wrapper"> <div className="chat-bubbles"> - {this._conversationArray.map((message, index) => ( + {(this._mode === GPTPopupMode.FIREFLY ? this._fireflyArray : this._conversationArray).map((message, index) => ( <div key={index} className={`chat-bubble ${index % 2 === 1 ? 'user-message' : 'chat-message'}`}> {message} </div> @@ -414,21 +453,21 @@ export class GPTPopup extends ObservableReactComponent<object> { </div> ); - promptBox = (isUserPrompt: boolean) => ( + promptBox = (heading: string, value: string, onChange: (e: string) => string, placeholder: string) => ( <> <div className="gptPopup-sortBox"> - {this.heading(isUserPrompt ? 'ASK' : 'QUIZ')} + {this.heading(heading)} {this.gptUserInput()} </div> <div className="inputWrapper"> <input className="searchBox-input" - value={isUserPrompt ? this._userPrompt : this._quizAnswer} // Controlled input + value={value} // Controlled input autoComplete="off" - onChange={e => (isUserPrompt ? this.setUserPrompt : this.setQuizAnswer)(e.target.value)} - onKeyDown={e => this.handleKeyPress(e, isUserPrompt)} + onChange={e => onChange(e.target.value)} + onKeyDown={e => this.handleKeyPress(e, this._mode)} type="text" - placeholder={`${isUserPrompt ? 'Have ChatGPT sort, tag, define, or filter your documents for you!' : 'Describe/answer the selected document!'}`} + placeholder={placeholder} /> <Button // text="Send" @@ -436,9 +475,9 @@ export class GPTPopup extends ObservableReactComponent<object> { icon={<AiOutlineSend />} iconPlacement="right" color={SnappingManager.userVariantColor} - onClick={() => this.callGpt(isUserPrompt)} + onClick={() => this.callGpt(this._mode)} /> - <DictationButton ref={r => (this._askDictation = r)} setInput={isUserPrompt ? this.setUserPrompt : this.setQuizAnswer} /> + <DictationButton ref={r => (this._askDictation = r)} setInput={onChange} /> </div> </> ); @@ -461,7 +500,7 @@ export class GPTPopup extends ObservableReactComponent<object> { <img key={rawSrc[0]} src={rawSrc[0]} width={150} height={150} alt="dalle generation" /> </div> </div> - <div className="btn-container"> + <div key={rawSrc[0] + i + 'btn'} className="btn-container"> <Button text="Save Image" onClick={() => this.transferToImage(rawSrc[1])} color={StrCast(Doc.UserDoc().userColor)} type={Type.TERT} /> </div> </> @@ -599,7 +638,7 @@ export class GPTPopup extends ObservableReactComponent<object> { color={Doc.hasDocFilter(this._collectionContext, 'tags', GPTPopup.ChatTag) ? 'red' : 'transparent'} onClick={() => this._collectionContext && Doc.setDocFilter(this._collectionContext, 'tags', GPTPopup.ChatTag, 'remove')} /> - {(this._mode === GPTPopupMode.USER_PROMPT || this._mode === GPTPopupMode.QUIZ_RESPONSE) && ( + {[GPTPopupMode.USER_PROMPT, GPTPopupMode.QUIZ_RESPONSE, GPTPopupMode.FIREFLY].includes(this._mode) && ( <IconButton color={StrCast(SettingsManager.userVariantColor)} tooltip="back" icon={<CgCornerUpLeft size="16px" />} onClick={() => (this._mode = GPTPopupMode.GPT_MENU)} /> )} </> @@ -613,8 +652,9 @@ export class GPTPopup extends ObservableReactComponent<object> { {(() => { //prettier-ignore switch (this._mode) { - case GPTPopupMode.USER_PROMPT: - case GPTPopupMode.QUIZ_RESPONSE: return this.promptBox(this._mode === GPTPopupMode.USER_PROMPT); + case GPTPopupMode.USER_PROMPT: return this.promptBox("ASK", this._userPrompt, this.setUserPrompt, 'Ask GPT to sort, tag, define, or filter your documents for you!'); + case GPTPopupMode.FIREFLY: return this.promptBox("CREATE", this._userPrompt, this.setUserPrompt, 'Ask Firefly to generate images'); + case GPTPopupMode.QUIZ_RESPONSE: return this.promptBox("QUIZ", this._quizAnswer, this.setQuizAnswer, 'Describe/answer the selected document!'); case GPTPopupMode.GPT_MENU: return this.menuBox(); case GPTPopupMode.SUMMARY: return this.summaryBox(); case GPTPopupMode.DATA: return this.dataAnalysisBox(); |
