From 81dab0e4c5990a179eafe99084a69261107f493a Mon Sep 17 00:00:00 2001 From: Gilles TOURREAU Date: Thu, 6 Jun 2024 19:02:25 +0200 Subject: [PATCH] Add the interface ICallAdapter. --- docs/Components/CallComposite.md | 30 ++++--- .../Calling/CallAdapter.cs | 56 +++---------- .../Calling/CallingService.cs | 2 +- .../Calling/ICallAdapter.cs | 80 +++++++++++++++++++ .../Calling/ICallingService.cs | 2 +- .../Pages/Home.razor.cs | 2 +- 6 files changed, 112 insertions(+), 60 deletions(-) create mode 100644 src/Communication.UI.Blazor/Calling/ICallAdapter.cs diff --git a/docs/Components/CallComposite.md b/docs/Components/CallComposite.md index 890b480..6c0c23c 100644 --- a/docs/Components/CallComposite.md +++ b/docs/Components/CallComposite.md @@ -14,8 +14,8 @@ To use the component: builder.Services.AddCalling(); ``` -- Inject the `ICallingService` dependency a use it to create an instance of `CallAdapter`. -- Add the `CallComposite` component and bind the `Adapter` property with the `CallAdapter` previously created. +- Inject the `ICallingService` dependency a use it to create an instance of `ICallAdapter`. +- Add the `CallComposite` component and bind the `Adapter` property with the `ICallAdapter` previously created. Example: ```razor @@ -27,7 +27,7 @@ Example: @code { - private CallAdapter? callAdapter; + private ICallAdapter? callAdapter; private async Task LoadAsync() { @@ -63,13 +63,13 @@ Example: } ``` -You can manage the `CallComposite` component using the `CallAdapter` associated. For example, you can +You can manage the `CallComposite` component using the `ICallAdapter` associated. For example, you can subscribe to different events using a simple delegate. ### Join/Leave the call -After the `CallAdapter` has been associated to the `CallComposite` component +After the `ICallAdapter` has been associated to the `CallComposite` component (or after leaving a call), it is possible to join the call -by calling the `JoinCall()` method on the `CallAdapter`. +by calling the `JoinCall()` method on the `ICallAdapter`. You can define if the camera and/or the microphone have to be activated. ```csharp @@ -85,18 +85,18 @@ private async Task JoinCallAsync() } ``` -To leave the call, call the `LeaveCallAsync()` method on the `CallAdapter`. This method +To leave the call, call the `LeaveCallAsync()` method on the `ICallAdapter`. This method take a boolean parameter `forEveryone` to remove all participants when leaving. ### Start/Stop screen share -To start sharing the screen on the current device, call the `StartScreenShare()` method on the `CallAdapter`. +To start sharing the screen on the current device, call the `StartScreenShare()` method on the `ICallAdapter`. -To stop sharing the screen on the current device, call the `StopScreenShare()` method on the `CallAdapter`. +To stop sharing the screen on the current device, call the `StopScreenShare()` method on the `ICallAdapter`. ### Mute/Unmute -To mute the microphone of the current user, call the `MuteAsync()` method on the `CallAdapter`. +To mute the microphone of the current user, call the `MuteAsync()` method on the `ICallAdapter`. -To unmute the microphone of the current user, call the `UnmuteAsync()` method on the `CallAdapter`. +To unmute the microphone of the current user, call the `UnmuteAsync()` method on the `ICallAdapter`. ### Events You can subsribe to the following asynchronous events using a standard delegate method: @@ -107,4 +107,10 @@ You can subsribe to the following asynchronous events using a standard delegate ### Dispose the resources It is recommanded to implement the `IAsyncDisposable` method in the class which create -and manage the `CallAdapter` instance. \ No newline at end of file +and manage the `ICallAdapter` instance. + +### Unit tests +The `ICallingService.CreateAdapterAsync()` method returns an instance of `ICallAdapter` +implemented by the `CallAdapter`. By returning interface implementation, developers +have no excuses to perform some units in their code by mocking the `ICallingService` +and `ICallAdapter` interfaces. \ No newline at end of file diff --git a/src/Communication.UI.Blazor/Calling/CallAdapter.cs b/src/Communication.UI.Blazor/Calling/CallAdapter.cs index f9c3efc..e732a9a 100644 --- a/src/Communication.UI.Blazor/Calling/CallAdapter.cs +++ b/src/Communication.UI.Blazor/Calling/CallAdapter.cs @@ -12,7 +12,7 @@ namespace PosInformatique.Azure.Communication.UI.Blazor /// /// An adapter interface specific for Azure Communication identity which extends . /// - public class CallAdapter : CommonCallAdapter, IDisposable, IAsyncDisposable + public class CallAdapter : CommonCallAdapter, ICallAdapter, IDisposable { private readonly Guid id; @@ -31,32 +31,19 @@ internal CallAdapter(IJSObjectReference module) this.callbackEvent = new CallbackEvent(this); } - /// - /// Occurs when the call is ended. - /// + /// public event AsyncEventHandler? OnCallEnded; - /// - /// Occurs when the microphone is muted/unmuted on a participant. - /// + /// public event AsyncEventHandler? OnMicrophoneMuteChanged; - /// - /// Occurs when a participant join the call. - /// + /// public event AsyncEventHandler? OnParticipantJoined; - /// - /// Occurs when a participant leave the call. - /// + /// public event AsyncEventHandler? OnParticipantLeft; - /// - /// Join an existing call. - /// - /// Options of the call. - /// A that represents the asynchronous invocation. - /// If the has already been disposed. + /// public async Task JoinCallAsync(JoinCallOptions options) { ObjectDisposedException.ThrowIf(this.callbackEvent is null, this); @@ -64,12 +51,7 @@ public async Task JoinCallAsync(JoinCallOptions options) await this.module.InvokeVoidAsync("adapterJoinCall", this.id, options); } - /// - /// Leave the call. - /// - /// Whether to remove all participants when leaving. - /// A that represents the asynchronous invocation. - /// If the has already been disposed. + /// public async Task LeaveCallAsync(bool forEveryone) { ObjectDisposedException.ThrowIf(this.callbackEvent is null, this); @@ -77,11 +59,7 @@ public async Task LeaveCallAsync(bool forEveryone) await this.module.InvokeVoidAsync("adapterLeaveCall", this.id, forEveryone); } - /// - /// Mute the current user during the call or disable microphone locally. - /// - /// A that represents the asynchronous invocation. - /// If the has already been disposed. + /// public async Task MuteAsync() { ObjectDisposedException.ThrowIf(this.callbackEvent is null, this); @@ -89,11 +67,7 @@ public async Task MuteAsync() await this.module.InvokeVoidAsync("adapterMute", this.id); } - /// - /// Unmute the current user during the call or enable microphone locally. - /// - /// A that represents the asynchronous invocation. - /// If the has already been disposed. + /// public async Task UnmuteAsync() { ObjectDisposedException.ThrowIf(this.callbackEvent is null, this); @@ -101,11 +75,7 @@ public async Task UnmuteAsync() await this.module.InvokeVoidAsync("adapterUnmute", this.id); } - /// - /// Start sharing the screen during a call. - /// - /// A that represents the asynchronous invocation. - /// If the has already been disposed. + /// public async Task StartScreenShareAsync() { ObjectDisposedException.ThrowIf(this.callbackEvent is null, this); @@ -113,11 +83,7 @@ public async Task StartScreenShareAsync() await this.module.InvokeVoidAsync("adapterStartScreenShare", this.id); } - /// - /// Stop sharing the screen. - /// - /// A that represents the asynchronous invocation. - /// If the has already been disposed. + /// public async Task StopScreenShareAsync() { ObjectDisposedException.ThrowIf(this.callbackEvent is null, this); diff --git a/src/Communication.UI.Blazor/Calling/CallingService.cs b/src/Communication.UI.Blazor/Calling/CallingService.cs index a1eddce..323575c 100644 --- a/src/Communication.UI.Blazor/Calling/CallingService.cs +++ b/src/Communication.UI.Blazor/Calling/CallingService.cs @@ -39,7 +39,7 @@ public async ValueTask DisposeAsync() } /// - public async Task CreateAdapterAsync(CallAdapterArgs args) + public async Task CreateAdapterAsync(CallAdapterArgs args) { await this.EnsureModuleLoadAsync(); diff --git a/src/Communication.UI.Blazor/Calling/ICallAdapter.cs b/src/Communication.UI.Blazor/Calling/ICallAdapter.cs new file mode 100644 index 0000000..6948d21 --- /dev/null +++ b/src/Communication.UI.Blazor/Calling/ICallAdapter.cs @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) P.O.S Informatique. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace PosInformatique.Azure.Communication.UI.Blazor +{ + using System.Threading.Tasks; + + /// + /// Adapter which allows to manage the component. + /// + public interface ICallAdapter : IAsyncDisposable + { + /// + /// Occurs when the call is ended. + /// + event AsyncEventHandler? OnCallEnded; + + /// + /// Occurs when the microphone is muted/unmuted on a participant. + /// + event AsyncEventHandler? OnMicrophoneMuteChanged; + + /// + /// Occurs when a participant join the call. + /// + event AsyncEventHandler? OnParticipantJoined; + + /// + /// Occurs when a participant leave the call. + /// + event AsyncEventHandler? OnParticipantLeft; + + /// + /// Join an existing call. + /// + /// Options of the call. + /// A that represents the asynchronous invocation. + /// If the has already been disposed. + Task JoinCallAsync(JoinCallOptions options); + + /// + /// Leave the call. + /// + /// Whether to remove all participants when leaving. + /// A that represents the asynchronous invocation. + /// If the has already been disposed. + Task LeaveCallAsync(bool forEveryone); + + /// + /// Mute the current user during the call or disable microphone locally. + /// + /// A that represents the asynchronous invocation. + /// If the has already been disposed. + Task MuteAsync(); + + /// + /// Start sharing the screen during a call. + /// + /// A that represents the asynchronous invocation. + /// If the has already been disposed. + Task StartScreenShareAsync(); + + /// + /// Stop sharing the screen. + /// + /// A that represents the asynchronous invocation. + /// If the has already been disposed. + Task StopScreenShareAsync(); + + /// + /// Unmute the current user during the call or enable microphone locally. + /// + /// A that represents the asynchronous invocation. + /// If the has already been disposed. + Task UnmuteAsync(); + } +} \ No newline at end of file diff --git a/src/Communication.UI.Blazor/Calling/ICallingService.cs b/src/Communication.UI.Blazor/Calling/ICallingService.cs index e9eb69b..67a9274 100644 --- a/src/Communication.UI.Blazor/Calling/ICallingService.cs +++ b/src/Communication.UI.Blazor/Calling/ICallingService.cs @@ -18,6 +18,6 @@ public interface ICallingService /// Parameters of the to create. /// A new instance of the which can be use by a using the /// property. - Task CreateAdapterAsync(CallAdapterArgs args); + Task CreateAdapterAsync(CallAdapterArgs args); } } diff --git a/tests/Communication.UI.Blazor.Demo/Pages/Home.razor.cs b/tests/Communication.UI.Blazor.Demo/Pages/Home.razor.cs index bc397d0..2fe468e 100644 --- a/tests/Communication.UI.Blazor.Demo/Pages/Home.razor.cs +++ b/tests/Communication.UI.Blazor.Demo/Pages/Home.razor.cs @@ -13,7 +13,7 @@ public partial class Home { private readonly List log; - private CallAdapter? callAdapter; + private ICallAdapter? callAdapter; private string userId;