aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/pdf/GPTPopup
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2025-02-26 18:31:13 -0500
committerbobzel <zzzman@gmail.com>2025-02-26 18:31:13 -0500
commit2e03c9bf1af2796faef8b81b326b48f4cd136d95 (patch)
tree1a368765f65dfbb123de1a2b8b0014b7e47279a7 /src/client/views/pdf/GPTPopup
parent2d73f20b38424119c9419b7b85799eb3aff6c17f (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.tsx90
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();