Skip to content

Commit e6f3563

Browse files
fix: PR button links to current thread instead of creating a new one
1 parent b107830 commit e6f3563

1 file changed

Lines changed: 36 additions & 47 deletions

File tree

crates/tauri-app/frontend/src/components/github/PrDashboard.tsx

Lines changed: 36 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -50,58 +50,46 @@ export function PrDashboard(props: Props) {
5050
}
5151
}
5252

53-
const [creatingPr, setCreatingPr] = createSignal<number | null>(null);
53+
const [linkingPr, setLinkingPr] = createSignal<number | null>(null);
5454

55-
async function createPrThread(pr: PullRequest) {
56-
if (creatingPr() === pr.number) return; // Prevent double-click
57-
setCreatingPr(pr.number);
58-
try {
59-
// Step 1: Create thread and store PR link in parallel
60-
const [thread] = await Promise.all([
61-
ipc.createThread(props.projectId, `PR #${pr.number}: ${pr.title}`, store.selectedProvider),
62-
]);
63-
64-
// Step 2: Switch to the new thread immediately (instant UI update)
65-
// Fire setSetting in background — no need to await it
66-
ipc.setSetting(`pr:${thread.id}`, String(pr.number)).catch((e) =>
67-
console.error("Failed to store PR link:", e)
68-
);
55+
async function linkPrToThread(pr: PullRequest) {
56+
const threadId = store.activeTab;
57+
if (!threadId || linkingPr() === pr.number) return;
58+
setLinkingPr(pr.number);
6959

60+
try {
61+
// Rename the current thread to reflect the PR
62+
await ipc.renameThread(threadId, `PR #${pr.number}: ${pr.title}`);
7063
setStore("projects", (projects) =>
71-
projects.map((p) =>
72-
p.id === props.projectId
73-
? { ...p, threads: [...p.threads, thread], collapsed: false }
74-
: p
75-
)
64+
projects.map((p) => ({
65+
...p,
66+
threads: p.threads.map((t) =>
67+
t.id === threadId ? { ...t, title: `PR #${pr.number}: ${pr.title}` } : t
68+
),
69+
}))
7670
);
77-
setStore("openTabs", (tabs) => [...tabs, thread.id]);
78-
setStore("activeTab", thread.id);
7971

80-
// Show a loading placeholder while the diff fetches
81-
const loadingMsgId = `loading-${crypto.randomUUID()}`;
82-
setStore("threadMessages", thread.id, [
83-
{ id: loadingMsgId, thread_id: thread.id, role: "system", content: "Fetching PR diff..." },
84-
]);
72+
// Store the PR link
73+
ipc.setSetting(`pr:${threadId}`, String(pr.number)).catch(() => {});
8574

86-
// Step 3: Fetch diff in the background, then replace the loading message
87-
ipc.getPrDiff(props.repoPath, pr.number).then(async (_diff) => {
88-
const context = `I'm working on PR #${pr.number}: "${pr.title}" by ${pr.author}\n\nBranch: ${pr.branch}${pr.base}\n+${pr.additions} -${pr.deletions} across ${pr.changed_files} files\n${pr.labels.length > 0 ? `Labels: ${pr.labels.join(", ")}\n` : ""}\nHere's the diff summary — help me review or continue work on this PR.`;
75+
// Update the PR map in the store
76+
setStore("projectPrMap", props.projectId, (map) => ({
77+
...(map || {}),
78+
[threadId]: pr.number,
79+
}));
8980

90-
const msgId = await ipc.persistUserMessage(thread.id, context);
91-
setStore("threadMessages", thread.id, [
92-
{ id: msgId, thread_id: thread.id, role: "user", content: context },
93-
]);
94-
}).catch((e) => {
95-
console.error("Failed to fetch PR diff:", e);
96-
// Replace loading message with error
97-
setStore("threadMessages", thread.id, [
98-
{ id: crypto.randomUUID(), thread_id: thread.id, role: "system", content: `Failed to fetch PR diff: ${e}` },
99-
]);
100-
});
81+
// Inject PR context as first message
82+
const context = `I'm working on PR #${pr.number}: "${pr.title}" by ${pr.author}\n\nBranch: ${pr.branch}${pr.base}\n+${pr.additions} -${pr.deletions} across ${pr.changed_files} files\n${pr.labels.length > 0 ? `Labels: ${pr.labels.join(", ")}\n` : ""}\nHelp me review or continue work on this PR.`;
83+
84+
const msgId = await ipc.persistUserMessage(threadId, context);
85+
setStore("threadMessages", threadId, (msgs) => [
86+
...(msgs || []),
87+
{ id: msgId, thread_id: threadId, role: "user" as const, content: context },
88+
]);
10189
} catch (e) {
102-
console.error("Failed to create PR thread:", e);
90+
console.error("Failed to link PR:", e);
10391
} finally {
104-
setCreatingPr(null);
92+
setLinkingPr(null);
10593
}
10694
}
10795

@@ -199,11 +187,12 @@ export function PrDashboard(props: Props) {
199187
</div>
200188
</Show>
201189
</div>
202-
<button class="prd-thread-btn" onClick={() => createPrThread(pr)} disabled={creatingPr() === pr.number} title="Create thread for this PR">
203-
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
204-
<line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" />
190+
<button class="prd-thread-btn" onClick={() => linkPrToThread(pr)} disabled={linkingPr() === pr.number} title="Link this PR to the current thread">
191+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
192+
<path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71" />
193+
<path d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71" />
205194
</svg>
206-
Thread
195+
{linkingPr() === pr.number ? "Linking…" : "Link"}
207196
</button>
208197
</div>
209198
);

0 commit comments

Comments
 (0)