diff options
| author | A.J. Shulman <Shulman.aj@gmail.com> | 2025-05-11 10:46:15 -0400 |
|---|---|---|
| committer | A.J. Shulman <Shulman.aj@gmail.com> | 2025-05-11 10:46:15 -0400 |
| commit | b87b2105e966928518c96c7702b68c12344ffdd7 (patch) | |
| tree | 84fd5ecede3af9d773c10d02908cdde27da1a759 /src/client/views/pdf/GPTPopup | |
| parent | 0db4583914e43e6efdba3e86a614a19956e73b5e (diff) | |
| parent | 0c3f86d57225a2991920adef3a337bc13e408ac0 (diff) | |
Merge branch 'master' into agent-web-working
Diffstat (limited to 'src/client/views/pdf/GPTPopup')
| -rw-r--r-- | src/client/views/pdf/GPTPopup/GPTPopup.scss | 11 | ||||
| -rw-r--r-- | src/client/views/pdf/GPTPopup/GPTPopup.tsx | 183 |
2 files changed, 109 insertions, 85 deletions
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.scss b/src/client/views/pdf/GPTPopup/GPTPopup.scss index 18441f76e..f6fa45221 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.scss +++ b/src/client/views/pdf/GPTPopup/GPTPopup.scss @@ -7,8 +7,15 @@ $highlightedText: #82e0ff; $inputHeight: 60px; $headingHeight: 32px; +.gptPopup-sortBox { + display: block; + max-height: calc(100% - 45px); // leave room for input +} + .gptPopup-summary-box { position: fixed; + padding-left: 10px; + padding-right: 10px; top: 115px; left: 75px; width: 100%; @@ -48,7 +55,6 @@ $headingHeight: 32px; } label { - color: $textgrey; font-size: 12px; font-weight: 400; letter-spacing: 1px; @@ -73,7 +79,6 @@ $headingHeight: 32px; justify-content: center; align-items: center; height: $inputHeight; - background-color: white; width: 100%; pointer-events: all; @@ -87,6 +92,7 @@ $headingHeight: 32px; } .btns-wrapper-gpt { height: 100%; + width: 100%; display: flex; justify-content: center; align-items: center; @@ -97,7 +103,6 @@ $headingHeight: 32px; flex-direction: column; width: 100%; height: 100%; - overflow-y: auto; padding-right: 5px; } diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index 67213382d..568e48edf 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -93,7 +93,7 @@ export class GPTPopup extends ObservableReactComponent<object> { this.onGptResponse = (sortResult: string, questionType: GPTDocCommand, args?: string) => this.processGptResponse(selDoc, this._textToDocMap, sortResult, questionType, args); this.onQuizRandom = () => this.randomlyChooseDoc(selDoc.Document, hasChildDocs()); this._documentDescriptions = Promise.all(hasChildDocs().map(doc => - Doc.getDescription(doc).then(text => this._textToDocMap.set(text.trim(), doc) && `${DescriptionSeperator}${text}${DescriptionSeperator}`) + Doc.getDescription(doc).then(text => this._textToDocMap.set(text.replace(/\n/g, ' ').trim(), doc) && `${DescriptionSeperator}${text}${DescriptionSeperator}`) )).then(docDescriptions => docDescriptions.join()); // prettier-ignore } }, @@ -210,8 +210,8 @@ export class GPTPopup extends ObservableReactComponent<object> { generateFireflyImage = (imgDesc: string) => { const selView = DocumentView.Selected().lastElement(); const selDoc = selView?.Document; - if (selDoc && (selView._props.renderDepth > 1 || selDoc[Doc.LayoutFieldKey(selDoc)] instanceof ImageField)) { - const oldPrompt = StrCast(selDoc.ai_firefly_prompt, StrCast(selDoc.title)); + if (selDoc && (selView._props.renderDepth > 1 || selDoc[Doc.LayoutDataKey(selDoc)] instanceof ImageField)) { + const oldPrompt = StrCast(selDoc.ai_prompt, StrCast(selDoc.title)); const newPrompt = oldPrompt ? `${oldPrompt} ~~~ ${imgDesc}` : imgDesc; return DrawingFillHandler.drawingToImage(selDoc, 100, newPrompt, selDoc) .then(action(() => (this._userPrompt = ''))) @@ -406,70 +406,80 @@ export class GPTPopup extends ObservableReactComponent<object> { scrollToBottom = () => setTimeout(() => this._messagesEndRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' }), 50); 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)} - color={StrCast(Doc.UserDoc().userVariantColor)} - type={Type.TERT} - style={{ - width: '100%', - height: '40%', - textAlign: 'center', - color: '#ffffff', - fontSize: '16px', - marginBottom: '10px', - }} - /> - <Button - tooltip="Test your knowledge by verifying answers with ChatGPT" - text="Take Quiz" - onClick={() => { - this._conversationArray = ['Define the selected card!']; - this.setMode(GPTPopupMode.QUIZ_RESPONSE); - this.onQuizRandom?.(); - }} - color={StrCast(Doc.UserDoc().userVariantColor)} - type={Type.TERT} - style={{ - width: '100%', - height: '40%', - textAlign: 'center', - color: '#ffffff', - fontSize: '16px', - }} - /> + <div style={{ display: 'flex', maxHeight: 'calc(100% - 32px)', overflow: 'auto' }}> + <div className="btns-wrapper-gpt"> + <Button + tooltip="Ask Firefly to create images" + text="Ask Firefly" + onClick={() => this.setMode(GPTPopupMode.FIREFLY)} + color={SettingsManager.userColor} + background={SettingsManager.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)} + color={SettingsManager.userColor} + background={SettingsManager.userVariantColor} + type={Type.TERT} + style={{ + width: '100%', + height: '40%', + textAlign: 'center', + color: '#ffffff', + fontSize: '16px', + marginBottom: '10px', + }} + /> + <Button + tooltip="Test your knowledge by verifying answers with ChatGPT" + text="Take Quiz" + onClick={() => { + this._conversationArray = ['Define the selected card!']; + this.setMode(GPTPopupMode.QUIZ_RESPONSE); + this.onQuizRandom?.(); + }} + color={SettingsManager.userColor} + background={SettingsManager.userVariantColor} + type={Type.TERT} + style={{ + width: '100%', + height: '40%', + textAlign: 'center', + color: '#ffffff', + fontSize: '16px', + }} + /> + </div> </div> ); callGpt = action((mode: GPTPopupMode) => { this.setGptProcessing(true); + const reset = action(() => { + this.setGptProcessing(false); + this._userPrompt = ''; + this._quizAnswer = ''; + }); switch (mode) { case GPTPopupMode.FIREFLY: this._fireflyArray.push(this._userPrompt); - return this.generateFireflyImage(this._userPrompt).then(action(() => (this._userPrompt = ''))); + return this.generateFireflyImage(this._userPrompt).then(reset); case GPTPopupMode.USER_PROMPT: this._conversationArray.push(this._userPrompt); - return this.generateUserPromptResponse(this._userPrompt).then(action(() => (this._userPrompt = ''))); + return this.generateUserPromptResponse(this._userPrompt).then(reset); case GPTPopupMode.QUIZ_RESPONSE: this._conversationArray.push(this._quizAnswer); - return this.generateQuizAnswerAnalysis(DocumentView.SelectedDocs().lastElement(), this._quizAnswer).then(action(() => (this._quizAnswer = ''))); + return this.generateQuizAnswerAnalysis(DocumentView.SelectedDocs().lastElement(), this._quizAnswer).then(reset); } }); @@ -487,18 +497,20 @@ export class GPTPopup extends ObservableReactComponent<object> { }; gptUserInput = () => ( - <div className="btns-wrapper-gpt"> - <div className="chat-wrapper"> - <div className="chat-bubbles"> - {(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> - ))} - {this._gptProcessing && <div className="chat-bubble chat-message">...</div>} - </div> + <div style={{ display: 'flex', maxHeight: 'calc(100% - 32px)', overflow: 'auto' }}> + <div className="btns-wrapper-gpt"> + <div className="chat-wrapper"> + <div className="chat-bubbles"> + {(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> + ))} + {this._gptProcessing && <div className="chat-bubble chat-message">...</div>} + </div> - <div ref={this._messagesEndRef} style={{ height: '100px' }} /> + <div ref={this._messagesEndRef} style={{ height: '40px' }} /> + </div> </div> </div> ); @@ -517,6 +529,7 @@ export class GPTPopup extends ObservableReactComponent<object> { onChange={e => onChange(e.target.value)} onKeyDown={e => this.handleKeyPress(e, this._mode)} type="text" + style={{ color: 'black' }} placeholder={placeholder} /> <Button // @@ -524,7 +537,8 @@ export class GPTPopup extends ObservableReactComponent<object> { type={Type.TERT} icon={<AiOutlineSend />} iconPlacement="right" - color={SnappingManager.userVariantColor} + color={SettingsManager.userColor} + background={SettingsManager.userVariantColor} onClick={() => this.callGpt(this._mode)} /> <DictationButton ref={r => (this._askDictation = r)} setInput={onChange} /> @@ -551,7 +565,7 @@ export class GPTPopup extends ObservableReactComponent<object> { </div> </div> <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} /> + <Button text="Save Image" onClick={() => this.transferToImage(rawSrc[1])} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} type={Type.TERT} /> </div> </> ))} @@ -561,7 +575,8 @@ export class GPTPopup extends ObservableReactComponent<object> { tooltip="Generate Again" onClick={() => this._imgTargetDoc && this.generateImage(this._imageDescription, this._imgTargetDoc, this._addToCollection)} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} - color={StrCast(Doc.UserDoc().userVariantColor)} + color={SettingsManager.userColor} + background={SettingsManager.userVariantColor} /> )} </div> @@ -603,14 +618,16 @@ export class GPTPopup extends ObservableReactComponent<object> { tooltip="Show originally selected text" // text="Selection" onClick={action(() => (this._showOriginal = true))} - color={StrCast(SettingsManager.userVariantColor)} + color={SettingsManager.userColor} + background={SettingsManager.userVariantColor} type={Type.TERT} /> <Button tooltip="Create a text Doc with this text and link to the text selection" // text="Transfer To Text" onClick={this.transferToText} - color={StrCast(SettingsManager.userVariantColor)} + color={SettingsManager.userColor} + background={SettingsManager.userVariantColor} type={Type.TERT} /> </> @@ -627,14 +644,16 @@ export class GPTPopup extends ObservableReactComponent<object> { } this.generateSummary(this._aiReferenceText); })} - color={StrCast(SettingsManager.userVariantColor)} + color={SettingsManager.userColor} + background={SettingsManager.userVariantColor} type={Type.TERT} /> <Button tooltip="Create Flashcards" // text="Create Flashcards" onClick={this.createFlashcards} - color={StrCast(SettingsManager.userVariantColor)} + color={SettingsManager.userColor} + background={SettingsManager.userVariantColor} type={Type.TERT} /> </> @@ -644,7 +663,7 @@ export class GPTPopup extends ObservableReactComponent<object> { <div className="summarizing"> <span>{this._showOriginal ? 'Creating Cards...' : 'Summarizing'}</span> <ReactLoading type="bubbles" color="#bcbcbc" width={20} height={20} /> - <Button text="Stop Animation" onClick={() => this.setStopAnimatingResponse(true)} color={StrCast(SettingsManager.userVariantColor)} type={Type.TERT} /> + <Button text="Stop Animation" onClick={() => this.setStopAnimatingResponse(true)} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} type={Type.TERT} /> </div> )} </div> @@ -689,19 +708,19 @@ export class GPTPopup extends ObservableReactComponent<object> { placeholder="Ask GPT a question about the data..." id="search-input" className="searchBox-input" - style={{ width: '100%' }} + style={{ width: '100%', color: SnappingManager.userColor }} /> ) : ( <> - <Button tooltip="Transfer to text" text="Transfer To Text" onClick={this.transferToText} color={StrCast(SnappingManager.userVariantColor)} type={Type.TERT} /> - <Button tooltip="Chat with AI" text="Chat with AI" onClick={() => this.setChatEnabled(true)} color={StrCast(SnappingManager.userVariantColor)} type={Type.TERT} /> + <Button tooltip="Transfer to text" text="Transfer To Text" onClick={this.transferToText} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} type={Type.TERT} /> + <Button tooltip="Chat with AI" text="Chat with AI" onClick={() => this.setChatEnabled(true)} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} type={Type.TERT} /> </> ) ) : ( <div className="summarizing"> <span>Summarizing</span> <ReactLoading type="bubbles" color="#bcbcbc" width={20} height={20} /> - <Button text="Stop Animation" onClick={() => this.setStopAnimatingResponse(true)} color={StrCast(SnappingManager.userVariantColor)} type={Type.TERT} /> + <Button text="Stop Animation" onClick={() => this.setStopAnimatingResponse(true)} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} type={Type.TERT} /> </div> )} </div> @@ -718,7 +737,7 @@ export class GPTPopup extends ObservableReactComponent<object> { ); heading = (headingText: string) => ( - <div className="summary-heading"> + <div className="summary-heading" style={{ color: SnappingManager.userBackgroundColor }}> <label className="summary-text">{headingText}</label> {this._gptProcessing ? ( <ReactLoading type="spin" color="#bcbcbc" width={14} height={14} /> @@ -734,7 +753,7 @@ export class GPTPopup extends ObservableReactComponent<object> { onClick={() => this._collectionContext && Doc.setDocFilter(this._collectionContext, 'tags', GPTPopup.ChatTag, 'remove')} /> {[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)} /> + <IconButton color={SettingsManager.userVariantColor} background={SettingsManager.userColor} tooltip="back" icon={<CgCornerUpLeft size="16px" />} onClick={action(() => (this._mode = GPTPopupMode.GPT_MENU))} /> )} </> )} @@ -743,12 +762,12 @@ export class GPTPopup extends ObservableReactComponent<object> { render() { return ( - <div className="gptPopup-summary-box" style={{ display: SnappingManager.ChatVisible ? 'flex' : 'none', overflow: 'auto' }}> + <div className="gptPopup-summary-box" style={{ background: SnappingManager.userColor, color: SnappingManager.userBackgroundColor, display: SnappingManager.ChatVisible ? 'flex' : 'none' }}> {(() => { //prettier-ignore switch (this._mode) { 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, StrCast(DocumentView.Selected().lastElement()?.Document.ai_firefly_prompt, 'Ask Firefly to generate images')); + case GPTPopupMode.FIREFLY: return this.promptBox("CREATE", this._userPrompt, this.setUserPrompt, StrCast(DocumentView.Selected().lastElement()?.Document.ai_prompt, '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(); |
