From 42040e6d0d95603fa9377716a706d12b521fea3a Mon Sep 17 00:00:00 2001 From: Yaser Moradi Date: Tue, 12 Nov 2024 14:12:39 +0100 Subject: [PATCH] feat(templates): initial implementation for Boilerplate's isOnline without signalR #9202 (#9210) --- .../Components/AppComponentBase.cs | 2 +- .../Components/ClientAppCoordinator.cs | 2 -- .../Components/Layout/RootContainer.razor.cs | 2 +- .../Components/Layout/RootLayout.razor.cs | 17 +++-------------- .../Components/Layout/UserMenu.razor | 4 ++-- .../Authorized/Settings/ProfileSection.razor | 2 +- .../Authorized/Settings/SessionsSection.razor | 2 +- .../Components/Parameters.cs | 3 ++- .../Services/AppTelemetryContext.cs | 2 -- .../Services/ClientPubSubMessages.cs | 5 +---- .../Services/Contracts/ITelemetryContext.cs | 4 ---- .../ExceptionDelegatingHandler.cs | 12 +++++++++++- .../MauiAppInsightsTelemetryInitializer.cs | 2 -- .../WindowsAppInsightsTelemetryInitializer.cs | 2 -- .../src/Directory.Packages.props | 2 +- 15 files changed, 24 insertions(+), 39 deletions(-) diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/AppComponentBase.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/AppComponentBase.cs index 028f112f41..596f43d88a 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/AppComponentBase.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/AppComponentBase.cs @@ -7,7 +7,7 @@ public partial class AppComponentBase : ComponentBase, IAsyncDisposable /// /// /// - [CascadingParameter(Name = Parameters.IsOnline)] protected bool IsOnline { get; set; } + [CascadingParameter(Name = Parameters.IsOnline)] protected bool? IsOnline { get; set; } [CascadingParameter] protected Task AuthenticationStateTask { get; set; } = default!; [AutoInject] protected IJSRuntime JSRuntime = default!; diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/ClientAppCoordinator.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/ClientAppCoordinator.cs index 8e1640103c..f638850a27 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/ClientAppCoordinator.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/ClientAppCoordinator.cs @@ -188,14 +188,12 @@ private async Task ConnectSignalR() private async Task HubConnectionConnected(string? connectionId) { - TelemetryContext.IsOnline = true; PubSubService.Publish(ClientPubSubMessages.IS_ONLINE_CHANGED, true); logger.LogInformation("SignalR connection {ConnectionId} established.", connectionId); } private async Task HubConnectionDisconnected(Exception? exception) { - TelemetryContext.IsOnline = false; PubSubService.Publish(ClientPubSubMessages.IS_ONLINE_CHANGED, false); if (exception is null) diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/RootContainer.razor.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/RootContainer.razor.cs index 07572dbe46..b4fffa2398 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/RootContainer.razor.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/RootContainer.razor.cs @@ -7,7 +7,7 @@ public partial class RootContainer /// /// /// - [Parameter] public bool IsOnline { get; set; } + [Parameter] public bool? IsOnline { get; set; } [Parameter] public BitDir? CurrentDir { get; set; } [Parameter] public string? CurrentUrl { get; set; } [Parameter] public bool? IsAuthenticated { get; set; } diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/RootLayout.razor.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/RootLayout.razor.cs index b5bd8efd77..44cf85bfc7 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/RootLayout.razor.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/RootLayout.razor.cs @@ -11,18 +11,7 @@ public partial class RootLayout : IDisposable /// /// /// - private bool isOnline - //#if (signalR == true) - = false; - //#else - //#if (IsInsideProjectTemplate == true) - /* - //#endif - = true; - //#if (IsInsideProjectTemplate == true) - */ - //#endif - //#endif + private bool? isOnline = null; private bool? isAuthenticated; /// @@ -39,6 +28,7 @@ private bool isOnline [AutoInject] private PubSubService pubSubService = default!; [AutoInject] private AuthenticationManager authManager = default!; [AutoInject] private IExceptionHandler exceptionHandler = default!; + [AutoInject] private ITelemetryContext telemetryContext = default!; [AutoInject] private NavigationManager navigationManager = default!; [AutoInject] private IPrerenderStateService prerenderStateService = default!; @@ -70,13 +60,12 @@ protected override async Task OnInitializedAsync() StateHasChanged(); })); - //#if (signalR == true) unsubscribers.Add(pubSubService.Subscribe(ClientPubSubMessages.IS_ONLINE_CHANGED, async payload => { isOnline = (bool)payload!; + telemetryContext.IsOnline = isOnline is true; await InvokeAsync(StateHasChanged); })); - //#endif isAuthenticated = await prerenderStateService.GetValue(async () => (await AuthenticationStateTask).User.IsAuthenticated()); diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/UserMenu.razor b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/UserMenu.razor index 8fdd46081d..11a2957fcf 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/UserMenu.razor +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/UserMenu.razor @@ -14,7 +14,7 @@ Size=@BitPersonaSize.Size32 PrimaryText="@user.DisplayName" Classes="@(new() { DetailsContainer="persona-details" })" - Presence="@(IsOnline ? BitPersonaPresence.Online : BitPersonaPresence.Offline)" /> + Presence="@(IsOnline is null ? BitPersonaPresence.None : IsOnline is true ? BitPersonaPresence.Online : BitPersonaPresence.Offline)" /> @@ -28,7 +28,7 @@ Size="BitPersonaSize.Size48" PrimaryText="@user.DisplayName" SecondaryText="@(user.Email ?? user.PhoneNumber)" - Presence="@(IsOnline ? BitPersonaPresence.Online : BitPersonaPresence.Offline)"> + Presence="@(IsOnline is null ? BitPersonaPresence.None : IsOnline is true ? BitPersonaPresence.Online : BitPersonaPresence.Offline)"> @Localizer[nameof(AppStrings.Edit)] diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Settings/ProfileSection.razor b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Settings/ProfileSection.razor index 1887eb4fa2..a2d677d5c8 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Settings/ProfileSection.razor +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Settings/ProfileSection.razor @@ -32,7 +32,7 @@ ImageUrl="@imageUrl" PrimaryText="@User?.FullName" Size=@BitPersonaSize.Size72 - Presence="@(IsOnline ? BitPersonaPresence.Online : BitPersonaPresence.Offline)" /> + Presence="@(IsOnline is null ? BitPersonaPresence.None : IsOnline is true ? BitPersonaPresence.Online : BitPersonaPresence.Offline)" /> @Localizer[nameof(AppStrings.UploadNewProfileImage)] diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Settings/SessionsSection.razor b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Settings/SessionsSection.razor index 56587beadf..f17ffc34c5 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Settings/SessionsSection.razor +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Settings/SessionsSection.razor @@ -12,7 +12,7 @@ Size="BitPersonaSize.Size48" Styles="@(new() { Image = "width:50%;height:50%" })" ImageInitials="✓" - Presence="@(IsOnline ? BitPersonaPresence.Online : BitPersonaPresence.Offline)" + Presence="@(IsOnline is null ? BitPersonaPresence.None : IsOnline is true ? BitPersonaPresence.Online : BitPersonaPresence.Offline)" ImageUrl="@($"/_content/Boilerplate.Client.Core/images/os/{GetImageUrl(currentSession.Device)}")" /> } diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Parameters.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Parameters.cs index 91309f8436..8c0f5a830e 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Parameters.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Parameters.cs @@ -15,8 +15,9 @@ public class Parameters /// /// Determines the connection status, with default behavior based on SignalR connection status. - /// If SignalR is not added to the project during initial project creation, this value will always be true by default. + /// If SignalR is not added to the project during initial project creation, this value will always be null by default. /// Alternatively, you can implement custom logic to control this value. + /// true => Online, false => Offline, null => Unknown /// public const string IsOnline = nameof(IsOnline); } diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/AppTelemetryContext.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/AppTelemetryContext.cs index 95cacd46a4..b7b071834c 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/AppTelemetryContext.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/AppTelemetryContext.cs @@ -25,7 +25,5 @@ public class AppTelemetryContext : ITelemetryContext public string? Environment { get; set; } = AppEnvironment.Current; - //#if (signalR == true) public bool IsOnline { get; set; } - //#endif } diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/ClientPubSubMessages.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/ClientPubSubMessages.cs index a02ea8dee7..83a9d3b13a 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/ClientPubSubMessages.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/ClientPubSubMessages.cs @@ -10,14 +10,11 @@ public static partial class ClientPubSubMessages public const string OPEN_NAV_PANEL = nameof(OPEN_NAV_PANEL); public const string CULTURE_CHANGED = nameof(CULTURE_CHANGED); public const string PROFILE_UPDATED = nameof(PROFILE_UPDATED); + public const string IS_ONLINE_CHANGED = nameof(IS_ONLINE_CHANGED); public const string PAGE_TITLE_CHANGED = nameof(PAGE_TITLE_CHANGED); public const string ROUTE_DATA_UPDATED = nameof(ROUTE_DATA_UPDATED); public const string UPDATE_IDENTITY_HEADER_BACK_LINK = nameof(UPDATE_IDENTITY_HEADER_BACK_LINK); public const string IDENTITY_HEADER_BACK_LINK_CLICKED = nameof(IDENTITY_HEADER_BACK_LINK_CLICKED); - //#if (signalR == true) - public const string IS_ONLINE_CHANGED = nameof(IS_ONLINE_CHANGED); - //#endif - public const string SHOW_DIAGNOSTIC_MODAL = nameof(SHOW_DIAGNOSTIC_MODAL); } diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/Contracts/ITelemetryContext.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/Contracts/ITelemetryContext.cs index 02d96c2bb6..a1b5962c34 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/Contracts/ITelemetryContext.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/Contracts/ITelemetryContext.cs @@ -44,9 +44,7 @@ public static ITelemetryContext? Current public string? Environment { get; set; } - //#if (signalR == true) public bool IsOnline { get; set; } - //#endif public Dictionary ToDictionary(Dictionary? additionalParameters = null) { @@ -61,9 +59,7 @@ public static ITelemetryContext? Current { nameof(TimeZone), TimeZone }, { nameof(Culture), Culture }, { nameof(Environment), Environment }, - //#if (signalR == true) { nameof(IsOnline), IsOnline } - //#endif }; if (AppPlatform.IsBlazorHybrid) diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/HttpMessageHandlers/ExceptionDelegatingHandler.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/HttpMessageHandlers/ExceptionDelegatingHandler.cs index 0f105087df..2ee7fec9cf 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/HttpMessageHandlers/ExceptionDelegatingHandler.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/HttpMessageHandlers/ExceptionDelegatingHandler.cs @@ -1,8 +1,12 @@ -using System.Net; +//+:cnd:noEmit +using System.Net; namespace Boilerplate.Client.Core.Services.HttpMessageHandlers; public partial class ExceptionDelegatingHandler(IStringLocalizer localizer, + //#if (signalR != true) + PubSubService pubSubService, + //#endif JsonSerializerOptions jsonSerializerOptions, HttpMessageHandler handler) : DelegatingHandler(handler) @@ -57,5 +61,11 @@ protected override async Task SendAsync(HttpRequestMessage { throw new ServerConnectionException(localizer[nameof(AppStrings.ServerConnectionException)], exp); } + //#if (signalR != true) + finally + { + pubSubService.Publish(ClientPubSubMessages.IS_ONLINE_CHANGED, serverCommunicationSuccess); + } + //#endif } } diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Maui/Services/MauiAppInsightsTelemetryInitializer.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Maui/Services/MauiAppInsightsTelemetryInitializer.cs index 435b1e1049..77e772e560 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Maui/Services/MauiAppInsightsTelemetryInitializer.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Maui/Services/MauiAppInsightsTelemetryInitializer.cs @@ -20,9 +20,7 @@ public void Initialize(ITelemetry telemetry) telemetry.Context.GlobalProperties[nameof(ITelemetryContext.UserAgent)] = ITelemetryContext.Current.UserAgent; telemetry.Context.GlobalProperties[nameof(ITelemetryContext.TimeZone)] = ITelemetryContext.Current.TimeZone; telemetry.Context.GlobalProperties[nameof(ITelemetryContext.Culture)] = ITelemetryContext.Current.Culture; - //#if (signalR == true) telemetry.Context.GlobalProperties[nameof(ITelemetryContext.IsOnline)] = ITelemetryContext.Current.IsOnline.ToString().ToLowerInvariant(); - //#endif } telemetry.Context.Session.IsFirst = VersionTracking.IsFirstLaunchEver; diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Windows/Services/WindowsAppInsightsTelemetryInitializer.cs b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Windows/Services/WindowsAppInsightsTelemetryInitializer.cs index 409b5aae97..3589b903d5 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Windows/Services/WindowsAppInsightsTelemetryInitializer.cs +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Windows/Services/WindowsAppInsightsTelemetryInitializer.cs @@ -20,9 +20,7 @@ public void Initialize(ITelemetry telemetry) telemetry.Context.GlobalProperties[nameof(ITelemetryContext.UserAgent)] = ITelemetryContext.Current.UserAgent; telemetry.Context.GlobalProperties[nameof(ITelemetryContext.TimeZone)] = ITelemetryContext.Current.TimeZone; telemetry.Context.GlobalProperties[nameof(ITelemetryContext.Culture)] = ITelemetryContext.Current.Culture; - //#if (signalR == true) telemetry.Context.GlobalProperties[nameof(ITelemetryContext.IsOnline)] = ITelemetryContext.Current.IsOnline.ToString().ToLowerInvariant(); - //#endif } } } diff --git a/src/Templates/Boilerplate/Bit.Boilerplate/src/Directory.Packages.props b/src/Templates/Boilerplate/Bit.Boilerplate/src/Directory.Packages.props index 6bfdefd73b..11127e45d3 100644 --- a/src/Templates/Boilerplate/Bit.Boilerplate/src/Directory.Packages.props +++ b/src/Templates/Boilerplate/Bit.Boilerplate/src/Directory.Packages.props @@ -63,7 +63,7 @@ - +