222 lines
No EOL
7 KiB
C#
222 lines
No EOL
7 KiB
C#
using Insight.Infrastructure.Services;
|
|
using Insight.Web.Constants;
|
|
using Insight.Web.Models;
|
|
using Insight.Web.Services;
|
|
using Microsoft.AspNetCore.Components;
|
|
using Microsoft.AspNetCore.Components.Authorization;
|
|
using Microsoft.AspNetCore.SignalR.Client;
|
|
using Microsoft.JSInterop;
|
|
using MongoDB.Driver;
|
|
using MudBlazor;
|
|
using Vaitr.Bus;
|
|
using static Insight.Web.Constants.Events.Chat;
|
|
|
|
namespace Insight.Web.Components.Dialogs;
|
|
|
|
public partial class ChatDialog : IDisposable
|
|
{
|
|
[Inject] private Bus Bus { get; init; } = default!;
|
|
[Inject] private ChatService ChatService { get; init; } = default!;
|
|
[Inject] private SessionPool SessionCache { get; init; } = default!;
|
|
[Inject] private SessionHandler SessionHandler { get; init; } = default!;
|
|
[Inject] private IdentityService IdentityService { get; init; } = default!;
|
|
[Inject] private AuthenticationStateProvider AuthenticationStateProvider { get; init; } = default!;
|
|
[Inject] private IMongoDatabase Database { get; init; } = default!;
|
|
[Inject] private IJSRuntime JSRuntime { get; init; } = default!;
|
|
[Inject] private ISnackbar Snackbar { get; init; } = default!;
|
|
[Inject] private ILogger<ChatDialog> Logger { get; init; } = default!;
|
|
|
|
private int _newMessages;
|
|
public int NewMessages
|
|
{
|
|
get
|
|
{
|
|
return _newMessages;
|
|
}
|
|
set
|
|
{
|
|
if (value != _newMessages)
|
|
{
|
|
_newMessages = value;
|
|
//Bus.Publish(Events.Sessions.Changed); // test, bugt hölle
|
|
}
|
|
}
|
|
}
|
|
|
|
private enum Content { Contacts, Chat }
|
|
private Content _content = Content.Contacts;
|
|
private ChatUser? _currentUser;
|
|
private ChatSession? _currentSession;
|
|
private string? _currentMessage;
|
|
private bool _disposed;
|
|
|
|
private readonly List<IDisposable> _subscriptions = [];
|
|
|
|
protected override Task OnInitializedAsync()
|
|
{
|
|
_subscriptions.Add(Bus.SubscribeAsync<ChatUserConnected>(UserConnected, p => p.User.Uid != SessionHandler.State.Uid));
|
|
_subscriptions.Add(Bus.SubscribeAsync<ChatUserDisconnected>(UserDisconnected, p => p.User.Uid != SessionHandler.State.Uid));
|
|
_subscriptions.Add(Bus.SubscribeAsync<ChatRefresh>(RefreshAsync, null));
|
|
_subscriptions.Add(Bus.SubscribeAsync<ChatMessageReceived>(MessageReceived, p => p.Message.SenderId != SessionHandler.State.Uid));
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
if (firstRender)
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
_currentUser = ChatService.Users.FirstOrDefault(p => p.Key.Uid == SessionHandler.State.Uid).Key;
|
|
|
|
if (_content == Content.Chat)
|
|
{
|
|
await JSRuntime.InvokeAsync<string>("ScrollToBottom", "chatContainer");
|
|
|
|
// mock
|
|
NewMessages = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task GetSessionAsync(ChatUser user)
|
|
{
|
|
if (_currentUser is null) return;
|
|
|
|
var members = new List<ChatUser>() { _currentUser, user };
|
|
var session = await ChatService.AddOrGetSession(members);
|
|
|
|
_currentSession = session;
|
|
|
|
_content = Content.Chat;
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
private async Task SendAsync()
|
|
{
|
|
if (_currentSession is null || _currentUser is null || string.IsNullOrWhiteSpace(_currentMessage)) return;
|
|
|
|
await _currentSession.SendMessage(_currentUser, _currentMessage, default);
|
|
_currentMessage = string.Empty;
|
|
|
|
await InvokeAsync(StateHasChanged);
|
|
|
|
//await JSRuntime.InvokeAsync<string>("ScrollToBottom", "chatContainer");
|
|
}
|
|
|
|
private async ValueTask UserConnected(ChatUserConnected model, CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
Notification.Information(Snackbar, $"{model.User.Username} Online", options =>
|
|
{
|
|
//options.Onclick = (x) => null;
|
|
options.HideIcon = true;
|
|
options.ShowCloseIcon = false;
|
|
options.RequireInteraction = false;
|
|
options.ShowTransitionDuration = 0;
|
|
options.HideTransitionDuration = 1000;
|
|
options.VisibleStateDuration = 10000;
|
|
});
|
|
|
|
await JSRuntime.InvokeAsync<string>("PlayAudio", "chat_user_online");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogError("{exception}", ex.Message);
|
|
}
|
|
}
|
|
|
|
private async ValueTask UserDisconnected(ChatUserDisconnected model, CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
Notification.Information(Snackbar, $"{model.User.Username} Offline", options =>
|
|
{
|
|
//options.Onclick = (x) => null;
|
|
options.HideIcon = true;
|
|
options.ShowCloseIcon = false;
|
|
options.RequireInteraction = false;
|
|
options.ShowTransitionDuration = 0;
|
|
options.HideTransitionDuration = 1000;
|
|
options.VisibleStateDuration = 10000;
|
|
});
|
|
|
|
await JSRuntime.InvokeAsync<string>("PlayAudio", "chat_user_online");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogError("{exception}", ex.Message);
|
|
}
|
|
}
|
|
|
|
private async ValueTask RefreshAsync(ChatRefresh model, CancellationToken cancellationToken)
|
|
{
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
private async ValueTask MessageReceived(ChatMessageReceived model, CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
Notification.Information(Snackbar, $"New message from: {model.Session.Members.FirstOrDefault(p => p.Uid == model.Message.SenderId)?.Username}", options =>
|
|
{
|
|
options.Onclick = (x) => OpenSpecificChatWindow(model.Session);
|
|
options.HideIcon = true;
|
|
options.ShowCloseIcon = true;
|
|
options.RequireInteraction = true;
|
|
options.ShowTransitionDuration = 0;
|
|
options.HideTransitionDuration = 0;
|
|
options.VisibleStateDuration = 10000;
|
|
options.DuplicatesBehavior = SnackbarDuplicatesBehavior.Prevent;
|
|
});
|
|
|
|
// mock
|
|
NewMessages++;
|
|
|
|
if (_content != Content.Chat)
|
|
{
|
|
await JSRuntime.InvokeAsync<string>("PlayAudio", "chat_message");
|
|
}
|
|
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogError("{exception}", ex.ToString());
|
|
}
|
|
}
|
|
|
|
private async Task OpenSpecificChatWindow(ChatSession session)
|
|
{
|
|
_currentSession = session;
|
|
_content = Content.Chat;
|
|
_visible = true;
|
|
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
private void Dispose(bool disposing)
|
|
{
|
|
if (_disposed is false) return;
|
|
if (disposing is false) return;
|
|
|
|
try
|
|
{
|
|
|
|
}
|
|
finally
|
|
{
|
|
_disposed = true;
|
|
}
|
|
}
|
|
} |