mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-07 13:23:15 +00:00
Get Conversation session action buttons out from under the three dot menu
This commit is contained in:
@@ -461,8 +461,8 @@ export class KhojChatView extends KhojPaneView {
|
|||||||
this.renderMessage(chatBodyEl, "Hey 👋🏾, what's up?", "khoj");
|
this.renderMessage(chatBodyEl, "Hey 👋🏾, what's up?", "khoj");
|
||||||
}
|
}
|
||||||
|
|
||||||
async toggleChatSessions(chatBodyEl: HTMLElement): Promise<boolean> {
|
async toggleChatSessions(chatBodyEl: HTMLElement, forceShow: boolean = false): Promise<boolean> {
|
||||||
if (this.contentEl.getElementsByClassName("side-panel")?.length > 0) {
|
if (!forceShow && this.contentEl.getElementsByClassName("side-panel")?.length > 0) {
|
||||||
chatBodyEl.innerHTML = "";
|
chatBodyEl.innerHTML = "";
|
||||||
return this.getChatHistory(chatBodyEl);
|
return this.getChatHistory(chatBodyEl);
|
||||||
}
|
}
|
||||||
@@ -497,42 +497,61 @@ export class KhojChatView extends KhojPaneView {
|
|||||||
let conversation = responseJson[key];
|
let conversation = responseJson[key];
|
||||||
let conversationSessionEl = this.contentEl.createEl('div');
|
let conversationSessionEl = this.contentEl.createEl('div');
|
||||||
let incomingConversationId = conversation["conversation_id"];
|
let incomingConversationId = conversation["conversation_id"];
|
||||||
const conversationTitle = conversation["slug"] || `New conversation 🌱`;
|
|
||||||
conversationSessionEl.textContent = conversationTitle;
|
|
||||||
conversationSessionEl.classList.add("conversation-session");
|
conversationSessionEl.classList.add("conversation-session");
|
||||||
if (incomingConversationId == conversationId) {
|
if (incomingConversationId == conversationId) {
|
||||||
conversationSessionEl.classList.add("selected-conversation");
|
conversationSessionEl.classList.add("selected-conversation");
|
||||||
}
|
}
|
||||||
conversationSessionEl.addEventListener('click', () => {
|
const conversationTitle = conversation["slug"] || `New conversation 🌱`;
|
||||||
|
const conversationSessionTitleEl = conversationSessionEl.createDiv("conversation-session-title");
|
||||||
|
conversationSessionTitleEl.textContent = conversationTitle;
|
||||||
|
conversationSessionTitleEl.addEventListener('click', () => {
|
||||||
chatBodyEl.innerHTML = "";
|
chatBodyEl.innerHTML = "";
|
||||||
chatBodyEl.dataset.conversationId = incomingConversationId;
|
chatBodyEl.dataset.conversationId = incomingConversationId;
|
||||||
chatBodyEl.dataset.conversationTitle = conversationTitle;
|
chatBodyEl.dataset.conversationTitle = conversationTitle;
|
||||||
this.getChatHistory(chatBodyEl);
|
this.getChatHistory(chatBodyEl);
|
||||||
});
|
});
|
||||||
let threeDotMenuEl = this.contentEl.createEl('div');
|
|
||||||
threeDotMenuEl.classList.add("three-dot-menu");
|
|
||||||
let threeDotMenuButton = this.contentEl.createEl('button');
|
|
||||||
threeDotMenuButton.innerHTML = "⋮";
|
|
||||||
threeDotMenuButton.classList.add("three-dot-menu-button");
|
|
||||||
threeDotMenuButton.addEventListener('click', (event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
let existingChildren = threeDotMenuEl.children;
|
|
||||||
if (existingChildren.length > 1) {
|
|
||||||
// Skip deleting the first, since that's the menu button.
|
|
||||||
for (let i = 1; i < existingChildren.length; i++) {
|
|
||||||
existingChildren[i].remove();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let conversationMenuEl = this.contentEl.createEl('div');
|
let conversationMenuEl = this.contentEl.createEl('div');
|
||||||
|
conversationMenuEl = this.addConversationMenu(
|
||||||
|
conversationMenuEl,
|
||||||
|
conversationSessionEl,
|
||||||
|
conversationTitle,
|
||||||
|
conversationSessionTitleEl,
|
||||||
|
chatBodyEl,
|
||||||
|
incomingConversationId,
|
||||||
|
incomingConversationId == conversationId,
|
||||||
|
);
|
||||||
|
|
||||||
|
conversationSessionEl.appendChild(conversationMenuEl);
|
||||||
|
conversationListBodyEl.appendChild(conversationSessionEl);
|
||||||
|
chatBodyEl.appendChild(sidePanelEl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
addConversationMenu(
|
||||||
|
conversationMenuEl: HTMLDivElement,
|
||||||
|
conversationSessionEl: HTMLElement,
|
||||||
|
conversationTitle: string,
|
||||||
|
conversationSessionTitleEl: HTMLElement,
|
||||||
|
chatBodyEl: HTMLElement,
|
||||||
|
incomingConversationId: string,
|
||||||
|
selectedConversation: boolean,
|
||||||
|
) {
|
||||||
conversationMenuEl.classList.add("conversation-menu");
|
conversationMenuEl.classList.add("conversation-menu");
|
||||||
|
|
||||||
|
const headers = { 'Authorization': `Bearer ${this.setting.khojApiKey}` };
|
||||||
|
|
||||||
let editConversationTitleButtonEl = this.contentEl.createEl('button');
|
let editConversationTitleButtonEl = this.contentEl.createEl('button');
|
||||||
editConversationTitleButtonEl.innerHTML = "Rename";
|
setIcon(editConversationTitleButtonEl, "edit");
|
||||||
|
editConversationTitleButtonEl.title = "Rename";
|
||||||
editConversationTitleButtonEl.classList.add("edit-title-button");
|
editConversationTitleButtonEl.classList.add("edit-title-button");
|
||||||
editConversationTitleButtonEl.classList.add("three-dot-menu-button-item");
|
editConversationTitleButtonEl.classList.add("three-dot-menu-button-item");
|
||||||
|
if (selectedConversation) editConversationTitleButtonEl.classList.add("selected-conversation");
|
||||||
editConversationTitleButtonEl.addEventListener('click', (event) => {
|
editConversationTitleButtonEl.addEventListener('click', (event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
@@ -544,8 +563,6 @@ export class KhojChatView extends KhojPaneView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a dialog box to get new title for conversation
|
// Create a dialog box to get new title for conversation
|
||||||
let editConversationTitleInputBoxEl = this.contentEl.createEl('div');
|
|
||||||
editConversationTitleInputBoxEl.classList.add("conversation-title-input-box");
|
|
||||||
let editConversationTitleInputEl = this.contentEl.createEl('input');
|
let editConversationTitleInputEl = this.contentEl.createEl('input');
|
||||||
editConversationTitleInputEl.classList.add("conversation-title-input");
|
editConversationTitleInputEl.classList.add("conversation-title-input");
|
||||||
editConversationTitleInputEl.value = conversationTitle;
|
editConversationTitleInputEl.value = conversationTitle;
|
||||||
@@ -559,9 +576,10 @@ export class KhojChatView extends KhojPaneView {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
let editConversationTitleSaveButtonEl = this.contentEl.createEl('button');
|
let editConversationTitleSaveButtonEl = this.contentEl.createEl('button');
|
||||||
editConversationTitleInputBoxEl.appendChild(editConversationTitleInputEl);
|
conversationSessionTitleEl.replaceWith(editConversationTitleInputEl);
|
||||||
editConversationTitleSaveButtonEl.innerHTML = "Save";
|
editConversationTitleSaveButtonEl.innerHTML = "Save";
|
||||||
editConversationTitleSaveButtonEl.classList.add("three-dot-menu-button-item");
|
editConversationTitleSaveButtonEl.classList.add("three-dot-menu-button-item");
|
||||||
|
if (selectedConversation) editConversationTitleSaveButtonEl.classList.add("selected-conversation");
|
||||||
editConversationTitleSaveButtonEl.addEventListener('click', (event) => {
|
editConversationTitleSaveButtonEl.addEventListener('click', (event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
let newTitle = editConversationTitleInputEl.value;
|
let newTitle = editConversationTitleInputEl.value;
|
||||||
@@ -570,25 +588,46 @@ export class KhojChatView extends KhojPaneView {
|
|||||||
fetch(`${this.setting.khojUrl}${editURL}`, { method: "PATCH", headers })
|
fetch(`${this.setting.khojUrl}${editURL}`, { method: "PATCH", headers })
|
||||||
.then(response => response.ok ? response.json() : Promise.reject(response))
|
.then(response => response.ok ? response.json() : Promise.reject(response))
|
||||||
.then(data => {
|
.then(data => {
|
||||||
conversationSessionEl.textContent = newTitle;
|
conversationSessionTitleEl.textContent = newTitle;
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
editConversationTitleInputBoxEl.remove();
|
const conversationSessionTitleEl = conversationSessionEl.createDiv("conversation-session-title");
|
||||||
|
conversationSessionTitleEl.textContent = newTitle;
|
||||||
|
conversationSessionTitleEl.addEventListener('click', () => {
|
||||||
|
chatBodyEl.innerHTML = "";
|
||||||
|
chatBodyEl.dataset.conversationId = incomingConversationId;
|
||||||
|
chatBodyEl.dataset.conversationTitle = conversationTitle;
|
||||||
|
this.getChatHistory(chatBodyEl);
|
||||||
|
});
|
||||||
|
|
||||||
|
let newConversationMenuEl = this.contentEl.createEl('div');
|
||||||
|
newConversationMenuEl = this.addConversationMenu(
|
||||||
|
newConversationMenuEl,
|
||||||
|
conversationSessionEl,
|
||||||
|
newTitle,
|
||||||
|
conversationSessionTitleEl,
|
||||||
|
chatBodyEl,
|
||||||
|
incomingConversationId,
|
||||||
|
selectedConversation,
|
||||||
|
);
|
||||||
|
|
||||||
|
conversationMenuEl.replaceWith(newConversationMenuEl);
|
||||||
|
editConversationTitleInputEl.replaceWith(conversationSessionTitleEl);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
editConversationTitleInputBoxEl.appendChild(editConversationTitleSaveButtonEl);
|
conversationMenuEl.appendChild(editConversationTitleSaveButtonEl);
|
||||||
conversationMenuEl.appendChild(editConversationTitleInputBoxEl);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
conversationMenuEl.appendChild(editConversationTitleButtonEl);
|
conversationMenuEl.appendChild(editConversationTitleButtonEl);
|
||||||
threeDotMenuEl.appendChild(conversationMenuEl);
|
|
||||||
|
|
||||||
let deleteConversationButtonEl = this.contentEl.createEl('button');
|
let deleteConversationButtonEl = this.contentEl.createEl('button');
|
||||||
deleteConversationButtonEl.innerHTML = "Delete";
|
setIcon(deleteConversationButtonEl, "trash");
|
||||||
|
deleteConversationButtonEl.title = "Delete";
|
||||||
deleteConversationButtonEl.classList.add("delete-conversation-button");
|
deleteConversationButtonEl.classList.add("delete-conversation-button");
|
||||||
deleteConversationButtonEl.classList.add("three-dot-menu-button-item");
|
deleteConversationButtonEl.classList.add("three-dot-menu-button-item");
|
||||||
|
if (selectedConversation) deleteConversationButtonEl.classList.add("selected-conversation");
|
||||||
deleteConversationButtonEl.addEventListener('click', () => {
|
deleteConversationButtonEl.addEventListener('click', () => {
|
||||||
// Ask for confirmation before deleting chat session
|
// Ask for confirmation before deleting chat session
|
||||||
let confirmation = confirm('Are you sure you want to delete this chat session?');
|
let confirmation = confirm('Are you sure you want to delete this chat session?');
|
||||||
@@ -600,7 +639,7 @@ export class KhojChatView extends KhojPaneView {
|
|||||||
chatBodyEl.innerHTML = "";
|
chatBodyEl.innerHTML = "";
|
||||||
chatBodyEl.dataset.conversationId = "";
|
chatBodyEl.dataset.conversationId = "";
|
||||||
chatBodyEl.dataset.conversationTitle = "";
|
chatBodyEl.dataset.conversationTitle = "";
|
||||||
this.getChatHistory(chatBodyEl);
|
this.toggleChatSessions(chatBodyEl, true);
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
return;
|
return;
|
||||||
@@ -608,18 +647,7 @@ export class KhojChatView extends KhojPaneView {
|
|||||||
});
|
});
|
||||||
|
|
||||||
conversationMenuEl.appendChild(deleteConversationButtonEl);
|
conversationMenuEl.appendChild(deleteConversationButtonEl);
|
||||||
threeDotMenuEl.appendChild(conversationMenuEl);
|
return conversationMenuEl;
|
||||||
});
|
|
||||||
threeDotMenuEl.appendChild(threeDotMenuButton);
|
|
||||||
conversationSessionEl.appendChild(threeDotMenuEl);
|
|
||||||
conversationListBodyEl.appendChild(conversationSessionEl);
|
|
||||||
chatBodyEl.appendChild(sidePanelEl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getChatHistory(chatBodyEl: HTMLElement): Promise<boolean> {
|
async getChatHistory(chatBodyEl: HTMLElement): Promise<boolean> {
|
||||||
|
|||||||
@@ -240,10 +240,22 @@ img {
|
|||||||
max-width: 60%;
|
max-width: 60%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.new-conversation {
|
||||||
|
display: grid;
|
||||||
|
grid-auto-flow: column;
|
||||||
|
grid-template-columns: 1fr auto;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
div.conversation-header-title {
|
||||||
|
text-align: left;
|
||||||
|
font-size: larger;
|
||||||
|
line-height: 1.5em;
|
||||||
|
}
|
||||||
div.conversation-session {
|
div.conversation-session {
|
||||||
color: var(--color-base-90);
|
color: var(--color-base-90);
|
||||||
border: 1px solid var(--khoj-storm-grey);
|
border: 1px solid var(--khoj-storm-grey);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
margin-top: 8px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
@@ -264,9 +276,11 @@ div.conversation-session {
|
|||||||
/* position: relative; */
|
/* position: relative; */
|
||||||
}
|
}
|
||||||
|
|
||||||
button.three-dot-menu-button-item {
|
button.selected-conversation {
|
||||||
background: var(--khoj-winter-sun);
|
background: var(--khoj-winter-sun);
|
||||||
color: var(--khoj-storm-grey);
|
}
|
||||||
|
button.three-dot-menu-button-item {
|
||||||
|
color: var(--color-base-90);
|
||||||
border: none;
|
border: none;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -307,11 +321,8 @@ div.conversation-menu {
|
|||||||
top: 100%;
|
top: 100%;
|
||||||
right: 0;
|
right: 0;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
background-color: var(--khoj-winter-sun);
|
|
||||||
border: 1px solid var(--khoj-storm-grey);
|
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
box-shadow: 0 0 11px #aaa;
|
|
||||||
}
|
}
|
||||||
div.conversation-session:hover {
|
div.conversation-session:hover {
|
||||||
transform: scale(1.03);
|
transform: scale(1.03);
|
||||||
|
|||||||
Reference in New Issue
Block a user