From cf791104c0b1608e37c3cf2d25dac7f6f58a1b66 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 18 Feb 2025 09:01:44 -0500
Subject: css fixes for gptPopup + close button

---
 src/client/views/pdf/GPTPopup/GPTPopup.tsx | 62 ++++++++++++++++--------------
 1 file changed, 34 insertions(+), 28 deletions(-)

(limited to 'src/client/views/pdf/GPTPopup/GPTPopup.tsx')

diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index f09d786d0..72381cfad 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -3,7 +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 { CgClose, CgCornerUpLeft } from 'react-icons/cg';
+import { CgCornerUpLeft } from 'react-icons/cg';
 import ReactLoading from 'react-loading';
 import { TypeAnimation } from 'react-type-animation';
 import { ClientUtils } from '../../../../ClientUtils';
@@ -108,8 +108,6 @@ export class GPTPopup extends ObservableReactComponent<object> {
 
     @observable private _mode: GPTPopupMode = GPTPopupMode.SUMMARY;
     @action public setMode = (mode: GPTPopupMode) => (this._mode = mode);
-    @observable public Visible: boolean = false;
-    @action public setVisible = (vis: boolean) => (this.Visible = vis);
 
     onQuizRandom?: () => void;
     onGptResponse?: (sortResult: string, questionType: GPTTypeStyle, tag?: string) => void;
@@ -233,10 +231,10 @@ export class GPTPopup extends ObservableReactComponent<object> {
      */
     generateImage = (imgDesc: string, imgTarget: Doc, addToCollection?: (doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) => {
         this._imgTargetDoc = imgTarget;
+        SnappingManager.SetChatVisible(true);
         this.addDoc = addToCollection;
         this.setImgUrls([]);
         this.setMode(GPTPopupMode.IMAGE);
-        this.setVisible(true);
         this.setGptProcessing(true);
         this._imageDescription = imgDesc;
 
@@ -259,8 +257,8 @@ export class GPTPopup extends ObservableReactComponent<object> {
      * @param text the text to summarizz
      */
     generateSummary = (text: string) => {
+        SnappingManager.SetChatVisible(true);
         this._textToSummarize = text;
-        this.setVisible(true);
         this.setMode(GPTPopupMode.SUMMARY);
         this.setGptProcessing(true);
         return gptAPICall(text, GPTCallType.SUMMARY)
@@ -274,7 +272,6 @@ export class GPTPopup extends ObservableReactComponent<object> {
      * this.dataJson in the popup.
      */
     generateDataAnalysis = () => {
-        this.setVisible(true);
         this.setGptProcessing(true);
         return gptAPICall(this._dataJson, GPTCallType.DATA, this._dataChatPrompt)
             .then(res => {
@@ -398,7 +395,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
         }
     };
 
-    gptUserInput = (isUserPrompt: boolean) => (
+    gptUserInput = () => (
         <div className="btns-wrapper-gpt">
             <div className="chat-wrapper">
                 <div className="chat-bubbles">
@@ -412,6 +409,15 @@ export class GPTPopup extends ObservableReactComponent<object> {
 
                 <div ref={this._messagesEndRef} style={{ height: '100px' }} />
             </div>
+        </div>
+    );
+
+    promptBox = (isUserPrompt: boolean) => (
+        <>
+            <div className="gptPopup-sortBox">
+                {this.heading(isUserPrompt ? 'ASK' : 'QUIZ')}
+                {this.gptUserInput()}
+            </div>
             <div className="inputWrapper">
                 <input
                     className="searchBox-input"
@@ -423,29 +429,31 @@ export class GPTPopup extends ObservableReactComponent<object> {
                     placeholder={`${isUserPrompt ? 'Have ChatGPT sort, tag, define, or filter your documents for you!' : 'Describe/answer the selected document!'}`}
                 />
             </div>
-        </div>
+        </>
     );
 
-    promptBox = (isUserPrompt: boolean) => (
-        <div className="gptPopup-sortBox" style={{ height: '80%' }}>
-            {this.heading(isUserPrompt ? 'SORTING' : 'QUIZ')}
-            {this._mode === GPTPopupMode.GPT_MENU ? this.gptMenu() : this.gptUserInput(isUserPrompt)}
+    menuBox = () => (
+        <div className="gptPopup-sortBox">
+            {this.heading('CHOOSE')}
+            {this.gptMenu()}
         </div>
     );
 
     imageBox = () => (
-        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
+        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', overflow: 'auto', height: '100%', pointerEvents: 'all' }}>
             {this.heading('GENERATED IMAGE')}
             <div className="image-content-wrapper">
                 {this._imgUrls.map((rawSrc, i) => (
-                    <div key={rawSrc[0] + i} className="img-wrapper">
-                        <div className="img-container">
-                            <img key={rawSrc[0]} src={rawSrc[0]} width={150} height={150} alt="dalle generation" />
+                    <>
+                        <div key={rawSrc[0] + i} className="img-wrapper">
+                            <div className="img-container">
+                                <img key={rawSrc[0]} src={rawSrc[0]} width={150} height={150} alt="dalle generation" />
+                            </div>
                         </div>
                         <div className="btn-container">
                             <Button text="Save Image" onClick={() => this.transferToImage(rawSrc[1])} color={StrCast(Doc.UserDoc().userColor)} type={Type.TERT} />
                         </div>
-                    </div>
+                    </>
                 ))}
             </div>
             {this._gptProcessing ? null : (
@@ -461,7 +469,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
 
     summaryBox = () => (
         <>
-            <div>
+            <div style={{ height: 'calc(100% - 60px)', overflow: 'auto' }}>
                 {this.heading('SUMMARY')}
                 <div className="gptPopup-content-wrapper">
                     {!this._gptProcessing &&
@@ -481,7 +489,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
                 </div>
             </div>
             {!this._gptProcessing && (
-                <div className="btns-wrapper">
+                <div className="btns-wrapper" style={{ position: 'absolute', bottom: 0, width: 'calc(100% - 32px)' }}>
                     {this._stopAnimatingResponse ? (
                         <>
                             <IconButton tooltip="Generate Again" onClick={() => this.generateSummary(this._textToSummarize + ' ')} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(SettingsManager.userVariantColor)} />
@@ -571,19 +579,18 @@ export class GPTPopup extends ObservableReactComponent<object> {
                 <ReactLoading type="spin" color="#bcbcbc" width={14} height={14} />
             ) : (
                 <>
-                    {(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"
                         toggleType={ToggleType.BUTTON}
                         type={Type.PRIM}
                         toggleStatus={Doc.hasDocFilter(this._collectionContext, 'tags', '#chat')}
                         text={Doc.hasDocFilter(this._collectionContext, 'tags', '#chat') ? 'filtered' : ''}
-                        color="red"
+                        color={Doc.hasDocFilter(this._collectionContext, 'tags', '#chat') ? 'red' : 'transparent'}
                         onClick={() => this._collectionContext && Doc.setDocFilter(this._collectionContext, 'tags', '#chat', 'remove')}
                     />
-                    <IconButton color={StrCast(SettingsManager.userVariantColor)} tooltip="close" icon={<CgClose size="16px" />} onClick={() => this.setVisible(false)} />
+                    {(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)} />
+                    )}
                 </>
             )}
         </div>
@@ -591,20 +598,19 @@ export class GPTPopup extends ObservableReactComponent<object> {
 
     render() {
         return (
-            <div className="gptPopup-summary-box" style={{ display: this.Visible ? 'flex' : 'none' }}>
+            <div className="gptPopup-summary-box" style={{ display: SnappingManager.ChatVisible ? 'flex' : 'none', overflow: 'auto' }}>
                 {(() => {
                     //prettier-ignore
                     switch (this._mode) {
-                        case GPTPopupMode.GPT_MENU:
-                        case GPTPopupMode.USER_PROMPT:
+                        case GPTPopupMode.USER_PROMPT: 
                         case GPTPopupMode.QUIZ_RESPONSE: return this.promptBox(this._mode === GPTPopupMode.USER_PROMPT);
+                        case GPTPopupMode.GPT_MENU:      return this.menuBox();
                         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" />
             </div>
         );
     }
-- 
cgit v1.2.3-70-g09d2

