wip: thread revamp
This commit is contained in:
1 parent
5b3f8b0f09
commit
9277b5a770
11 files changed
+401
-205
No files matched your search
+64
-3
@@ -79,6 +79,8 @@ export class ChatSession {
|
||||
this._rescroll = callback;
|
||||
}
|
||||
|
||||
// Call after changing the messages display length (change list or content)
|
||||
// It protects the scroll position in the document
|
||||
rescroll (options) {
|
||||
if (this._rescroll) this._rescroll(options);
|
||||
}
|
||||
@@ -117,7 +119,9 @@ export class ChatSession {
|
||||
this._unsubscribeChat = backend.onChatMessages(chatId, it => this.receiveMessage(it));
|
||||
this._unsubscribeRuns = runs.onChatMessage(chatId, event => this.trackRun(event));
|
||||
|
||||
const response = await backend.sendAction("get-chat-messages", {chatId});
|
||||
// Don't load all messages, only thread headers
|
||||
//const response = await backend.sendAction("get-chat-messages", {chatId});
|
||||
const response = await backend.sendAction("get-chat-thread-heads", {chatId});
|
||||
if (this.chatId != chatId) return;
|
||||
|
||||
// Always good to duplicate when assigning to a ref
|
||||
@@ -134,8 +138,7 @@ export class ChatSession {
|
||||
// otherwise start in "New Thread" state
|
||||
const lastMessage = response.messages[response.messages.length - 1];
|
||||
if (lastMessage && lastMessage.threadId != null && !isMessageStale(lastMessage)) {
|
||||
this.currentThreadId.value = lastMessage.threadId;
|
||||
this.isNewThread.value = false;
|
||||
this.activateThread(lastMessage.threadId);
|
||||
}
|
||||
|
||||
// Must happen on the same async-thread that sets `messages`
|
||||
@@ -317,6 +320,21 @@ export class ChatSession {
|
||||
// Continuing a thread: it becomes the one open thread
|
||||
this.currentThreadId.value = threadId;
|
||||
this.isNewThread.value = false;
|
||||
|
||||
// Load thread messages asynchronously
|
||||
backend.sendAction("get-thread-messages", {
|
||||
chatId: this.chatId, threadId
|
||||
}).then(res => {
|
||||
this.addMessageBulk(res.messages.map(it => ({
|
||||
id: it.id,
|
||||
type: it.kind,
|
||||
format: it.format,
|
||||
subkind: it.subkind,
|
||||
sender: it.sender,
|
||||
content: it.content,
|
||||
threadId: it.threadId,
|
||||
})));
|
||||
});
|
||||
this.rescroll();
|
||||
}
|
||||
|
||||
@@ -327,6 +345,49 @@ export class ChatSession {
|
||||
this.rescroll();
|
||||
}
|
||||
|
||||
// Adds a bulk of messages to the message list, in their correct
|
||||
// chronological position and replacing duplicates
|
||||
addMessageBulk (messages) {
|
||||
const list = this.messages.value;
|
||||
|
||||
for (let message of messages) {
|
||||
const id = message.id;
|
||||
|
||||
// Replace an already-known message in place
|
||||
const existingIndex = list.findIndex(it => it.id == id);
|
||||
if (existingIndex >= 0) {
|
||||
list[existingIndex] = message;
|
||||
continue;
|
||||
}
|
||||
|
||||
// An unsent user message echoed back with an id: adopt it
|
||||
if (message.sender == 'user') {
|
||||
const unsentIndex = this.unsentMessages.value.findIndex(
|
||||
it => it.content == message.content
|
||||
);
|
||||
if (unsentIndex >= 0) {
|
||||
this.unsentMessages.value.splice(unsentIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Insert after the last message known to belong to the same thread,
|
||||
// keeping each thread's messages contiguous and ordered
|
||||
let insertIndex = -1;
|
||||
for (let i = list.length - 1; i >= 0; i--) {
|
||||
if (list[i].threadId != null && list[i].threadId == message.threadId) {
|
||||
insertIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (insertIndex < 0) insertIndex = list.length;
|
||||
list.splice(insertIndex, 0, message);
|
||||
}
|
||||
|
||||
// Refs need reassignment to notify watchers; duplicate the list
|
||||
this.messages.value = list.slice();
|
||||
}
|
||||
|
||||
|
||||
// === Entry Computation === //
|
||||
|
||||
|
||||
@@ -114,8 +114,9 @@
|
||||
async function chatEntryContextMenu (message, logMeta) {
|
||||
let entries = [
|
||||
{value: 'pin', title: "Pin message"},
|
||||
{value: 'edit', title: "Edit message"},
|
||||
{value: 'start-thread', title: "Start thread from here"},
|
||||
{value: 'edit', title: "Edit in-place"},
|
||||
{value: 'edit-fork', title: "Edit in new thread"},
|
||||
//{value: 'start-thread', title: "Start thread from here"},
|
||||
];
|
||||
|
||||
// Long logs can be expanded/collapsed
|
||||
@@ -136,8 +137,8 @@
|
||||
editMessage(message);
|
||||
break;
|
||||
}
|
||||
case 'start-thread': {
|
||||
alert("Start Thread (TODO)");
|
||||
case 'edit-fork': {
|
||||
editMessage(message, true);
|
||||
break;
|
||||
}
|
||||
case 'toggle-log': {
|
||||
|
||||
Reference in new issue
Block a user