mirror of
https://github.com/Stone-Red-Code/EchoHub.git
synced 2026-09-04 09:06:07 +02:00
- Updated IrcBroadcaster to use constructor injection for IrcGatewayService. - Refactored JwtTokenService to initialize configuration values in the constructor. - Modified AuthController to use constructor injection for EchoHubDbContext and JwtTokenService. - Refactored ChannelsController to utilize constructor injection for dependencies. - Updated FilesController to use constructor injection for FileStorageService. - Refactored ServerController to initialize EchoHubDbContext and IConfiguration via constructor. - Modified UsersController to use constructor injection for EchoHubDbContext and ImageToAsciiService. - Updated EchoHubDbContext to use constructor for DbContextOptions. - Refactored ChatHub to use constructor injection for IChatService and ILogger. - Modified ChatService to utilize constructor injection for dependencies. - Refactored ServerDirectoryService to use constructor injection for IConfiguration, PresenceTracker, and ILogger.
156 lines
5.0 KiB
C#
156 lines
5.0 KiB
C#
using System.Security.Claims;
|
|
using EchoHub.Core.Constants;
|
|
using EchoHub.Core.Contracts;
|
|
using EchoHub.Core.DTOs;
|
|
using EchoHub.Core.Models;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
|
|
namespace EchoHub.Server.Hubs;
|
|
|
|
[Authorize]
|
|
public class ChatHub : Hub<IEchoHubClient>
|
|
{
|
|
private readonly IChatService _chatService;
|
|
private readonly ILogger<ChatHub> _logger;
|
|
|
|
public ChatHub(IChatService chatService, ILogger<ChatHub> logger)
|
|
{
|
|
_chatService = chatService;
|
|
_logger = logger;
|
|
}
|
|
|
|
private Guid CurrentUserId =>
|
|
Guid.Parse(Context.User?.FindFirstValue(ClaimTypes.NameIdentifier)
|
|
?? throw new HubException("User ID claim not found."));
|
|
|
|
private string CurrentUsername =>
|
|
Context.User?.FindFirstValue("username")
|
|
?? throw new HubException("Username claim not found.");
|
|
|
|
public override async Task OnConnectedAsync()
|
|
{
|
|
try
|
|
{
|
|
await _chatService.UserConnectedAsync(Context.ConnectionId, CurrentUserId, CurrentUsername);
|
|
await base.OnConnectedAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in OnConnectedAsync for {ConnectionId}", Context.ConnectionId);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public override async Task OnDisconnectedAsync(Exception? exception)
|
|
{
|
|
try
|
|
{
|
|
await _chatService.UserDisconnectedAsync(Context.ConnectionId);
|
|
await base.OnDisconnectedAsync(exception);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in OnDisconnectedAsync for {ConnectionId}", Context.ConnectionId);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public async Task<List<MessageDto>> JoinChannel(string channelName)
|
|
{
|
|
try
|
|
{
|
|
var (history, error) = await _chatService.JoinChannelAsync(
|
|
Context.ConnectionId, CurrentUserId, CurrentUsername, channelName);
|
|
|
|
if (error is not null)
|
|
{
|
|
await Clients.Caller.Error(error);
|
|
return [];
|
|
}
|
|
|
|
await Groups.AddToGroupAsync(Context.ConnectionId, channelName.ToLowerInvariant().Trim());
|
|
return 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 [];
|
|
}
|
|
}
|
|
|
|
public async Task LeaveChannel(string channelName)
|
|
{
|
|
try
|
|
{
|
|
channelName = channelName.ToLowerInvariant().Trim();
|
|
await _chatService.LeaveChannelAsync(Context.ConnectionId, CurrentUsername, channelName);
|
|
await Groups.RemoveFromGroupAsync(Context.ConnectionId, channelName);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error leaving channel '{Channel}' for {User}", channelName, CurrentUsername);
|
|
await Clients.Caller.Error($"Failed to leave channel: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public async Task SendMessage(string channelName, string content)
|
|
{
|
|
try
|
|
{
|
|
var error = await _chatService.SendMessageAsync(CurrentUserId, CurrentUsername, channelName, content);
|
|
if (error is not null)
|
|
await Clients.Caller.Error(error);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error sending message in '{Channel}' for {User}", channelName, CurrentUsername);
|
|
await Clients.Caller.Error($"Failed to send message: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public async Task<List<MessageDto>> GetChannelHistory(string channelName, int count = HubConstants.DefaultHistoryCount)
|
|
{
|
|
try
|
|
{
|
|
return await _chatService.GetChannelHistoryAsync(channelName, count);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error fetching history for '{Channel}'", channelName);
|
|
await Clients.Caller.Error($"Failed to load history: {ex.Message}");
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public async Task UpdateStatus(UserStatus status, string? statusMessage)
|
|
{
|
|
try
|
|
{
|
|
var error = await _chatService.UpdateStatusAsync(CurrentUserId, CurrentUsername, status, statusMessage);
|
|
if (error is not null)
|
|
await Clients.Caller.Error(error);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error updating status for {User}", CurrentUsername);
|
|
await Clients.Caller.Error($"Failed to update status: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public async Task<List<UserPresenceDto>> GetOnlineUsers(string channelName)
|
|
{
|
|
try
|
|
{
|
|
return await _chatService.GetOnlineUsersAsync(channelName);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error listing users in '{Channel}'", channelName);
|
|
await Clients.Caller.Error($"Failed to list users: {ex.Message}");
|
|
return [];
|
|
}
|
|
}
|
|
}
|