Skip to content

Conversation

@olivermrose
Copy link
Collaborator

Closes #63

Copilot AI review requested due to automatic review settings November 13, 2025 08:59
@olivermrose olivermrose added feature New feature or request ui Related to Svelte/UI lang: typescript labels Nov 13, 2025
@olivermrose olivermrose added this to the Beta milestone Nov 13, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a whispers (direct messaging) feature for the application, allowing users to send and receive private messages. The implementation includes UI components for viewing whisper conversations, managing message threads, and displaying unread message counts.

Key changes include:

  • New routes for viewing whisper lists and individual whisper conversations
  • Whisper model with message management and API integration
  • Global handler architecture to support whispers alongside channel-specific events
  • UI updates to the sidebar with unread whisper notifications

Reviewed Changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/routes/(main)/whispers/[id]/+page.ts Load function for individual whisper conversation (has data access issue)
src/routes/(main)/whispers/[id]/+page.svelte Chat UI for whisper conversations with message list and input
src/routes/(main)/whispers/+page.ts Load function for whisper list page
src/routes/(main)/whispers/+page.svelte UI for displaying whisper threads with relative timestamps
src/lib/models/whisper.svelte.ts New Whisper class for managing messages and sending whispers
src/lib/models/user.svelte.ts Added whispers map to User model
src/lib/models/index.ts Export whisper model
src/lib/handlers/irc/whisper.ts Handler for incoming whisper messages
src/lib/handlers/helper.ts Extended handler types to support global handlers
src/lib/twitch/irc.ts Added WhisperMessage type and BaseMessage interface
src/lib/managers/user-manager.ts Updated error message to use ErrorMessage helper
src/lib/app.svelte.ts Updated handler routing to support global vs channel handlers
src/routes/(main)/channels/[username]/+page.svelte Filter out global handlers from channel message processing
src/lib/components/Sidebar.svelte Added whispers button with unread count badge

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +38 to +54
await this.client.post("/whispers", {
params: {
from_user_id: app.user.id,
to_user_id: this.id,
},
body: {
message,
},
});

this.messages.push({
id: crypto.randomUUID(),
createdAt: new Date(),
badges: [],
user: app.user,
text: message,
});
Copy link

Copilot AI Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The send method doesn't handle API errors. If the client.post call fails (network error, authorization failure, etc.), the message is still added to the local messages array, creating a discrepancy between local state and the server. Consider wrapping the API call in a try-catch block and only adding the message after a successful response, or implement proper error handling and rollback.

Suggested change
await this.client.post("/whispers", {
params: {
from_user_id: app.user.id,
to_user_id: this.id,
},
body: {
message,
},
});
this.messages.push({
id: crypto.randomUUID(),
createdAt: new Date(),
badges: [],
user: app.user,
text: message,
});
try {
await this.client.post("/whispers", {
params: {
from_user_id: app.user.id,
to_user_id: this.id,
},
body: {
message,
},
});
this.messages.push({
id: crypto.randomUUID(),
createdAt: new Date(),
badges: [],
user: app.user,
text: message,
});
} catch (error) {
// Optionally handle the error (e.g., log, notify user)
console.error("Failed to send whisper:", error);
}

Copilot uses AI. Check for mistakes.
Comment on lines +31 to 35
if (handler.global === undefined) {
handler.global = false;
}

return handler;
Copy link

Copilot AI Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mutating handler.global by setting a default value modifies the input parameter, which is an anti-pattern. This could cause unexpected behavior if the same handler object is passed multiple times. Instead, use a default parameter or handle the undefined case in the return value without mutation: return { ...handler, global: handler.global ?? false };.

Suggested change
if (handler.global === undefined) {
handler.global = false;
}
return handler;
return { ...handler, global: handler.global ?? false };

Copilot uses AI. Check for mistakes.
olivermrose and others added 4 commits November 13, 2025 04:16
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@olivermrose olivermrose merged commit 848a7ca into main Nov 13, 2025
1 check passed
@olivermrose olivermrose deleted the feat/whispers branch November 13, 2025 09:19
This was referenced Nov 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request lang: typescript ui Related to Svelte/UI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Whispers

2 participants