Skip to content

Commit 12bfdab

Browse files
committed
feat: enhance host management logic in competition rooms
1 parent 4f16fb4 commit 12bfdab

1 file changed

Lines changed: 65 additions & 21 deletions

File tree

src/routes/(app)/compete/[roomId]/+page.svelte

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,20 @@
2424
email?: string; // Add email for stable identification
2525
}
2626
27+
// Interface for room state
28+
interface RoomState {
29+
hostId: string | null;
30+
creationTime: number;
31+
}
32+
2733
let roomId = page.params.roomId;
2834
let isCompetitionActive = $state(false);
2935
let participants = $state<Participant[]>([]);
3036
let error = $state<string | null>(null);
3137
let loading = $state(true);
3238
let creatorId = $state<string | null>(null);
3339
let roomCreationTime = $state<number>(Date.now()); // Track room creation time
40+
let roomState = $state<RoomState>({ hostId: null, creationTime: Date.now() });
3441
3542
// Agora related variables - only need client and tracks
3643
let agoraClient = $state<IAgoraRTCClient | null>(null);
@@ -183,12 +190,28 @@
183190
console.log(`[AGORA] Removed user ${user.uid} from remoteUsers`);
184191
}
185192
193+
// Check if the host left
194+
const userIdStr = user.uid.toString();
195+
const wasHost = participants.find((p) => p.userId === userIdStr && p.isHost);
196+
186197
// Remove from participants
187-
participants = participants.filter((p) => p.userId !== user.uid.toString());
198+
participants = participants.filter((p) => p.userId !== userIdStr);
188199
console.log(
189200
`[AGORA] Removed user ${user.uid} from participants, remaining: ${participants.length}`
190201
);
191202
203+
// If the host left, assign a new host
204+
if (wasHost && participants.length > 0) {
205+
// Select the participant who has been in the room the longest
206+
const oldestParticipant = participants[0];
207+
oldestParticipant.isHost = true;
208+
roomState.hostId = oldestParticipant.userId;
209+
210+
// Update participants to trigger reactivity
211+
participants = [...participants];
212+
console.log(`[AGORA] Host left, assigned ${oldestParticipant.name} as new host`);
213+
}
214+
192215
updateRankings();
193216
});
194217
@@ -252,37 +275,56 @@
252275
}
253276
});
254277
255-
// Determine host - first joiner or based on email if authentication is used
256-
let isCurrentUserHost = false;
278+
// Improved host determination logic
279+
let shouldBeHost = false;
257280
const userEmail = $session.data?.user?.email;
258281
259-
if (remoteUsersList.length === 0) {
260-
// First user to join becomes host
261-
isCurrentUserHost = true;
262-
console.log(`[AGORA] No other users found, setting self as host`);
263-
} else {
264-
// Check participants to see if there's already a host
265-
const existingHost = participants.find(p => p.isHost);
266-
267-
// If no host is set yet, the first authenticated user becomes host
268-
if (!existingHost && userEmail) {
269-
isCurrentUserHost = true;
270-
console.log(`[AGORA] No host exists yet, setting authenticated user as host`);
282+
// Get existing host if any
283+
const existingHost = participants.find((p) => p.isHost);
284+
285+
if (!existingHost) {
286+
// No existing host found
287+
if (remoteUsersList.length === 0) {
288+
// First user in the room becomes host
289+
shouldBeHost = true;
290+
roomState.hostId = uid.toString();
291+
roomState.creationTime = Date.now();
292+
console.log(`[AGORA] First user in room, becoming host`);
293+
} else {
294+
// There are other users but no host yet (possible during initialization)
295+
// Wait a moment to check if any other user is claiming host status
296+
shouldBeHost = false;
297+
console.log(`[AGORA] Other users present but no host, waiting to determine host`);
298+
299+
// We'll check again after a delay to see if a host appeared
300+
setTimeout(() => {
301+
const delayedHostCheck = participants.find((p) => p.isHost);
302+
if (!delayedHostCheck && participants.length > 0) {
303+
// Still no host, make the first participant the host
304+
const firstParticipant = participants[0];
305+
firstParticipant.isHost = true;
306+
roomState.hostId = firstParticipant.userId;
307+
participants = [...participants]; // Trigger reactivity
308+
console.log(`[AGORA] Assigned ${firstParticipant.name} as host after delay`);
309+
}
310+
}, 3000);
271311
}
312+
} else {
313+
// Host already exists, respect that
314+
console.log(`[AGORA] Host already exists: ${existingHost.name}`);
315+
roomState.hostId = existingHost.userId;
272316
}
273317
274318
// Add current user to participants
275319
const userName = $session.data?.user?.name || `You (${uid})`;
276320
participants = [
277-
...participants
278-
.filter((p) => p.userId !== uid.toString())
279-
.map((p) => ({ ...p })),
321+
...participants.filter((p) => p.userId !== uid.toString()).map((p) => ({ ...p })),
280322
{
281323
userId: uid.toString(),
282324
name: userName,
283325
image: $session.data?.user?.image ?? undefined,
284326
email: userEmail,
285-
isHost: isCurrentUserHost
327+
isHost: shouldBeHost
286328
}
287329
];
288330
@@ -483,8 +525,10 @@
483525
// Determine if current user is host
484526
let isHost = $derived(() => {
485527
const currentUserId = agoraClient?.uid?.toString();
486-
const currentUserParticipant = participants.find(p => p.userId === currentUserId);
487-
return !!currentUserParticipant?.isHost;
528+
// Check both the participant list and roomState to determine host status
529+
const isHostInParticipants = participants.some((p) => p.userId === currentUserId && p.isHost);
530+
const isHostInState = roomState.hostId === currentUserId;
531+
return isHostInParticipants || isHostInState;
488532
});
489533
</script>
490534

0 commit comments

Comments
 (0)