aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/apis/gpt/GPT.ts2
-rw-r--r--src/client/documents/Documents.ts2
-rw-r--r--src/client/util/CurrentUserUtils.ts29
-rw-r--r--src/client/views/collections/CollectionCardDeckView.tsx231
-rw-r--r--src/client/views/global/globalScripts.ts153
-rw-r--r--src/client/views/pdf/GPTPopup/GPTPopup.scss6
-rw-r--r--src/client/views/pdf/GPTPopup/GPTPopup.tsx102
7 files changed, 343 insertions, 182 deletions
diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts
index 9a24c808c..398f8ae39 100644
--- a/src/client/apis/gpt/GPT.ts
+++ b/src/client/apis/gpt/GPT.ts
@@ -20,7 +20,7 @@ const callTypeMap: { [type: string]: GPTCallOpts } = {
summary: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: 'Summarize this text in simpler terms: ' },
edit: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: 'Reword this: ' },
completion: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: '' },
- sort:{model:'gpt-4o',maxTokens:2048,temp:0.5,prompt:"I'm going to give you a list of descriptions. Each one is seperated by ====== on either side. They will vary in length, so make sure to only seperate when you see ======. Sort them into lists by shared content. MAKE SURE EACH DESCRIPTOR IS IN ONLY ONE LIST. Generate only the list with each list seperated by ====== with the elements seperated by ~~~~~~"},
+ sort:{model:'gpt-4o',maxTokens:2048,temp:0.5,prompt:"I'm going to give you a list of descriptions. Each one is seperated by ====== on either side. They will vary in length, so make sure to only seperate when you see ======. Sort them into lists by shared content. MAKE SURE EACH DESCRIPTOR IS IN ONLY ONE LIST. Generate only the list with each list seperated by ====== with the elements seperated by ~~~~~~. Try to do around 4 groups, but a little more or less is ok."},
describe:{model:'gpt-4-vision-preview',maxTokens:2048,temp:0,prompt:"Describe these images in 3-5 words"},
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 57f91399a..eded2b485 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -502,6 +502,8 @@ export class DocumentOptions {
cardSort?: STRt = new StrInfo('way cards are sorted in deck view');
customSortNumber?: NUMt = new NumInfo('number of custom sorts the user has created');
customHashMap?: List<string>
+ visibleGroupNumbers?: List<number>
+
// card_sort_time?: BOOLt = new BoolInfo('whether sorting cards in deck view by time');
// card_sort_type?: BOOLt = new BoolInfo('whether sorting cards in deck view by type');
// card_sort_color?: BOOLt = new BoolInfo('whether sorting cards in deck view by color');
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index e18c22bac..251771e8e 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -729,18 +729,34 @@ pie title Minerals in my tap water
{ title: "Time", icon:"hourglass-half", toolTip:"Sort by most recent document creation", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"time", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
{ title: "Type", icon:"eye", toolTip:"Sort by document type", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"docType", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
{ title: "Color", icon:"palette", toolTip:"Sort by document color", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"color", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
- { title: "Links", icon:"link", toolTip:"Sort by its links", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"links", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
- { title: "Create", icon:"heart", toolTip:"Create your first custom grouping!", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"custom1", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
- { title: "Create", icon:"star", toolTip:"Create your second custom grouping!", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"custom2", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
- { title: "Create", icon:"satellite", toolTip:"Create your third custom grouping!", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"custom3", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
- { title: "Create", icon:"robot", toolTip:"Have ChatGPT sort your text-based nodes !", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"chat", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "Smart Sort", icon:"robot", toolTip:"Have ChatGPT sort your text-based nodes !", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"chat", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ ]
+ }
+ static customCardTools(): Button[] {
+ return [
+ { title: "Create", icon:"heart", toolTip:"Create your first custom grouping!", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"custom1", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "Create", icon:"star", toolTip:"Create your second custom grouping!", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"custom2", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "Create", icon:"satellite", toolTip:"Create your third custom grouping!", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"custom3", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "Custom 1", icon: "Custom 1", width: 10, toolTip: "Set visibilty!", subMenu: CurrentUserUtils.cardGroupTools("heart"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!isThatCardGroup(0)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "Custom 2", icon: "Custom 2", width: 80, toolTip: "Set visibilty!", subMenu: CurrentUserUtils.cardGroupTools("star"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!isThatCardGroup(1)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "Custom 3", icon: "Custom 3", width: 80, toolTip: "Set visibilty!", subMenu: CurrentUserUtils.cardGroupTools("satellite"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!isThatCardGroup(2)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ ]
+ }
- // ...customs
+ static cardGroupTools(icon: string): Button[] {
+ return [
+ { title: "", icon:icon, toolTip:"Click to toggle visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"1", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "", icon:icon, toolTip:"Click to toggle visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"2", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "", icon:icon, toolTip:"Click to toggle visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"3", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
+ { title: "", icon:icon, toolTip:"Click to toggle visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"4", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}},
]
}
+
+
+
static viewTools(): Button[] {
return [
{ title: "Snap", icon: "th", toolTip: "Show Snap Lines", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"snaplines", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
@@ -842,6 +858,7 @@ pie title Minerals in my tap water
{ title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
{ title: "Stack", icon: "View", toolTip: "Stacking tools", subMenu: CurrentUserUtils.stackTools(), expertMode: false, toolType:CollectionViewType.Stacking, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
{ title: "Card", icon: "Sort", toolTip: "Card sort", subMenu: CurrentUserUtils.cardTools(), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
+ { title: "CustomCard", icon: "Create", toolTip: "Create custom groupings!", subMenu: CurrentUserUtils.customCardTools(), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Always available
{ title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Only when Web is selected
{ title: "Video", icon: "Video", toolTip: "Video functions", subMenu: CurrentUserUtils.videoTools(), expertMode: false, toolType:DocumentType.VID, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Only when video is selected
{ title: "Image", icon: "Image", toolTip: "Image functions", subMenu: CurrentUserUtils.imageTools(), expertMode: false, toolType:DocumentType.IMG, funcs: {hidden: `!SelectionManager_selectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(this.toolType, this.expertMode)`} }, // Only when image is selected
diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx
index e96fbc161..42c82ca74 100644
--- a/src/client/views/collections/CollectionCardDeckView.tsx
+++ b/src/client/views/collections/CollectionCardDeckView.tsx
@@ -24,6 +24,7 @@ import { ImageField, PdfField, URLField } from '../../../fields/URLField';
import { GPTPopup } from '../pdf/GPTPopup/GPTPopup';
import { GPTPopupMode } from '../pdf/GPTPopup/GPTPopup';
import { reaction } from 'mobx';
+import { NumListCast } from '../../../fields/Doc';
@observer
export class CollectionCardView extends CollectionSubView() {
@@ -32,8 +33,42 @@ export class CollectionCardView extends CollectionSubView() {
// documents themselves
@observable hoveredNodeIndex = -1;
+ //index to group
+ @observable customGroupDictionary: Map<number, number>[] = [new Map<number, number>(), new Map<number, number>(), new Map<number, number>()];
+
@computed get myChildLayoutPairs() {
+ let activeGroups = NumListCast(this._props.Document.visibleGroupNumbers);
+ let currCustom = NumCast(this._props.Document.customSortNumber);
+
+ // console.log("Active Groups:", activeGroups);
+
+ for (let i=0; i< activeGroups.length; i++){
+ console.log("Active Groups" + activeGroups[i])
+ }
+ // console.log("Current Custom Sort Number:", currCustom);
+
+ if (activeGroups.length <= 0) {
+ return this.childLayoutPairs.filter(l => l.layout.type != DocumentType.LINK);
+ }
+
+ if (StrCast(this._props.Document.cardSort).includes("custom")) {
+ return this.childLayoutPairs.filter((l, index) => {
+ if (l.layout.type === DocumentType.LINK) {
+ return false;
+ }
+
+ // Get the group number for the current index from the customGroupDictionary
+ const groupNumber = this.customGroupDictionary[currCustom].get(index);
+
+ // console.log(`Index: ${index}, Group Number: ${groupNumber}`);
+
+ // Check if the group number is in the active groups
+ return groupNumber !== undefined && activeGroups.includes(groupNumber);
+ });
+ }
+
+ // Default return for non-custom cardSort or other cases, filtering out links
return this.childLayoutPairs.filter(l => l.layout.type != DocumentType.LINK);
}
@@ -90,6 +125,9 @@ export class CollectionCardView extends CollectionSubView() {
if (this._props.Document.customHashMap != undefined){
this.customGroupDictionary = this.getCustoms(StrListCast(this._props.Document.customHashMap))
}
+ // this._props.Document.visibleGroupNumbers = new List<number>([1,2,3,4])
+
+
reaction(
() => this._props.Document.cardSort,
@@ -101,7 +139,6 @@ export class CollectionCardView extends CollectionSubView() {
);
}
- @observable customGroupDictionary: Map<number, number>[] = [new Map<number, number>(), new Map<number, number>(), new Map<number, number>()];
@computed get mapToField(): List<string> {
const resultList = new List<string>();
@@ -272,7 +309,8 @@ export class CollectionCardView extends CollectionSubView() {
case 'custom':
return this.sort(sorted, 'custom', desc);
case 'chat':
- return { docs: this.sortedDocs || this.myChildLayoutPairs}; // Use the sorted docs from the observable
+ return this.sort(this.myChildLayoutPairs, 'gpt', BoolCast(this.layoutDoc.sortDesc));
+
default:
docs = this.myChildLayoutPairs;
return { docs };
@@ -458,7 +496,8 @@ export class CollectionCardView extends CollectionSubView() {
// const childPair = { layout: doc, data: doc };
const isHovered = this.hoveredNodeIndex === index;
- const childPairIndex = this.myChildLayoutPairs.indexOf(childPair);
+ // const childPairIndex = this.myChildLayoutPairs.indexOf(childPair);
+ const childPairIndex = this.childLayoutPairs.filter(d => d.layout.type != DocumentType.LINK).indexOf(childPair)
const realIndex = this.sortedDocsType.docs.filter(d => !SelectionManager.IsSelected(d.layout)).indexOf(childPair);
const calcRowIndex = this.overflowIndexCalc(realIndex);
@@ -501,6 +540,8 @@ export class CollectionCardView extends CollectionSubView() {
{this.displayDoc(childPair, childScreenToLocal)}
{this._props.Document.cardSort == 'custom' ? this.renderButtons(childPairIndex) : ''}
+ {this._props.Document.cardSort == 'chat' ? this.renderButtons(childPairIndex, childPair.layout, true) : ''}
+
</div>
);
});
@@ -512,38 +553,23 @@ export class CollectionCardView extends CollectionSubView() {
- @action toggleButton(childPairIndex: number, buttonID: number) {
- this.customGroupDictionary[NumCast(this._props.Document.customSortNumber)].set(childPairIndex, buttonID);
- this._props.Document.customHashMap = this.mapToField
-
- // Cast(selected.Document.data, WebField, null)?.url?.href)
-
- //note richtext
-
- // StrCast(selected.Document.data, Cast(selected.Document.data, WebField, null)?.url?.href)
-
-
-
- // const
- const imgurlperchance = Cast(this.childDocs[1].data, ImageField, null)?.url.href;
- const perchance = this.imageUrlToBase64(imgurlperchance)
- // const imgurlperchance = Cast(this.childDocs[1].data, PdfField, null)?.url.;
-
-
- // console.log('Print Front of cards: ' + RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text);
- // console.log('Print Back of cards: ' + RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text);
-
- // const perchance = StrCast(this.childDocs[0].text);
-
-
-
- // const pdf = (StrCast(this.myChildLayoutPairs[0].layout.text)); //pdf
- const queryText = this.myChildLayoutPairs[0].layout.type; //everything else
-
- // const queryText = RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text;
-
- console.log(queryText ?? "sad")
+ @action toggleButton(childPairIndex: number, buttonID: number, isChat = false, doc?: Doc) {
+ if (!isChat) {
+ this.customGroupDictionary[NumCast(this._props.Document.customSortNumber)].set(childPairIndex, buttonID);
+ this._props.Document.customHashMap = this.mapToField;
+ }
+
+ if (isChat && doc) {
+ this.gptGroups.set(doc, buttonID);
+ }
+
+ // console.log(`Toggled button for childPairIndex: ${childPairIndex}, buttonID: ${buttonID}, isChat: ${isChat}`);
+ // console.log(`Updated customGroupDictionary:`, this.customGroupDictionary);
+ if (isChat && doc) {
+ console.log(`Updated gptGroups for doc ${doc}:`, this.gptGroups.get(doc));
+ }
}
+
async childPairStringList(): Promise<string> {
let string = "";
@@ -598,20 +624,25 @@ export class CollectionCardView extends CollectionSubView() {
textToDoc = new Map<string, Doc>()
gptProccessedImages = new Set<Doc>()
- @action async getImageDesc(image: Doc){
- let href = (image['data'] as URLField).url.href;
- let hrefParts = href.split('.');
- let hrefComplete = `${hrefParts[0]}_o.${hrefParts[1]}`;
- try {
- let hrefBase64 = await this.imageUrlToBase64(hrefComplete);
- let response = await gptImageLabel(hrefBase64);
- this.textToDoc.set(response.trim(), image);
- this.gptProccessedImages.add(image);
- console.log(response);
- return response; // Return the response from gptImageLabel
- } catch (error) {
- console.log("bad things have happened");
- }
+ @action async getImageDesc(image: Doc) {
+ if (this.gptProccessedImages.has(image)) {
+ // Return the already processed description
+ return Array.from(this.textToDoc.keys()).find(key => this.textToDoc.get(key) === image) || '';
+ }
+
+ let href = (image['data'] as URLField).url.href;
+ let hrefParts = href.split('.');
+ let hrefComplete = `${hrefParts[0]}_o.${hrefParts[1]}`;
+ try {
+ let hrefBase64 = await this.imageUrlToBase64(hrefComplete);
+ let response = await gptImageLabel(hrefBase64);
+ this.textToDoc.set(response.trim(), image);
+ this.gptProccessedImages.add(image);
+ console.log(response);
+ return response; // Return the response from gptImageLabel
+ } catch (error) {
+ console.log("bad things have happened");
+ }
}
@@ -620,41 +651,43 @@ export class CollectionCardView extends CollectionSubView() {
//a map from the text to the Doc (for everything)
- @action async smartSort() {
- this.isLoading = true;
- console.log("loading");
+ // @action async smartSort() {
+ // this.isLoading = true;
+ // console.log("loading");
- // Store the result of childPairStringList in a variable
- const childPairStrings = await this.childPairStringList();
+ // // Store the result of childPairStringList in a variable
+ // const childPairStrings = await this.childPairStringList();
- if (childPairStrings === "") {
- console.log("no child pairs :(");
- } else {
- console.log(childPairStrings + " og list");
- let prompt = childPairStrings;
+ // if (childPairStrings === "") {
+ // console.log("no child pairs :(");
+ // } else {
+ // console.log(childPairStrings + " og list");
+ // let prompt = childPairStrings;
- let res = await gptAPICall(prompt, GPTCallType.SORT);
- this.isLoading = false;
- if (res == 'Error connecting with API.') {
- // If GPT call failed
- console.error('GPT call failed');
- } else if (res != null) {
- console.log(res);
- this.processGptOutput(res);
- // Update the observable with the sorted documents
- this.sortedDocs = this.sort(this.myChildLayoutPairs, 'gpt', BoolCast(this.layoutDoc.sortDesc)).docs;
- }
- this.isLoading = false;
- }
- }
+ // let res = await gptAPICall(prompt, GPTCallType.SORT);
+ // this.isLoading = false;
+ // if (res == 'Error connecting with API.') {
+ // // If GPT call failed
+ // console.error('GPT call failed');
+ // } else if (res != null) {
+ // console.log(res);
+ // this.processGptOutput(res);
+ // // Update the observable with the sorted documents
+ // this.sortedDocs = this.sort(this.myChildLayoutPairs, 'gpt', BoolCast(this.layoutDoc.sortDesc)).docs;
+ // }
+ // this.isLoading = false;
+ // }
+ // }
- gptGroups = new Map<Doc, number>
+ gptGroups = new ObservableMap<Doc, number>
+ @observable amGPTGroups = 0
// Method to convert the GPT-produced string into a map
processGptOutput(gptOutput: string) {
// Split the string into individual list items
const listItems = gptOutput.split('======').filter(item => item.trim() !== '');
+ this.amGPTGroups = listItems.length
listItems.forEach((item, index) => {
// Split the item by '~~~~~~' to get all descriptors
@@ -678,14 +711,15 @@ export class CollectionCardView extends CollectionSubView() {
@observable isChatPopupOpen = false;
@action openChatPopup = async () => {
- this.isChatPopupOpen = true;
- GPTPopup.Instance.setVisible(true);
- GPTPopup.Instance.setMode(GPTPopupMode.SORT);
-
- // Await the promise to get the string result
- const sortDesc = await this.childPairStringList();
- GPTPopup.Instance.setSortDesc(sortDesc);
- GPTPopup.Instance.onSortComplete = this.handleGptSortResult;
+ this.isChatPopupOpen = true;
+ GPTPopup.Instance.setVisible(true);
+ GPTPopup.Instance.setMode(GPTPopupMode.SORT);
+
+ // Await the promise to get the string result
+ const sortDesc = await this.childPairStringList();
+ GPTPopup.Instance.setCardsDoneLoading(true); // Set dataDoneLoading to true after data is loaded
+ GPTPopup.Instance.setSortDesc(sortDesc);
+ GPTPopup.Instance.onSortComplete = this.handleGptSortResult;
};
@action handleGptSortResult = (sortResult: string) => {
this.processGptOutput(sortResult);
@@ -696,19 +730,34 @@ export class CollectionCardView extends CollectionSubView() {
- renderButtons(childPairIndex: number) {
+ renderButtons(childPairIndex: number, doc?: Doc, isChat = false) {
const buttons = []; // Array to hold the button elements
-
- let amButtons = 4;
-
- let activeButtonIndex = this.customGroupDictionary[NumCast(this._props.Document.customSortNumber)].get(childPairIndex);
-
+ const groupNumber = NumCast(this._props.Document.customSortNumber);
+
+ let amButtons = 4; // Adjusted to your context
+ let activeButtonIndex = this.customGroupDictionary[groupNumber].get(childPairIndex);
+
+ if (isChat && doc) {
+ if (this.amGPTGroups > 4){
+ amButtons = this.amGPTGroups;
+ }
+ activeButtonIndex = this.gptGroups.get(doc);
+ }
+
+ console.log("childPairIndex:", childPairIndex, "activeButtonIndex:", activeButtonIndex, "groupNumber:", groupNumber);
+
for (let i = 0; i < amButtons; i++) {
- const isActive = activeButtonIndex == i;
-
- buttons.push(<button key={i} style={{ backgroundColor: `${isActive ? '#4476f7' : '#323232'}` }} onClick={() => this.toggleButton(childPairIndex, i)}></button>);
+ const isActive = activeButtonIndex === i;
+ console.log(`Rendering button ${i} for childPairIndex ${childPairIndex} isActive: ${isActive}`);
+ buttons.push(
+ <button
+ key={i}
+ style={{ backgroundColor: isActive ? '#4476f7' : '#323232' }}
+ onClick={() => this.toggleButton(childPairIndex, i, isChat, doc)}
+ ></button>
+ );
}
-
+
const totalWidth = amButtons * 35 + amButtons * 2 * 5 + 6;
return (
<div className="card-button-container" style={{ width: `${totalWidth}px` }}>
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 14f83beb6..496d7482c 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -22,7 +22,8 @@ import { VideoBox } from '../nodes/VideoBox';
import { WebBox } from '../nodes/WebBox';
import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
import { ImageBox } from '../nodes/ImageBox';
-
+import { NumListCast } from '../../../fields/Doc';
+import { List } from '../../../fields/List';
ScriptingGlobals.add(function IsNoneSelected() {
return SelectionManager.Views.length <= 0;
}, 'are no document selected');
@@ -107,84 +108,146 @@ ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) {
-ScriptingGlobals.add(function showFreeform(attr: 'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links' | 'custom1' | 'custom2' | 'custom3'| 'chat', checkResult?: boolean, persist?: boolean, customNumber?: number) {
+ScriptingGlobals.add(function showFreeform(
+ attr: 'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links' | 'custom1' | 'custom2' | 'custom3' | 'chat' | '1' | '2' | '3' | '4',
+ checkResult?: boolean,
+ persist?: boolean,
+ isDoubleClick?: boolean
+) {
const selected = SelectionManager.Docs.lastElement();
// prettier-ignore
- const map: Map<'flashcards' | 'center' |'grid' | 'snaplines' | 'clusters' | 'arrange'| 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links' | 'custom1' | 'custom2' | 'custom3'| 'chat', { waitForRender?: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc, dv:DocumentView) => void;}> = new Map([
+ const map: Map<'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links' | 'custom1' | 'custom2' | 'custom3' | 'chat' | '1' | '2' | '3' | '4',
+ {
+ waitForRender?: boolean;
+ checkResult: (doc: Doc) => any;
+ setDoc: (doc: Doc, dv: DocumentView) => void;
+ }> = new Map([
['grid', {
- checkResult: (doc:Doc) => BoolCast(doc?._freeform_backgroundGrid, false),
- setDoc: (doc:Doc,dv:DocumentView) => doc._freeform_backgroundGrid = !doc._freeform_backgroundGrid,
+ checkResult: (doc: Doc) => BoolCast(doc?._freeform_backgroundGrid, false),
+ setDoc: (doc: Doc, dv: DocumentView) => doc._freeform_backgroundGrid = !doc._freeform_backgroundGrid,
}],
['snaplines', {
- checkResult: (doc:Doc) => BoolCast(doc?._freeform_snapLines, false),
- setDoc: (doc:Doc, dv:DocumentView) => doc._freeform_snapLines = !doc._freeform_snapLines,
+ checkResult: (doc: Doc) => BoolCast(doc?._freeform_snapLines, false),
+ setDoc: (doc: Doc, dv: DocumentView) => doc._freeform_snapLines = !doc._freeform_snapLines,
}],
['viewAll', {
- checkResult: (doc:Doc) => BoolCast(doc?._freeform_fitContentsToBox, false),
- setDoc: (doc:Doc,dv:DocumentView) => {
+ checkResult: (doc: Doc) => BoolCast(doc?._freeform_fitContentsToBox, false),
+ setDoc: (doc: Doc, dv: DocumentView) => {
if (persist) doc._freeform_fitContentsToBox = !doc._freeform_fitContentsToBox;
else if (doc._freeform_fitContentsToBox) doc._freeform_fitContentsToBox = undefined;
else (dv.ComponentView as CollectionFreeFormView)?.fitContentOnce();
},
}],
['center', {
- checkResult: (doc:Doc) => BoolCast(doc?._stacking_alignCenter, false),
- setDoc: (doc:Doc,dv:DocumentView) => doc._stacking_alignCenter = !doc._stacking_alignCenter,
+ checkResult: (doc: Doc) => BoolCast(doc?._stacking_alignCenter, false),
+ setDoc: (doc: Doc, dv: DocumentView) => doc._stacking_alignCenter = !doc._stacking_alignCenter,
}],
['clusters', {
- waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire
- checkResult: (doc:Doc) => BoolCast(doc?._freeform_useClusters, false),
- setDoc: (doc:Doc,dv:DocumentView) => doc._freeform_useClusters = !doc._freeform_useClusters,
+ waitForRender: true,
+ checkResult: (doc: Doc) => BoolCast(doc?._freeform_useClusters, false),
+ setDoc: (doc: Doc, dv: DocumentView) => doc._freeform_useClusters = !doc._freeform_useClusters,
}],
['flashcards', {
- checkResult: (doc:Doc) => BoolCast(Doc.UserDoc().defaultToFlashcards, false),
- setDoc: (doc:Doc,dv:DocumentView) => Doc.UserDoc().defaultToFlashcards = !Doc.UserDoc().defaultToFlashcards,
+ checkResult: (doc: Doc) => BoolCast(Doc.UserDoc().defaultToFlashcards, false),
+ setDoc: (doc: Doc, dv: DocumentView) => Doc.UserDoc().defaultToFlashcards = !Doc.UserDoc().defaultToFlashcards,
}],
['time', {
- checkResult: (doc:Doc) => StrCast(doc?.cardSort),
- setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "time",
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "time",
+ setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort = "time",
}],
['docType', {
- checkResult: (doc:Doc) => StrCast(doc?.cardSort),
- setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "type",
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "type",
+ setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort = "type",
}],
['color', {
- checkResult: (doc:Doc) => StrCast(doc?.cardSort),
- setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "color",
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "color",
+ setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort = "color",
}],
-
['links', {
- checkResult: (doc:Doc) => StrCast(doc?.cardSort),
- setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "links",
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "links",
+ setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort = "links",
}],
-
['custom1', {
- checkResult: (doc:Doc) => StrCast(doc?.cardSort),
- setDoc: (doc, dv) => {
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "custom" && NumCast(doc?.customSortNumber) === 0,
+ setDoc: (doc: Doc, dv: DocumentView) => {
doc.cardSort = "custom";
doc.customSortNumber = 0;
+ doc.visibleGroupNumbers = new List<number>();
}
- }],
-
+ }],
['custom2', {
- checkResult: (doc:Doc) => StrCast(doc?.cardSort),
- setDoc: (doc, dv) => {
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "custom" && NumCast(doc?.customSortNumber) === 1,
+ setDoc: (doc: Doc, dv: DocumentView) => {
doc.cardSort = "custom";
doc.customSortNumber = 1;
- console.log(doc.customSortNumber + " numberrrrrrrr")
- } }],
-
+ doc.visibleGroupNumbers = new List<number>();
+ }
+ }],
['custom3', {
- checkResult: (doc:Doc) => StrCast(doc?.cardSort),
- setDoc: (doc, dv) => {
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "custom" && NumCast(doc?.customSortNumber) === 2,
+ setDoc: (doc: Doc, dv: DocumentView) => {
doc.cardSort = "custom";
doc.customSortNumber = 2;
- } }],
+ doc.visibleGroupNumbers = new List<number>();
+ }
+ }],
['chat', {
- checkResult: (doc:Doc) => StrCast(doc?.cardSort),
- setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "chat",
+ checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "chat",
+ setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort = "chat",
+ }],
+ ['1', {
+ checkResult: (doc: Doc) => NumListCast(doc?.visibleGroupNumbers).includes(0),
+ setDoc: (doc: Doc, dv: DocumentView) => {
+ let list = NumListCast(doc.visibleGroupNumbers);
+ if (list.includes(0)) {
+ let newList = new List<number>(list.filter(d => d !== 0));
+ doc.visibleGroupNumbers = newList;
+ } else {
+ list.push(0);
+ doc.visibleGroupNumbers = new List<number>(list);
+ }
+ }
}],
- ]);
+ ['2', {
+ checkResult: (doc: Doc) => NumListCast(doc?.visibleGroupNumbers).includes(1),
+ setDoc: (doc: Doc, dv: DocumentView) => {
+ let list = NumListCast(doc.visibleGroupNumbers);
+ if (list.includes(1)) {
+ let newList = new List<number>(list.filter(d => d !== 1));
+ doc.visibleGroupNumbers = newList;
+ } else {
+ list.push(1);
+ doc.visibleGroupNumbers = new List<number>(list);
+ }
+ }
+ }],
+ ['3', {
+ checkResult: (doc: Doc) => NumListCast(doc?.visibleGroupNumbers).includes(2),
+ setDoc: (doc: Doc, dv: DocumentView) => {
+ let list = NumListCast(doc.visibleGroupNumbers);
+ if (list.includes(2)) {
+ let newList = new List<number>(list.filter(d => d !== 2));
+ doc.visibleGroupNumbers = newList;
+ } else {
+ list.push(2);
+ doc.visibleGroupNumbers = new List<number>(list);
+ }
+ }
+ }],
+ ['4', {
+ checkResult: (doc: Doc) => NumListCast(doc?.visibleGroupNumbers).includes(3),
+ setDoc: (doc: Doc, dv: DocumentView) => {
+ let list = NumListCast(doc.visibleGroupNumbers);
+ if (list.includes(3)) {
+ let newList = new List<number>(list.filter(d => d !== 3));
+ doc.visibleGroupNumbers = newList;
+ } else {
+ list.push(3);
+ doc.visibleGroupNumbers = new List<number>(list);
+ }
+ }
+ }],
+ ]);
if (checkResult) {
return map.get(attr)?.checkResult(selected);
@@ -194,6 +257,14 @@ ScriptingGlobals.add(function showFreeform(attr: 'flashcards' | 'center' | 'grid
setTimeout(() => batch.end(), 100);
});
+
+ScriptingGlobals.add(function isThatCardGroup(n: number){
+ const canvas = SelectionManager.Docs.lastElement();
+ return canvas.customSortNumber == n
+
+
+})
+
// ScriptingGlobals.add(function setCardSortAttr(attr: 'time' | 'docType' | 'color', value: any, checkResult?: boolean) {
// // const editorView = RichTextMenu.Instance?.TextView?.EditorView;
// const selected = SelectionManager.Docs.lastElement();
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.scss b/src/client/views/pdf/GPTPopup/GPTPopup.scss
index 4425cf158..551c8e5af 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.scss
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.scss
@@ -55,10 +55,10 @@ $highlightedText: #82e0ff;
overflow-y: auto;
}
- .btns-wrapper {
+ .btns-wrapper-gpt {
height: 50px;
display: flex;
- justify-content: space-between;
+ justify-content: center;
align-items: center;
transform: translateY(30px);
@@ -76,6 +76,8 @@ $highlightedText: #82e0ff;
display: flex;
align-items: center;
}
+
+
}
button {
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index faf66af85..d94be1860 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -154,6 +154,13 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
}
@observable onSortComplete?: (sortResult: string) => void;
+ @observable cardsDoneLoading = false;
+
+ @action setCardsDoneLoading(done: boolean) {
+ console.log(done + "HI HIHI")
+ this.cardsDoneLoading = done;
+ }
+
@@ -169,12 +176,14 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
this.setSortDone(false);
try {
- const res = await gptAPICall(this.sortPrompt + this.sortDesc, GPTCallType.SORT);
+
+ const res = await gptAPICall(this.sortDesc, GPTCallType.SORT);
this.setSortText(res || 'Something went wrong :(');
// Trigger the callback with the result
if (this.onSortComplete) {
this.onSortComplete(res || 'Something went wrong :(');
+ console.log(res)
}
} catch (err) {
console.error(err);
@@ -313,52 +322,63 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
{this.heading("SORTING")}
{this.loading ? (
<div className="content-wrapper">
- <div className="loading-spinner">
- <ReactLoading type="spin" color="#000" height={30} width={30} />
- <span>Loading...</span>
- </div>
- </div>
- ) : !this.sortDone && (
- <div className="btns-wrapper">
- <input
- defaultValue=""
- autoComplete="off"
- onChange={this.setSortPrompt}
- onKeyDown={e => {
- if (e.key === 'Enter') {
- this.generateSort();
- }
- e.stopPropagation();
- }}
- type="text"
- placeholder="Enter sorting instructions..."
- id="search-input"
- className="searchBox-input"
- style={{ width: "100%" }}
- />
+ <div className="loading-spinner">
+ <ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} height={30} width={30} />
+ <span>Loading...</span>
</div>
- )}
+ </div>
+ ) : (
+ <>
+ {!this.cardsDoneLoading ? (
+ <div className="content-wrapper">
+ <div className="loading-spinner">
+ <ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} height={30} width={30} />
+ <span>Reading Cards...</span>
+ </div>
+ </div>
+ ) : (
+ !this.sortDone && (
+ <div className="btns-wrapper-gpt">
+ <Button
+ tooltip="Have ChatGPT sort your cards for you!"
+ text="Sort!"
+ onClick={this.generateSort}
+ color={StrCast(Doc.UserDoc().userVariantColor)}
+ type={Type.TERT}
+ style={{
+ width: '90%', // Almost as wide as the container
+ textAlign: 'center',
+ color: '#ffffff', // White text
+ fontSize: '16px' // Adjust font size as needed
+ }}
+ />
+ </div>
+ )
+ )}
- {this.sortDone && (
- <div>
- <div className="content-wrapper">
-
- <p>{this.text== "Something went wrong :(" ? "Something went wrong :(" : "Sorting done! Feel free to move things around / regenerate :) !"}</p>
-
-
- <IconButton
- tooltip="Generate Again"
- onClick={() => this.setSortDone(false)}
- icon={<FontAwesomeIcon icon="redo-alt" size="lg" />}
- color={StrCast(Doc.UserDoc().userVariantColor)}
- />
-
- </div>
- </div>
+ {this.sortDone && (
+ <div>
+ <div className="content-wrapper">
+ <p>
+ {this.text === "Something went wrong :(" ?
+ "Something went wrong :(" :
+ "Sorting done! Feel free to move things around / regenerate :) !"}
+ </p>
+ <IconButton
+ tooltip="Generate Again"
+ onClick={() => this.setSortDone(false)}
+ icon={<FontAwesomeIcon icon="redo-alt" size="lg" />}
+ color={StrCast(Doc.UserDoc().userVariantColor)}
+ />
+ </div>
+ </div>
+ )}
+ </>
)}
</div>
</>
);
+