generated from nventive/Template
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #384 from nventive/dev/cama/MergeMain
Merge main in feature/uno5
- Loading branch information
Showing
17 changed files
with
238 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,8 @@ schedules: | |
include: | ||
- main | ||
|
||
trigger: none | ||
|
||
variables: | ||
- template: build/variables.yml | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Default Analytics | ||
|
||
This application comes with a few default tracked events. | ||
They can be found in the [IAnalyticsSink](../src/app/ApplicationTemplate.Presentation/Framework/Analytics/IAnalyticsSink.cs) interface. | ||
The idea is that you would change the implementation of this interface to send the events to an analytics service (such as AppCenter, Firebase, Segment, etc.). | ||
|
||
> 💡 The default events are meant to be a starting point for your application's analytics. Because they are automatic, they are more generic than custom events. If you want to track more specific events, you can adjust this recipe by adding new members to the `IAnalyticsSink` interface (or changing the existing ones) to better suit your needs. | ||
Here is a list of the default events: | ||
|
||
## Page Views | ||
This is based on the changes of state from the `ISectionsNavigator`. | ||
|
||
The `ISectionsNavigator` controls the navigation of the application. It's state can be observed and this is leveraged to detect the page views. | ||
|
||
## Command Executions | ||
This is based on the default builder of the `IDynamicCommandBuilderFactory`. | ||
|
||
The `IDynamicCommandBuilder` allows to customize the default behavior or all DynamicCommands. This is leveraged to inject analytics on command invocations. | ||
|
||
Command executions are typically associated with button presses and gestures. |
21 changes: 21 additions & 0 deletions
21
src/app/ApplicationTemplate.Presentation/Configuration/AnalyticsConfiguration.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace ApplicationTemplate.Presentation; | ||
|
||
public static class AnalyticsConfiguration | ||
{ | ||
/// <summary> | ||
/// Adds the analytics services to the <see cref="IServiceCollection"/>. | ||
/// </summary> | ||
/// <param name="services">The service collection.</param> | ||
public static IServiceCollection AddAnalytics(this IServiceCollection services) | ||
{ | ||
return services.AddSingleton<IAnalyticsSink, AnalyticsSink>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
src/app/ApplicationTemplate.Presentation/Framework/Analytics/AnalytcsSink.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#nullable enable | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using System.Xml.Linq; | ||
using Chinook.DataLoader; | ||
using Chinook.DynamicMvvm; | ||
using Chinook.SectionsNavigation; | ||
using Chinook.StackNavigation; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace ApplicationTemplate.Presentation; | ||
|
||
public sealed class AnalyticsSink : IAnalyticsSink | ||
{ | ||
private readonly ILogger<AnalyticsSink> _logger; | ||
private INavigableViewModel? _lastViewModel; | ||
|
||
public AnalyticsSink(ILogger<AnalyticsSink> logger) | ||
{ | ||
_logger = logger; | ||
} | ||
|
||
public void TrackNavigation(SectionsNavigatorState navigatorState) | ||
{ | ||
if (navigatorState.LastRequestState != NavigatorRequestState.Processed) | ||
{ | ||
// Skip the requests that are still processing of that failed to process. | ||
return; | ||
} | ||
|
||
// Get the actual ViewModel instance. | ||
// This allows to track based on instances and not types (because there are scenarios where you can open the same page multiple times with different parameters). | ||
// Having the instance also allows casting into more specific types to get more information, such as navigation parameters, that could be relevant for analytics. | ||
var viewModel = navigatorState.GetActiveStackNavigator().State.Stack.LastOrDefault()?.ViewModel; | ||
if (viewModel is null || _lastViewModel == viewModel) | ||
{ | ||
return; | ||
} | ||
|
||
// Gather analytics data. | ||
var pageName = viewModel.GetType().Name.Replace("ViewModel", string.Empty, StringComparison.OrdinalIgnoreCase); | ||
var isInModal = navigatorState.ActiveModal != null; | ||
var sectionName = navigatorState.ActiveSection.Name; | ||
|
||
// Send the analytics event. | ||
SendPageView(pageName, isInModal, sectionName); | ||
|
||
// Capture the last ViewModel instance to avoid duplicate events in the future. | ||
_lastViewModel = viewModel; | ||
} | ||
|
||
private void SendPageView(string pageName, bool isInModal, string sectionName) | ||
{ | ||
// TODO: Implement page views using a real analytics provider. | ||
if (!_logger.IsEnabled(LogLevel.Information)) | ||
{ | ||
return; | ||
} | ||
|
||
if (isInModal) | ||
{ | ||
_logger.LogInformation("Viewed page '{PageName}' in modal.", pageName); | ||
} | ||
else | ||
{ | ||
_logger.LogInformation("Viewed page '{PageName}' in section '{SectionName}'.", pageName, sectionName); | ||
} | ||
} | ||
|
||
public void TrackCommand(string commandName, object? commandParameter, WeakReference<IViewModel>? viewModel) | ||
{ | ||
// TODO: Implement command execution events using a real analytics provider. | ||
if (!_logger.IsEnabled(LogLevel.Information)) | ||
{ | ||
return; | ||
} | ||
|
||
if (viewModel?.TryGetTarget(out var vm) ?? false) | ||
{ | ||
_logger.LogInformation("Invoked command '{CommandName}' from ViewModel '{ViewModelName}'.", commandName, vm.Name); | ||
} | ||
else | ||
{ | ||
_logger.LogInformation("Invoked command '{CommandName}'.", commandName); | ||
} | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
src/app/ApplicationTemplate.Presentation/Framework/Analytics/AnalyticsCommandStrategy.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Chinook.DynamicMvvm; | ||
|
||
namespace ApplicationTemplate.Presentation; | ||
|
||
/// <summary> | ||
/// This <see cref="IDynamicCommandStrategy"/> tracks the success and failure of a command for analytics purposes. | ||
/// </summary> | ||
public sealed class AnalyticsCommandStrategy : DelegatingCommandStrategy | ||
{ | ||
private readonly IAnalyticsSink _analyticsSink; | ||
private readonly WeakReference<IViewModel> _viewModel; | ||
|
||
public AnalyticsCommandStrategy(IAnalyticsSink analyticsSink, IViewModel viewModel) | ||
{ | ||
_analyticsSink = analyticsSink; | ||
_viewModel = new WeakReference<IViewModel>(viewModel); | ||
} | ||
|
||
public override async Task Execute(CancellationToken ct, object parameter, IDynamicCommand command) | ||
{ | ||
_analyticsSink.TrackCommand(command.Name, parameter, _viewModel); | ||
|
||
await base.Execute(ct, parameter, command); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
src/app/ApplicationTemplate.Presentation/Framework/Analytics/IAnalyticsSink.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#nullable enable | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Chinook.DataLoader; | ||
using Chinook.DynamicMvvm; | ||
using Chinook.SectionsNavigation; | ||
|
||
namespace ApplicationTemplate.Presentation; | ||
|
||
/// <summary> | ||
/// This service collects raw analytics data from the application and processes it to send to an analytics provider (such as AppCenter, Firebase, Segment, etc.). | ||
/// </summary> | ||
public interface IAnalyticsSink | ||
{ | ||
/// <summary> | ||
/// Tracks a navigation event from which to derive page views. | ||
/// </summary> | ||
/// <param name="navigatorState">The state of the navigator.</param> | ||
void TrackNavigation(SectionsNavigatorState navigatorState); | ||
|
||
/// <summary> | ||
/// Tracks a command execution initiation. | ||
/// </summary> | ||
/// <param name="commandName">The name of the command.</param> | ||
/// <param name="commandParameter">The optional command parameter.</param> | ||
/// <param name="viewModel">An optional weak reference to the ViewModel owning the command.</param> | ||
void TrackCommand(string commandName, object? commandParameter, WeakReference<IViewModel>? viewModel); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.