aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2025-02-14 00:23:41 -0500
committerbobzel <zzzman@gmail.com>2025-02-14 00:23:41 -0500
commitb7845adf2904e18e237638a0bf907c6ec0fe06ee (patch)
treed3aa29c64fc7440d7242cdef7872334b4fea4cbc /src
parent6f60b3ccf18c35c3faada44ef7187f4ae9d50ab1 (diff)
more gptPopup cleanup and starting to allow it to work on any collection type.
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/CollectionCardDeckView.tsx18
-rw-r--r--src/client/views/pdf/GPTPopup/GPTPopup.tsx64
2 files changed, 38 insertions, 44 deletions
diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx
index a3ec3884b..ba68504d7 100644
--- a/src/client/views/collections/CollectionCardDeckView.tsx
+++ b/src/client/views/collections/CollectionCardDeckView.tsx
@@ -75,13 +75,13 @@ export class CollectionCardView extends CollectionSubView() {
}
/**
- * update's gpt's doc-text list and initializes callbacks
+ * update's gpt's doc-text list and initialize callbacks to respond to GPT output
*/
- childPairStringListAndUpdateSortDesc = () =>
- this.childPairStringList().then(sortDesc => {
- GPTPopup.Instance.setSortDesc(sortDesc.join());
+ updateDocumentDescriptions = () =>
+ this.childPairStringList().then(docDescriptions => {
+ GPTPopup.Instance.setDocumentDescriptions(docDescriptions.join());
GPTPopup.Instance.onGptResponse = this.processGptResponse;
- GPTPopup.Instance.onQuizRandom = this.quizMode;
+ GPTPopup.Instance.onQuizRandom = this.randomlyChooseDoc;
});
componentDidMount() {
@@ -89,7 +89,7 @@ export class CollectionCardView extends CollectionSubView() {
() => GPTPopup.Instance.Visible,
vis => !vis && this.onGptHide()
);
- GPTPopup.Instance.setRegenerateCallback(this.Document, this.childPairStringListAndUpdateSortDesc);
+ GPTPopup.Instance.setRetrieveDocDescriptionsCallback(this.Document, this.updateDocumentDescriptions);
this._props.setContentViewBox?.(this);
// if card deck moves, then the child doc views are hidden so their screen to local transforms will return empty rectangles
// when inquired from the dom (below in childScreenToLocal). When the doc is actually rendered, we need to act like the
@@ -112,10 +112,8 @@ export class CollectionCardView extends CollectionSubView() {
onGptHide = () => Doc.setDocFilter(this.Document, 'tags', '#chat', 'remove');
componentWillUnmount() {
- GPTPopup.Instance.setSortDesc('');
GPTPopup.Instance.onGptResponse = undefined;
GPTPopup.Instance.onQuizRandom = undefined;
- GPTPopup.Instance.setRegenerateCallback(undefined, null);
Object.keys(this._disposers).forEach(key => this._disposers[key]?.());
this._dropDisposer?.();
}
@@ -169,9 +167,7 @@ export class CollectionCardView extends CollectionSubView() {
/**
* When in quiz mode, randomly selects a document
*/
- quizMode = () => {
- this.layoutDoc._card_curDoc = this.childDocs[Math.floor(Math.random() * this.childDocs.length)];
- };
+ randomlyChooseDoc = () => (this.layoutDoc._card_curDoc = this.childDocs[Math.floor(Math.random() * this.childDocs.length)]);
setHoveredNodeIndex = action((index: number) => {
if (!SnappingManager.IsDragging) this._hoveredNodeIndex = index;
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index 4457bde91..281748155 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -39,20 +39,20 @@ export enum GPTQuizType {
export class GPTPopup extends ObservableReactComponent<object> {
// eslint-disable-next-line no-use-before-define
static Instance: GPTPopup;
- private _regenerateCallback: (() => Promise<void>) | null = null;
+ private _retrieveDocDescriptions: (() => Promise<void>) | null = null;
private _messagesEndRef: React.RefObject<HTMLDivElement>;
private _correlatedColumns: string[] = [];
private _dataChatPrompt: string | undefined = undefined;
private _imgTargetDoc: Doc | undefined;
private _textAnchor: Doc | undefined;
private _dataJson: string = '';
- private _sortDesc: string = '';
+ private _documentDescriptions: string = '';
private _sidebarFieldKey: string = '';
- private _selectedText: string = '';
- private _imgDesc: string = '';
+ private _textToSummarize: string = '';
+ private _imageDescription: string = '';
public setSidebarFieldKey = (id: string) => (this._sidebarFieldKey = id);
- public setSortDesc = (t: string) => (this._sortDesc = t);
+ public setDocumentDescriptions = (t: string) => (this._documentDescriptions = t);
public setImgTargetDoc = (anchor: Doc) => (this._imgTargetDoc = anchor);
public setTextAnchor = (anchor: Doc) => (this._textAnchor = anchor);
public onGptResponse?: (sortResult: string, questionType: GPTTypeStyle, tag?: string) => void;
@@ -94,12 +94,13 @@ export class GPTPopup extends ObservableReactComponent<object> {
@action public setStopAnimatingResponse = (done: boolean) => (this._stopAnimatingResponse = done);
/**
- * Callback function that causes the card view to update the childpair string list
- * @param callback
+ * sets callback needed to retrieve an updated description of the collection's documents
+ * @param collectionDoc - the collection doc context for the GPT prompts
+ * @param callback - function to retrieve document descriptions
*/
- public setRegenerateCallback(collectionDoc: Doc | undefined, callback: null | (() => Promise<void>)) {
+ public setRetrieveDocDescriptionsCallback(collectionDoc: Doc | undefined, callback: null | (() => Promise<void>)) {
this.setCollectionContext(collectionDoc);
- this._regenerateCallback = callback;
+ this._retrieveDocDescriptions = callback;
}
public addDoc: (doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean = () => false;
@@ -126,35 +127,33 @@ export class GPTPopup extends ObservableReactComponent<object> {
* @returns
*/
generateQuizAnswerAnalysis = (doc: Doc, quizAnswer: string) =>
- (this._regenerateCallback?.() ?? Promise.resolve()).then(
- () =>
- this.generateRubric(doc).then(() =>
- gptAPICall(
- `Question: ${StrCast(doc.gptInputText)};
- UserAnswer: ${quizAnswer};
- Rubric: ${StrCast(doc.gptRubric)}`,
- GPTCallType.QUIZ
- ).then(res => {
- this._conversationArray.push(res || 'GPT provided no answer');
- this.onQuizRandom?.();
- })
- .catch(err => console.error('GPT call failed', err))
- ) // prettier-ignore
- );
+ this.generateRubric(doc).then(() =>
+ gptAPICall(
+ `Question: ${StrCast(doc.gptInputText)};
+ UserAnswer: ${quizAnswer};
+ Rubric: ${StrCast(doc.gptRubric)}`,
+ GPTCallType.QUIZ
+ ).then(res => {
+ this._conversationArray.push(res || 'GPT provided no answer');
+ this.onQuizRandom?.();
+ })
+ .catch(err => console.error('GPT call failed', err))
+ ) // prettier-ignore
/**
- * Generates a response to the user's question depending on the type of their question
+ * 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
* @param userPrompt the user's input that chat will respond to
*/
generateUserPromptResponse = (userPrompt: string) =>
- (this._regenerateCallback ?? Promise.resolve)().then(() =>
+ (this._retrieveDocDescriptions ?? Promise.resolve)().then(() =>
gptAPICall(userPrompt, GPTCallType.TYPE).then(questionType =>
(() => {
switch (this.questionTypeNumberToStyle(questionType)) {
case GPTTypeStyle.AssignTags:
case GPTTypeStyle.Filter:
- case GPTTypeStyle.ChooseDoc: return gptAPICall(this._sortDesc, GPTCallType.SUBSET, userPrompt);
- case GPTTypeStyle.SortDocs: return gptAPICall(this._sortDesc, GPTCallType.SORT, userPrompt);
+ case GPTTypeStyle.ChooseDoc: return gptAPICall(this._documentDescriptions, GPTCallType.SUBSET, userPrompt);
+ case GPTTypeStyle.SortDocs: return gptAPICall(this._documentDescriptions, GPTCallType.SORT, userPrompt);
default: return gptAPICall(StrCast(DocumentView.SelectedDocs().lastElement()?.gptInputText), GPTCallType.INFO, userPrompt);
} // prettier-ignore
})().then(
@@ -178,7 +177,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
this.setMode(GPTPopupMode.IMAGE);
this.setVisible(true);
this.setGptProcessing(true);
- this._imgDesc = imgDesc;
+ this._imageDescription = imgDesc;
return gptImageCall(imgDesc)
.then(imageUrls =>
@@ -199,7 +198,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
* @param text the text to summarizz
*/
generateSummary = (text: string) => {
- this._selectedText = text;
+ this._textToSummarize = text;
this.setVisible(true);
this.setMode(GPTPopupMode.SUMMARY);
this.setGptProcessing(true);
@@ -355,7 +354,6 @@ export class GPTPopup extends ObservableReactComponent<object> {
<div className="inputWrapper">
<input
className="searchBox-input"
- defaultValue=""
value={isUserPrompt ? this._userPrompt : this._quizAnswer} // Controlled input
autoComplete="off"
onChange={isUserPrompt ? this.setUserPrompt : this.setQuizAnswer}
@@ -389,7 +387,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
</div>
))}
</div>
- {this._gptProcessing ? null : <IconButton tooltip="Generate Again" onClick={() => this.generateImage(this._imgDesc)} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(Doc.UserDoc().userVariantColor)} />}
+ {this._gptProcessing ? null : <IconButton tooltip="Generate Again" onClick={() => this.generateImage(this._imageDescription)} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(Doc.UserDoc().userVariantColor)} />}
</div>
);
@@ -418,7 +416,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
<div className="btns-wrapper">
{this._stopAnimatingResponse ? (
<>
- <IconButton tooltip="Generate Again" onClick={() => this.generateSummary(this._selectedText + ' ')} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(SettingsManager.userVariantColor)} />
+ <IconButton tooltip="Generate Again" onClick={() => this.generateSummary(this._textToSummarize + ' ')} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(SettingsManager.userVariantColor)} />
<Button tooltip="Transfer to text" text="Transfer To Text" onClick={this.transferToText} color={StrCast(SettingsManager.userVariantColor)} type={Type.TERT} />
</>
) : (