mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 06:57:10 +00:00
Fix fork archive thread list refresh
This commit is contained in:
parent
52a7ed02a5
commit
0423cf899f
3 changed files with 43 additions and 6 deletions
|
|
@ -42,10 +42,12 @@ export class ChatThreadActionController {
|
|||
}
|
||||
|
||||
async archiveThread(threadId: string, saveMarkdown = this.host.settings().archiveExportEnabled): Promise<void> {
|
||||
await this.archiveThreadWithResult(threadId, saveMarkdown);
|
||||
if (await this.archiveThreadOnServer(threadId, saveMarkdown)) {
|
||||
this.host.notifyThreadArchived(threadId);
|
||||
}
|
||||
}
|
||||
|
||||
private async archiveThreadWithResult(threadId: string, saveMarkdown = this.host.settings().archiveExportEnabled): Promise<boolean> {
|
||||
private async archiveThreadOnServer(threadId: string, saveMarkdown = this.host.settings().archiveExportEnabled): Promise<boolean> {
|
||||
if (chatTurnBusy(this.state)) {
|
||||
this.host.addSystemMessage("Finish or interrupt the current turn before archiving threads.");
|
||||
return false;
|
||||
|
|
@ -64,7 +66,6 @@ export class ChatThreadActionController {
|
|||
new Notice(`Saved archived thread to ${result.path}.`);
|
||||
}
|
||||
await client.archiveThread(threadId);
|
||||
this.host.notifyThreadArchived(threadId);
|
||||
return true;
|
||||
} catch (error) {
|
||||
this.host.addSystemMessage(error instanceof Error ? error.message : String(error));
|
||||
|
|
@ -117,8 +118,9 @@ export class ChatThreadActionController {
|
|||
}
|
||||
if (archiveSource) {
|
||||
if (!openedForkPanel) return;
|
||||
const archived = await this.archiveThreadWithResult(threadId);
|
||||
if (archived) this.host.closePanel();
|
||||
if (!(await this.archiveThreadOnServer(threadId))) return;
|
||||
this.host.closePanel();
|
||||
this.host.notifyThreadArchived(threadId);
|
||||
}
|
||||
} catch (error) {
|
||||
this.host.addSystemMessage(error instanceof Error ? error.message : String(error));
|
||||
|
|
|
|||
|
|
@ -46,10 +46,11 @@ describe("ChatThreadActionController", () => {
|
|||
expect(client.rollbackThread).not.toHaveBeenCalled();
|
||||
expect(client.archiveThread).toHaveBeenCalledWith("source");
|
||||
expect(host.closePanel).not.toHaveBeenCalled();
|
||||
expect(host.notifyThreadArchived).not.toHaveBeenCalled();
|
||||
expect(host.addSystemMessage).toHaveBeenCalledWith("archive failed");
|
||||
});
|
||||
|
||||
it("closes the source panel after fork and archive succeeds", async () => {
|
||||
it("closes the source panel before notifying surfaces after fork and archive succeeds", async () => {
|
||||
const client = clientMock();
|
||||
const host = hostMock({ client, displayItems: turnItems() });
|
||||
const controller = new ChatThreadActionController(host);
|
||||
|
|
@ -58,6 +59,11 @@ describe("ChatThreadActionController", () => {
|
|||
|
||||
expect(client.archiveThread).toHaveBeenCalledWith("source");
|
||||
expect(host.closePanel).toHaveBeenCalledOnce();
|
||||
expect(host.notifyThreadArchived).toHaveBeenCalledWith("source");
|
||||
const closeOrder = host.closePanel.mock.invocationCallOrder[0];
|
||||
const notifyOrder = host.notifyThreadArchived.mock.invocationCallOrder[0];
|
||||
if (closeOrder === undefined || notifyOrder === undefined) throw new Error("Expected close and archive notification calls.");
|
||||
expect(closeOrder).toBeLessThan(notifyOrder);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -362,6 +362,35 @@ describe("CodexPanelPlugin boot restored panel loading", () => {
|
|||
expect(disconnectedRefresh).not.toHaveBeenCalled();
|
||||
expect(connectedRefresh).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("refreshes shared thread lists from a remaining connected panel after the archived panel is detached", async () => {
|
||||
const { CodexChatView } = await import("../src/features/chat/view");
|
||||
const sourceLeaf = leaf();
|
||||
sourceLeaf.view = chatView(CodexChatView, sourceLeaf);
|
||||
const sourceView = sourceLeaf.view as CodexChatView;
|
||||
vi.spyOn(sourceView, "openPanelSnapshot").mockReturnValue(panelSnapshot({ viewId: "source", threadId: "thread-1", connected: true }));
|
||||
const sourceRefresh = vi.spyOn(sourceView, "refreshSharedThreadList").mockResolvedValue(undefined);
|
||||
|
||||
const remainingLeaf = leaf();
|
||||
remainingLeaf.view = chatView(CodexChatView, remainingLeaf);
|
||||
const remainingView = remainingLeaf.view as CodexChatView;
|
||||
vi.spyOn(remainingView, "openPanelSnapshot").mockReturnValue(
|
||||
panelSnapshot({ viewId: "remaining", threadId: "forked-thread", connected: true }),
|
||||
);
|
||||
const remainingRefresh = vi.spyOn(remainingView, "refreshSharedThreadList").mockResolvedValue(undefined);
|
||||
|
||||
const leaves = [sourceLeaf, remainingLeaf];
|
||||
sourceLeaf.detach.mockImplementation(() => {
|
||||
leaves.splice(leaves.indexOf(sourceLeaf), 1);
|
||||
});
|
||||
const plugin = await pluginWithLeaves(leaves);
|
||||
|
||||
sourceLeaf.detach();
|
||||
plugin.notifyThreadArchived("thread-1");
|
||||
|
||||
expect(sourceRefresh).not.toHaveBeenCalled();
|
||||
expect(remainingRefresh).toHaveBeenCalledOnce();
|
||||
});
|
||||
});
|
||||
|
||||
async function pluginWithLeaves(leaves: ReturnType<typeof leaf>[]) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue