feat(FN-1746): merge fusion/fn-1746
This commit is contained in:
@@ -29,6 +29,7 @@ class BadgeWebSocketStore {
|
||||
private reconnectDelayMs = 1_000;
|
||||
private shouldReconnect = false;
|
||||
private isConnected = false;
|
||||
private projectId: string | null = null;
|
||||
private snapshot: StoreSnapshot = {
|
||||
badgeUpdates: new Map(),
|
||||
isConnected: false,
|
||||
@@ -45,6 +46,34 @@ class BadgeWebSocketStore {
|
||||
return this.snapshot;
|
||||
}
|
||||
|
||||
setProjectId(projectId: string | null): void {
|
||||
if (this.projectId === projectId) return;
|
||||
|
||||
const hadSubscriptions = this.subscriptionsByTask.size > 0;
|
||||
// Collect all (hookId, taskId) pairs that were subscribed
|
||||
const previousSubscriptions: Array<{ hookId: string; taskId: string }> = [];
|
||||
for (const [taskId, subscribers] of this.subscriptionsByTask) {
|
||||
for (const hookId of subscribers) {
|
||||
previousSubscriptions.push({ hookId, taskId });
|
||||
}
|
||||
}
|
||||
|
||||
this.projectId = projectId;
|
||||
this.reset();
|
||||
|
||||
// Re-subscribe to all previous subscriptions after project change
|
||||
// This ensures badge subscriptions survive project switches
|
||||
// Note: we restore subscriptions BEFORE calling connect() so that
|
||||
// onopen will send the subscribe messages over the new socket
|
||||
if (hadSubscriptions) {
|
||||
for (const { hookId, taskId } of previousSubscriptions) {
|
||||
this.subscriptionsByTask.set(taskId, new Set([hookId]));
|
||||
}
|
||||
this.shouldReconnect = this.subscriptionsByTask.size > 0;
|
||||
this.connect();
|
||||
}
|
||||
}
|
||||
|
||||
subscribeTask(hookId: string, taskId: string): void {
|
||||
const subscribers = this.subscriptionsByTask.get(taskId) ?? new Set<string>();
|
||||
const beforeSize = subscribers.size;
|
||||
@@ -101,7 +130,11 @@ class BadgeWebSocketStore {
|
||||
}
|
||||
|
||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
||||
const ws = new WebSocket(`${protocol}//${window.location.host}/api/ws`);
|
||||
let url = `${protocol}//${window.location.host}/api/ws`;
|
||||
if (this.projectId) {
|
||||
url += `?projectId=${encodeURIComponent(this.projectId)}`;
|
||||
}
|
||||
const ws = new WebSocket(url);
|
||||
this.ws = ws;
|
||||
|
||||
ws.onopen = () => {
|
||||
@@ -216,7 +249,7 @@ function hasMessageField(message: BadgeUpdatedMessage, field: "prInfo" | "issueI
|
||||
return Object.prototype.hasOwnProperty.call(message, field);
|
||||
}
|
||||
|
||||
export function useBadgeWebSocket(): {
|
||||
export function useBadgeWebSocket(projectId?: string): {
|
||||
badgeUpdates: Map<string, BadgeSnapshot>;
|
||||
isConnected: boolean;
|
||||
subscribeToBadge: (taskId: string) => void;
|
||||
@@ -240,6 +273,11 @@ export function useBadgeWebSocket(): {
|
||||
badgeWebSocketStore.unsubscribeTask(hookIdRef.current!, taskId);
|
||||
}, []);
|
||||
|
||||
// Update project context when projectId changes
|
||||
useEffect(() => {
|
||||
badgeWebSocketStore.setProjectId(projectId ?? null);
|
||||
}, [projectId]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
badgeWebSocketStore.cleanupHook(hookIdRef.current!);
|
||||
|
||||
Reference in New Issue
Block a user