aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2025-02-13 23:50:03 -0500
committerbobzel <zzzman@gmail.com>2025-02-13 23:50:03 -0500
commit6f60b3ccf18c35c3faada44ef7187f4ae9d50ab1 (patch)
tree8865c3b510289c9c388f69c8035f71e01250b385
parent3f6a168b2916ccac707cf5ea1e4ef898a470d7d1 (diff)
from last
-rw-r--r--src/client/views/global/globalScripts.ts2
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx3
-rw-r--r--src/client/views/pdf/GPTPopup/GPTPopup.tsx119
3 files changed, 59 insertions, 65 deletions
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 029c4dbc7..790ebeabe 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -230,7 +230,7 @@ ScriptingGlobals.add(function showFreeform(
GPTPopup.Instance.setVisible(false);
} else {
GPTPopup.Instance.setVisible(true);
- GPTPopup.Instance.setMode(GPTPopupMode.CARD);
+ GPTPopup.Instance.setMode(GPTPopupMode.GPT_MENU);
}
},
}],
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 17b9bce47..2e14fb1d9 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1065,8 +1065,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
GPTPopup.Instance?.setTextAnchor(this.getAnchor(false));
GPTPopup.Instance?.setImgTargetDoc(this.Document);
GPTPopup.Instance.addToCollection = this._props.addDocument;
- GPTPopup.Instance.setImgDesc((this.dataDoc.text as RichTextField)?.Text);
- GPTPopup.Instance.generateImage();
+ GPTPopup.Instance.generateImage((this.dataDoc.text as RichTextField)?.Text);
};
breakupDictation = () => {
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index 691c24792..4457bde91 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -21,14 +21,12 @@ import { AnchorMenu } from '../AnchorMenu';
import './GPTPopup.scss';
export enum GPTPopupMode {
- SUMMARY,
- EDIT,
- IMAGE,
- FLASHCARD,
+ SUMMARY, // summary of seleted document text
+ IMAGE, // generate image from image description
DATA,
- CARD,
- SORT,
- QUIZ,
+ 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
}
export enum GPTQuizType {
@@ -50,10 +48,9 @@ export class GPTPopup extends ObservableReactComponent<object> {
private _dataJson: string = '';
private _sortDesc: string = '';
private _sidebarFieldKey: string = '';
- private _imgDesc: string = '';
private _selectedText: string = '';
+ private _imgDesc: string = '';
- public setImgDesc = (text: string) => (this._imgDesc = text);
public setSidebarFieldKey = (id: string) => (this._sidebarFieldKey = id);
public setSortDesc = (t: string) => (this._sortDesc = t);
public setImgTargetDoc = (anchor: Doc) => (this._imgTargetDoc = anchor);
@@ -89,8 +86,8 @@ export class GPTPopup extends ObservableReactComponent<object> {
@action public setMode = (mode: GPTPopupMode) => (this._mode = mode);
@observable private _collectionContext: Doc | undefined = undefined;
@action setCollectionContext = (doc: Doc | undefined) => (this._collectionContext = doc);
- @observable private _sortPrompt: string = '';
- @action setSortPrompt = (e: React.ChangeEvent<HTMLInputElement>) => (this._sortPrompt = e.target.value);
+ @observable private _userPrompt: string = '';
+ @action setUserPrompt = (e: React.ChangeEvent<HTMLInputElement>) => (this._userPrompt = e.target.value);
@observable private _quizAnswer: string = '';
@action setQuizAnswer = (e: React.ChangeEvent<HTMLInputElement>) => (this._quizAnswer = e.target.value);
@observable private _stopAnimatingResponse: boolean = false;
@@ -149,7 +146,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
* Generates a response to the user's question depending on the type of their question
* @param userPrompt the user's input that chat will respond to
*/
- generateQueryResponse = (userPrompt: string) =>
+ generateUserPromptResponse = (userPrompt: string) =>
(this._regenerateCallback ?? Promise.resolve)().then(() =>
gptAPICall(userPrompt, GPTCallType.TYPE).then(questionType =>
(() => {
@@ -176,26 +173,24 @@ export class GPTPopup extends ObservableReactComponent<object> {
/**
* Generates a Dalle image and uploads it to the server.
*/
- generateImage = () => {
- if (this._imgDesc !== '') {
- this.setImgUrls([]);
- this.setMode(GPTPopupMode.IMAGE);
- this.setVisible(true);
- this.setGptProcessing(true);
-
- return gptImageCall(this._imgDesc)
- .then(imageUrls =>
- imageUrls?.[0]
- ? Networking.PostToServer('/uploadRemoteImage', { sources: [imageUrls[0]] }).then(res => {
- const source = ClientUtils.prepend(res[0].accessPaths.agnostic.client);
- return this.setImgUrls([[imageUrls[0]!, source]]);
- })
- : undefined
- )
- .catch(err => console.error(err))
- .finally(() => this.setGptProcessing(false));
- }
- return undefined;
+ generateImage = (imgDesc: string) => {
+ this.setImgUrls([]);
+ this.setMode(GPTPopupMode.IMAGE);
+ this.setVisible(true);
+ this.setGptProcessing(true);
+ this._imgDesc = imgDesc;
+
+ return gptImageCall(imgDesc)
+ .then(imageUrls =>
+ imageUrls?.[0]
+ ? Networking.PostToServer('/uploadRemoteImage', { sources: [imageUrls[0]] }).then(res => {
+ const source = ClientUtils.prepend(res[0].accessPaths.agnostic.client);
+ return this.setImgUrls([[imageUrls[0]!, source]]);
+ })
+ : undefined
+ )
+ .catch(err => console.error(err))
+ .finally(() => this.setGptProcessing(false));
};
/**
@@ -203,12 +198,12 @@ export class GPTPopup extends ObservableReactComponent<object> {
*
* @param text the text to summarizz
*/
- generateSummary = (text?: string) => {
- this._selectedText = text ?? this._selectedText;
+ generateSummary = (text: string) => {
+ this._selectedText = text;
this.setVisible(true);
this.setMode(GPTPopupMode.SUMMARY);
this.setGptProcessing(true);
- return gptAPICall(this._selectedText, GPTCallType.SUMMARY)
+ return gptAPICall(text, GPTCallType.SUMMARY)
.then(res => this.setResponseText(res || 'Something went wrong.'))
.catch(err => console.error(err))
.finally(() => this.setGptProcessing(false));
@@ -286,12 +281,12 @@ export class GPTPopup extends ObservableReactComponent<object> {
scrollToBottom = () => setTimeout(() => this._messagesEndRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' }), 50);
- cardMenu = () => (
+ gptMenu = () => (
<div className="btns-wrapper-gpt">
<Button
- tooltip="Have ChatGPT sort, tag, define, or filter your cards for you!"
+ tooltip="Have ChatGPT sort, tag, define, or filter your documents for you!"
text="Modify/Sort Cards!"
- onClick={() => this.setMode(GPTPopupMode.SORT)}
+ onClick={() => this.setMode(GPTPopupMode.USER_PROMPT)}
color={StrCast(Doc.UserDoc().userVariantColor)}
type={Type.TERT}
style={{
@@ -308,7 +303,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
text="Quiz Cards!"
onClick={() => {
this._conversationArray = ['Define the selected card!'];
- this.setMode(GPTPopupMode.QUIZ);
+ this.setMode(GPTPopupMode.QUIZ_RESPONSE);
this.onQuizRandom?.();
}}
color={StrCast(Doc.UserDoc().userVariantColor)}
@@ -325,14 +320,14 @@ export class GPTPopup extends ObservableReactComponent<object> {
);
@action
- handleKeyPress = async (e: React.KeyboardEvent, isSort: boolean) => {
+ handleKeyPress = async (e: React.KeyboardEvent, isUserPrompt: boolean) => {
if (e.key === 'Enter') {
e.stopPropagation();
this.setGptProcessing(true);
- if (isSort) {
- this._conversationArray.push(this._sortPrompt);
- await this.generateQueryResponse(this._sortPrompt).then(action(() => (this._sortPrompt = '')));
+ if (isUserPrompt) {
+ this._conversationArray.push(this._userPrompt);
+ await this.generateUserPromptResponse(this._userPrompt).then(action(() => (this._userPrompt = '')));
} else {
this._conversationArray.push(this._quizAnswer);
await this.generateQuizAnswerAnalysis(DocumentView.SelectedDocs().lastElement(), this._quizAnswer).then(action(() => (this._quizAnswer = '')));
@@ -343,7 +338,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
}
};
- cardActual = (isSort: boolean) => (
+ gptUserInput = (isUserPrompt: boolean) => (
<div className="btns-wrapper-gpt">
<div className="chat-wrapper">
<div className="chat-bubbles">
@@ -352,7 +347,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
{message}
</div>
))}
- {this._gptProcessing && <div className={`chat-bubble chat-message`}>...</div>}
+ {this._gptProcessing && <div className="chat-bubble chat-message">...</div>}
</div>
<div ref={this._messagesEndRef} style={{ height: '100px' }} />
@@ -361,21 +356,21 @@ export class GPTPopup extends ObservableReactComponent<object> {
<input
className="searchBox-input"
defaultValue=""
- value={isSort ? this._sortPrompt : this._quizAnswer} // Controlled input
+ value={isUserPrompt ? this._userPrompt : this._quizAnswer} // Controlled input
autoComplete="off"
- onChange={isSort ? this.setSortPrompt : this.setQuizAnswer}
- onKeyDown={e => this.handleKeyPress(e, isSort)}
+ onChange={isUserPrompt ? this.setUserPrompt : this.setQuizAnswer}
+ onKeyDown={e => this.handleKeyPress(e, isUserPrompt)}
type="text"
- placeholder={`${isSort ? 'Have ChatGPT sort, tag, define, or filter your cards for you!' : 'Define the selected card!'}`}
+ placeholder={`${isUserPrompt ? 'Have ChatGPT sort, tag, define, or filter your documents for you!' : 'Describe/answer the selected document!'}`}
/>
</div>
</div>
);
- sortBox = (isSort: boolean) => (
+ promptBox = (isUserPrompt: boolean) => (
<div className="gptPopup-sortBox" style={{ height: '80%' }}>
- {this.heading(isSort ? 'SORTING' : 'QUIZ')}
- {this._mode === GPTPopupMode.CARD ? this.cardMenu() : this.cardActual(isSort)}
+ {this.heading(isUserPrompt ? 'SORTING' : 'QUIZ')}
+ {this._mode === GPTPopupMode.GPT_MENU ? this.gptMenu() : this.gptUserInput(isUserPrompt)}
</div>
);
@@ -394,7 +389,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
</div>
))}
</div>
- {this._gptProcessing ? null : <IconButton tooltip="Generate Again" onClick={this.generateImage} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(Doc.UserDoc().userVariantColor)} />}
+ {this._gptProcessing ? null : <IconButton tooltip="Generate Again" onClick={() => this.generateImage(this._imgDesc)} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(Doc.UserDoc().userVariantColor)} />}
</div>
);
@@ -510,8 +505,8 @@ export class GPTPopup extends ObservableReactComponent<object> {
<ReactLoading type="spin" color="#bcbcbc" width={14} height={14} />
) : (
<>
- {(this._mode === GPTPopupMode.SORT || this._mode === GPTPopupMode.QUIZ) && (
- <IconButton color={StrCast(SettingsManager.userVariantColor)} tooltip="back" icon={<CgCornerUpLeft size="16px" />} onClick={() => (this._mode = GPTPopupMode.CARD)} style={{ right: '50px', position: 'absolute' }} />
+ {(this._mode === GPTPopupMode.USER_PROMPT || this._mode === GPTPopupMode.QUIZ_RESPONSE) && (
+ <IconButton color={StrCast(SettingsManager.userVariantColor)} tooltip="back" icon={<CgCornerUpLeft size="16px" />} onClick={() => (this._mode = GPTPopupMode.GPT_MENU)} style={{ right: '50px', position: 'absolute' }} />
)}
<Toggle
tooltip="Clear Chat filter"
@@ -534,13 +529,13 @@ export class GPTPopup extends ObservableReactComponent<object> {
{(() => {
//prettier-ignore
switch (this._mode) {
- case GPTPopupMode.SORT:
- case GPTPopupMode.CARD:
- case GPTPopupMode.QUIZ: return this.sortBox(this._mode === GPTPopupMode.SORT);
- case GPTPopupMode.SUMMARY: return this.summaryBox();
- case GPTPopupMode.DATA: return this.dataAnalysisBox();
- case GPTPopupMode.IMAGE: return this.imageBox();
- default: return null;
+ case GPTPopupMode.GPT_MENU:
+ case GPTPopupMode.USER_PROMPT:
+ case GPTPopupMode.QUIZ_RESPONSE: return this.promptBox(this._mode === GPTPopupMode.USER_PROMPT);
+ case GPTPopupMode.SUMMARY: return this.summaryBox();
+ case GPTPopupMode.DATA: return this.dataAnalysisBox();
+ case GPTPopupMode.IMAGE: return this.imageBox();
+ default: return null;
}
})()}
<div className="resize-handle" />