Merge pull request #28 from HueByte/dev_fix_ghost_channel_on_join

fix: ghost channel when trying to join a channel that doesn't exist
This commit is contained in:
Stone_Red
2026-02-24 21:47:53 +01:00
committed by GitHub
4 changed files with 12 additions and 10 deletions
+2
View File
@@ -15,6 +15,7 @@
- Fix thread safety — `_channelUsers` presence cache now protected by `Lock` to prevent races between SignalR events and background fetches
- Fix `@mention` regex matching email addresses and `#channel` regex matching hex colors / issue numbers — both now use lookbehind and letter-requirement guards
- Fix `ParseThemeColor` accepting non-hex characters — now validates `[0-9a-fA-F]` digits
- Fix ghost channel when trying to join a channel that doesn't exist
## New Features
@@ -38,6 +39,7 @@
- Extract `IUserService`/`UserService` — consolidate user registration, authentication, and profile management into a dedicated service, eliminating duplicated logic between `AuthController` and `ChatService`
- IRC gateway now checks ban status during authentication (previously skipped)
- EchoHubSpace directory updates — server now only sends user count when it actually changes instead of every 30 seconds
- `ChatHub.JoinChannel` now returns `JoinChannelResult` instead of `List<MessageDto>` to allow for better error handling
## Distribution
@@ -136,8 +136,10 @@ public sealed class EchoHubConnection : IAsyncDisposable
public async Task<List<MessageDto>> JoinChannelAsync(string channelName)
{
var messages = await _connection.InvokeAsync<List<MessageDto>>("JoinChannel", channelName);
return DecryptMessages(messages);
var result = await _connection.InvokeAsync<JoinChannelResult>("JoinChannel", channelName);
if (!result.Success)
throw new InvalidOperationException(result.Error ?? "Failed to join channel.");
return DecryptMessages(result.History);
}
public async Task LeaveChannelAsync(string channelName)
+2
View File
@@ -39,6 +39,8 @@ public record UpdateTopicRequest(string? Topic);
public record SendUrlRequest(string Url);
public record JoinChannelResult(bool Success, List<MessageDto> History, string? Error = null);
public record EmbedDto(
string? SiteName,
string? Title,
+4 -8
View File
@@ -56,7 +56,7 @@ public class ChatHub : Hub<IEchoHubClient>
}
}
public async Task<List<MessageDto>> JoinChannel(string channelName)
public async Task<JoinChannelResult> JoinChannel(string channelName)
{
try
{
@@ -64,19 +64,15 @@ public class ChatHub : Hub<IEchoHubClient>
Context.ConnectionId, CurrentUserId, CurrentUsername, channelName);
if (error is not null)
{
await Clients.Caller.Error(error);
return [];
}
return new JoinChannelResult(false, [], error);
await Groups.AddToGroupAsync(Context.ConnectionId, channelName.ToLowerInvariant().Trim());
return history;
return new JoinChannelResult(true, history);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error joining channel '{Channel}' for {User}", channelName, CurrentUsername);
await Clients.Caller.Error($"Failed to join channel: {ex.Message}");
return [];
return new JoinChannelResult(false, [], $"Failed to join channel: {ex.Message}");
}
}