Skip to content

Commit b1bf5f3

Browse files
authored
Merge pull request #704 from immense/tech/circuit-events
Strongly-typed circuit events.
2 parents 75a2a56 + e58bbd7 commit b1bf5f3

45 files changed

Lines changed: 785 additions & 640 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ dotnet_style_qualification_for_event = false:silent
111111
dotnet_style_qualification_for_method = false:silent
112112
dotnet_style_qualification_for_property = false:silent
113113
dotnet_style_qualification_for_field = false:silent
114+
115+
# IDE0130: Namespace does not match folder structure
116+
dotnet_diagnostic.IDE0130.severity = error
117+
114118
[*.cs]
115119
csharp_indent_labels = one_less_than_current
116120
csharp_using_directive_placement = outside_namespace:silent
@@ -167,3 +171,6 @@ dotnet_diagnostic.CS8600.severity = error
167171

168172
# CS8602: Dereference of a possibly null reference.
169173
dotnet_diagnostic.CS8602.severity = error
174+
175+
# CS8631: The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match constraint type.
176+
dotnet_diagnostic.CS8631.severity = error

Server/Components/AuthComponentBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace Remotely.Server.Components;
1212

1313
[Authorize]
14-
public class AuthComponentBase : ComponentBase
14+
public class AuthComponentBase : MessengerSubscriber
1515
{
1616
[Inject]
1717
protected IAuthService AuthService { get; set; } = null!;

Server/Components/Devices/ChatCard.razor.cs

Lines changed: 44 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
using Microsoft.AspNetCore.Components;
1+
using Immense.SimpleMessenger;
2+
using Microsoft.AspNetCore.Components;
23
using Microsoft.AspNetCore.Components.Web;
34
using Remotely.Server.Hubs;
5+
using Remotely.Server.Models.Messages;
46
using Remotely.Server.Services;
7+
using Remotely.Server.Services.Stores;
58
using Remotely.Shared.Enums;
69
using Remotely.Shared.ViewModels;
710
using System;
8-
using System.Collections.Generic;
9-
using System.Linq;
1011
using System.Threading.Tasks;
1112

1213
namespace Remotely.Server.Components.Devices;
1314

14-
public partial class ChatCard : AuthComponentBase, IDisposable
15+
public partial class ChatCard : AuthComponentBase, IAsyncDisposable
1516
{
1617
private ElementReference _chatMessagesWindow;
1718

@@ -22,21 +23,14 @@ public partial class ChatCard : AuthComponentBase, IDisposable
2223
public required ChatSession Session { get; set; }
2324

2425
[Inject]
25-
private IClientAppState AppState { get; init; } = null!;
26+
private IChatSessionStore ChatSessionStore { get; init; } = null!;
2627

2728
[Inject]
2829
private ICircuitConnection CircuitConnection { get; init; } = null!;
2930

3031
[Inject]
3132
private IJsInterop JsInterop { get; init; } = null!;
3233

33-
public void Dispose()
34-
{
35-
AppState.PropertyChanged -= AppState_PropertyChanged;
36-
CircuitConnection.MessageReceived -= CircuitConnection_MessageReceived;
37-
GC.SuppressFinalize(this);
38-
}
39-
4034
protected override void OnAfterRender(bool firstRender)
4135
{
4236
JsInterop.ScrollToEnd(_chatMessagesWindow);
@@ -45,64 +39,55 @@ protected override void OnAfterRender(bool firstRender)
4539
protected override async Task OnInitializedAsync()
4640
{
4741
await base.OnInitializedAsync();
48-
AppState.PropertyChanged += AppState_PropertyChanged;
49-
CircuitConnection.MessageReceived += CircuitConnection_MessageReceived;
42+
await Register<ChatReceivedMessage, string>(
43+
CircuitConnection.ConnectionId,
44+
HandleChatMessageReceived);
5045
}
5146

52-
private async void AppState_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
47+
private async Task HandleChatMessageReceived(ChatReceivedMessage message)
5348
{
54-
if (e.PropertyName == Session.SessionId)
49+
if (message.DeviceId != Session.DeviceId)
5550
{
56-
await InvokeAsync(StateHasChanged);
51+
return;
5752
}
58-
}
5953

60-
private async void CircuitConnection_MessageReceived(object? sender, Models.CircuitEvent e)
61-
{
62-
if (e.EventName == Models.CircuitEventName.ChatReceived)
54+
if (!ChatSessionStore.TryGetSession(message.DeviceId, out var session))
6355
{
64-
var deviceId = (string)e.Params[0];
56+
return;
57+
}
6558

66-
if (deviceId == Session.DeviceId)
59+
if (message.DidDisconnect)
60+
{
61+
session.ChatHistory.Enqueue(new ChatHistoryItem()
6762
{
68-
var deviceName = (string)e.Params[1];
69-
var message = (string)e.Params[2];
70-
var disconnected = (bool)e.Params[3];
71-
72-
var session = AppState.DevicesFrameChatSessions.Find(x => x.DeviceId == deviceId);
73-
74-
if (disconnected)
75-
{
76-
session.ChatHistory.Add(new ChatHistoryItem()
77-
{
78-
Message = $"{Session.DeviceName} disconnected.",
79-
Origin = ChatHistoryItemOrigin.System
80-
});
81-
}
82-
else
83-
{
84-
session.ChatHistory.Add(new ChatHistoryItem()
85-
{
86-
Message = message,
87-
Origin = ChatHistoryItemOrigin.Device
88-
});
89-
}
90-
91-
if (!session.IsExpanded)
92-
{
93-
session.MissedChats++;
94-
}
95-
96-
await InvokeAsync(StateHasChanged);
97-
98-
JsInterop.ScrollToEnd(_chatMessagesWindow);
99-
}
63+
Message = $"{Session.DeviceName} disconnected.",
64+
Origin = ChatHistoryItemOrigin.System
65+
});
66+
}
67+
else
68+
{
69+
session.ChatHistory.Enqueue(new ChatHistoryItem()
70+
{
71+
Message = message.MessageText,
72+
Origin = ChatHistoryItemOrigin.Device
73+
});
74+
}
75+
76+
if (!session.IsExpanded)
77+
{
78+
session.MissedChats++;
10079
}
80+
81+
await InvokeAsync(StateHasChanged);
82+
83+
JsInterop.ScrollToEnd(_chatMessagesWindow);
10184
}
102-
private void CloseChatCard()
85+
86+
private async Task CloseChatCard()
10387
{
104-
AppState.DevicesFrameChatSessions.RemoveAll(x => x.DeviceId == Session.DeviceId);
105-
AppState.InvokePropertyChanged(nameof(AppState.DevicesFrameChatSessions));
88+
_ = ChatSessionStore.TryRemove($"{Session.DeviceId}", out _);
89+
var message = new ChatSessionsChangedMessage();
90+
await Messenger.Send(message, CircuitConnection.ConnectionId);
10691
}
10792
private async Task EvaluateInputKeypress(KeyboardEventArgs args)
10893
{
@@ -115,7 +100,7 @@ private async Task EvaluateInputKeypress(KeyboardEventArgs args)
115100

116101
await CircuitConnection.SendChat(_inputText, $"{Session.DeviceId}");
117102

118-
Session.ChatHistory.Add(new ChatHistoryItem()
103+
Session.ChatHistory.Enqueue(new ChatHistoryItem()
119104
{
120105
Origin = ChatHistoryItemOrigin.Self,
121106
Message = _inputText

Server/Components/Devices/ChatFrame.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
@attribute [Authorize]
22
@inherits AuthComponentBase
33

4-
@if (AppState.DevicesFrameChatSessions.Any())
4+
@if (_chatSessions.Any())
55
{
66
<div class="chat-frame">
7-
@foreach (var session in AppState.DevicesFrameChatSessions)
7+
@foreach (var session in _chatSessions)
88
{
99
<ChatCard @key="session.SessionId" Session="session" />
1010
}
Lines changed: 40 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
using Microsoft.AspNetCore.Components;
1+
using Immense.SimpleMessenger;
2+
using Microsoft.AspNetCore.Components;
23
using Microsoft.AspNetCore.Components.Web;
34
using Remotely.Server.Hubs;
4-
using Remotely.Server.Services;
5+
using Remotely.Server.Models.Messages;
6+
using Remotely.Server.Services.Stores;
7+
using Remotely.Shared.Entities;
58
using Remotely.Shared.Enums;
69
using Remotely.Shared.ViewModels;
710
using System;
@@ -11,71 +14,61 @@
1114

1215
namespace Remotely.Server.Components.Devices;
1316

14-
public partial class ChatFrame : AuthComponentBase, IDisposable
17+
public partial class ChatFrame : AuthComponentBase, IAsyncDisposable
1518
{
19+
private ICollection<ChatSession> _chatSessions = Array.Empty<ChatSession>();
1620

1721
[Inject]
18-
private IClientAppState AppState { get; init; } = null!;
22+
private ISelectedCardsStore CardStore { get; init; } = null!;
1923

2024
[Inject]
21-
private ICircuitConnection CircuitConnection { get; init; } = null!;
25+
private IChatSessionStore ChatCache { get; init; } = null!;
2226

23-
public void Dispose()
24-
{
25-
AppState.PropertyChanged -= AppState_PropertyChanged;
26-
CircuitConnection.MessageReceived -= CircuitConnection_MessageReceived;
27-
GC.SuppressFinalize(this);
28-
}
27+
[Inject]
28+
private ICircuitConnection CircuitConnection { get; init; } = null!;
2929

3030
protected override async Task OnInitializedAsync()
3131
{
32+
_chatSessions = ChatCache.GetAllSessions();
33+
await Register<ChatSessionsChangedMessage, string>(
34+
CircuitConnection.ConnectionId,
35+
HandleChatSessionsChanged);
36+
await Register<ChatReceivedMessage, string>(
37+
CircuitConnection.ConnectionId,
38+
HandleChatMessageReceived);
39+
3240
await base.OnInitializedAsync();
33-
AppState.PropertyChanged += AppState_PropertyChanged;
34-
CircuitConnection.MessageReceived += CircuitConnection_MessageReceived;
3541
}
3642

37-
private void CircuitConnection_MessageReceived(object? sender, Models.CircuitEvent e)
43+
private async Task HandleChatMessageReceived(ChatReceivedMessage message)
3844
{
39-
if (e.EventName == Models.CircuitEventName.ChatReceived)
45+
if (message.DidDisconnect ||
46+
ChatCache.ContainsKey(message.DeviceId))
4047
{
41-
var deviceId = (string)e.Params[0];
42-
43-
if (!AppState.DevicesFrameChatSessions.Exists(x => x.DeviceId == deviceId))
44-
{
45-
var deviceName = (string)e.Params[1];
46-
var message = (string)e.Params[2];
47-
var disconnected = (bool)e.Params[3];
48-
49-
if (disconnected)
50-
{
51-
return;
52-
}
48+
return;
49+
}
5350

54-
var newChat = new ChatSession()
55-
{
56-
DeviceId = deviceId,
57-
DeviceName = deviceName,
58-
IsExpanded = true
59-
};
51+
var newChat = new ChatSession()
52+
{
53+
DeviceId = message.DeviceId,
54+
DeviceName = message.DeviceName,
55+
IsExpanded = true
56+
};
6057

61-
newChat.ChatHistory.Add(new ChatHistoryItem()
62-
{
63-
Message = message,
64-
Origin = ChatHistoryItemOrigin.Device
65-
});
58+
newChat.ChatHistory.Enqueue(new ChatHistoryItem()
59+
{
60+
Message = message.MessageText,
61+
Origin = ChatHistoryItemOrigin.Device
62+
});
6663

67-
AppState.DevicesFrameChatSessions.Add(newChat);
64+
ChatCache.AddOrUpdate(message.DeviceId, newChat, (k, v) => newChat);
6865

69-
InvokeAsync(StateHasChanged);
70-
}
71-
}
66+
await Messenger.Send(new ChatSessionsChangedMessage(), CircuitConnection.ConnectionId);
7267
}
7368

74-
private void AppState_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
69+
private async Task HandleChatSessionsChanged(ChatSessionsChangedMessage message)
7570
{
76-
if (e.PropertyName == nameof(AppState.DevicesFrameChatSessions))
77-
{
78-
InvokeAsync(StateHasChanged);
79-
}
71+
_chatSessions = ChatCache.GetAllSessions();
72+
await InvokeAsync(StateHasChanged);
8073
}
8174
}

Server/Components/Devices/DeviceCard.razor

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
@attribute [Authorize]
22
@inherits AuthComponentBase
33

4-
<div @ref="_card" class="card border-secondary my-3 mr-3 device-card @_theme @GetCardStateClass(Device)"
4+
<div @ref="_card" class="card border-secondary my-3 mr-3 device-card @_theme @GetCardStateClass()"
55
@onclick="ExpandCard"
66
@onclick:stopPropagation
77
@oncontextmenu="ContextMenuOpening"
8-
@oncontextmenu:preventDefault="GetCardState() == DeviceCardState.Normal"
9-
@oncontextmenu:stopPropagation="GetCardState() == DeviceCardState.Normal">
8+
@oncontextmenu:preventDefault="_state == DeviceCardState.Normal"
9+
@oncontextmenu:stopPropagation="_state == DeviceCardState.Normal">
1010

1111
<div class="card-header" @onclick="HandleHeaderClick"
12-
@onclick:stopPropagation="GetCardState() == DeviceCardState.Expanded"
13-
@onclick:preventDefault="GetCardState() == DeviceCardState.Expanded">
12+
@onclick:stopPropagation="_state == DeviceCardState.Expanded"
13+
@onclick:preventDefault="_state == DeviceCardState.Expanded">
1414
<div>
1515
@if (Device.IsOnline)
1616
{

0 commit comments

Comments
 (0)