Skip to content

Commit

Permalink
feat: add analytics to sharing feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Arley Pádua authored and Arley Pádua committed Nov 30, 2024
1 parent d3e958e commit 52f6c87
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/PKHeX.Web/BackendApi/Repositories/UserRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public async Task<UserRepresentation> GetSignedInUser()
if (_cache.Get(SignedInUserKey) is UserRepresentation user)
return user;

var firebaseUser = await auth.GetSignedInUser();
var firebaseUser = await auth.GetSignedInUserOrThrow();
user = new UserRepresentation
{
Id = firebaseUser.Id,
Expand Down
20 changes: 16 additions & 4 deletions src/PKHeX.Web/Components/Pokemons/PokemonOnCloud.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@using PKHeX.Web.BackendApi
@using PKHeX.Web.BackendApi.Repositories
@using PKHeX.Web.BackendApi.Representation
@using PKHeX.Web.Services.Auth
@implements IDisposable
@inject INotificationService Notification
@inject SyncPokemonWorker SyncWorker
Expand All @@ -9,6 +10,8 @@
@inject MyPokemonRepository MyPokemonRepository
@inject NavigationManager Navigation
@inject UserRepository UserRepository
@inject AnalyticsService AnalyticsService
@inject AuthService Auth

<Space Style="width: 100%; gap: 10px;" Direction="DirectionVHType.Vertical">
<ResponsibleDescriptions Bordered Size="small" Style="width: 100%">
Expand Down Expand Up @@ -112,6 +115,8 @@
Description = $"You have reached your sync quota: {user.SyncQuota}.",
NotificationType = NotificationType.Error
});

AnalyticsService.TrackPokemonSyncQuotaExceeded(await Auth.GetSignedInUserOrThrow(), user.SyncQuota);
}
else
{
Expand All @@ -128,6 +133,11 @@
{
await MyPokemonRepository.RemoveByLocalId(Pokemon.GetLocalSyncId());
}

if (_syncedMetadata is not null)
{
AnalyticsService.TrackPokemonSyncStopped(_syncedMetadata, await Auth.GetSignedInUserOrThrow());
}
}

await RefreshMetadata();
Expand All @@ -141,6 +151,7 @@
if (_syncedMetadata is null) return;

await MyPokemonRepository.Share(_syncedMetadata.Id, isShared);
AnalyticsService.TrackPokemonPublicToggle(_syncedMetadata, isShared, await Auth.GetSignedInUserOrThrow());

await RefreshMetadata();
}
Expand All @@ -150,21 +161,22 @@
if (_syncedMetadata is null) return;

await MyPokemonRepository.AllowDownload(_syncedMetadata.Id, isAllowed);
AnalyticsService.TrackPokemonDownloadToggle(_syncedMetadata, isAllowed, await Auth.GetSignedInUserOrThrow());

await RefreshMetadata();
}

private Task HandlePokemonUploaded(PokemonUploadedArgs arg)
private async Task HandlePokemonUploaded(PokemonUploadedArgs arg)
{
if (arg.Pokemon.GetLocalSyncId() != Pokemon.GetLocalSyncId()) return Task.CompletedTask;
if (arg.Pokemon.GetLocalSyncId() != Pokemon.GetLocalSyncId()) return;

_syncedMetadata = arg.Metadata;

AnalyticsService.TrackPokemonSyncStarted(arg.Metadata, await Auth.GetSignedInUserOrThrow());

SetSyncingStatuses();

StateHasChanged();

return Task.CompletedTask;
}

private void SetSyncingStatuses()
Expand Down
6 changes: 5 additions & 1 deletion src/PKHeX.Web/Pages/Home.razor
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
@inject AntdThemeService ThemeService
@inject PlugInRegistry PlugInRegistry
@inject PlugInRuntime PlugInRuntime
@inject IConfiguration Configuration

<PageTitle>Home</PageTitle>

Expand Down Expand Up @@ -46,7 +47,10 @@
</Descriptions>
}

<CloudSummary />
@if (Configuration.GetBackendApiOptions().Enabled)
{
<CloudSummary />
}

</Space>

Expand Down
11 changes: 7 additions & 4 deletions src/PKHeX.Web/Pages/SharedPokemon.razor
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
@page "/s/{Id}"
@using PKHeX.Web.BackendApi
@using PKHeX.Web.BackendApi.Repositories
@using PKHeX.Web.BackendApi.Representation
@using PKHeX.Web.Services.Auth
@inject PublicPokemonRepository PublicPokemonRepository
@inject NavigationManager Navigation
@inject JsService Js
@inject AnalyticsService AnalyticsService
@inject AuthService Auth
@inject ILogger<SharedPokemon> Logger

@if (_metadata is not null)
Expand Down Expand Up @@ -42,8 +44,6 @@

private PokemonPublicMetadataRepresentation? _metadata;

private readonly ListGridType _grid = new() { Gutter = 16, Column = 4 };

protected override async Task OnInitializedAsync()
{
var parsed = Guid.TryParse(Id, out _id);
Expand All @@ -56,6 +56,7 @@
try
{
_metadata = await PublicPokemonRepository.GetById(_id);
AnalyticsService.TrackSharedPokemonSeen(_metadata, await Auth.GetSignedInUser());
}
catch (Exception e)
{
Expand All @@ -79,7 +80,9 @@
private async Task HandleDownloadClick()
{
if (_metadata is null) return;


AnalyticsService.TrackSharedPokemonDownloaded(_metadata, await Auth.GetSignedInUser());

var file = await PublicPokemonRepository.GetBinaries(_metadata.Id);
var memoryStream = new MemoryStream(file);
var fileName = $"{_metadata.Species}-{_metadata.Id}.bin";
Expand Down
99 changes: 98 additions & 1 deletion src/PKHeX.Web/Services/AnalyticsService.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using Blazor.Analytics;
using Microsoft.AspNetCore.Components;
using PKHeX.Facade;
using PKHeX.Facade.Pokemons;
using PKHeX.Facade.Repositories;
using PKHeX.Web.BackendApi.Representation;
using PKHeX.Web.Components;
using PKHeX.Web.Extensions;
using PKHeX.Web.Plugins;
using PKHeX.Web.Services.Auth;
using PKHeX.Web.Services.Plugins;

namespace PKHeX.Web.Services;
Expand Down Expand Up @@ -67,6 +69,101 @@ public void TrackPokemon(string eventType, Pokemon pokemon, PokemonSource? sourc
});
}

public void TrackSharedPokemonSeen(PokemonPublicMetadataRepresentation pokemon, AuthService.User? user = null)
{
analytics.TrackEvent("shared_pokemon_seen", new
{
id = pokemon.Id.ToString(),
species_id = (int)pokemon.Species,
species_name = pokemon.Species.ToString(),
gender = pokemon.Gender.Name,
ball_name = ItemRepository.GetItem(Convert.ToUInt16(pokemon.MetConditions.BallId)).Name,
level = pokemon.Level,
seen_by_user_id = user?.Id
});
}

public void TrackSharedPokemonDownloaded(PokemonPublicMetadataRepresentation pokemon, AuthService.User? user = null)
{
analytics.TrackEvent("shared_pokemon_downloaded", new
{
id = pokemon.Id.ToString(),
species_id = (int)pokemon.Species,
species_name = pokemon.Species.ToString(),
gender = pokemon.Gender.Name,
ball_name = ItemRepository.GetItem(Convert.ToUInt16(pokemon.MetConditions.BallId)).Name,
level = pokemon.Level,
downloaded_by_user_id = user?.Id
});
}

public void TrackPokemonSyncStarted(PokemonMetadataRepresentation pokemon, AuthService.User user)
{
analytics.TrackEvent("pokemon_sync_started", new
{
id = pokemon.Id.ToString(),
species_id = (int)pokemon.Species,
species_name = pokemon.Species.ToString(),
gender = pokemon.Gender.Name,
ball_name = ItemRepository.GetItem(Convert.ToUInt16(pokemon.MetConditions.BallId)).Name,
level = pokemon.Level,
user_id = user.Id
});
}

public void TrackPokemonSyncStopped(PokemonMetadataRepresentation pokemon, AuthService.User user)
{
analytics.TrackEvent("pokemon_sync_stopped", new
{
id = pokemon.Id.ToString(),
species_id = (int)pokemon.Species,
species_name = pokemon.Species.ToString(),
gender = pokemon.Gender.Name,
ball_name = ItemRepository.GetItem(Convert.ToUInt16(pokemon.MetConditions.BallId)).Name,
level = pokemon.Level,
user_id = user.Id
});
}

public void TrackPokemonPublicToggle(PokemonMetadataRepresentation pokemon, bool isShared, AuthService.User user)
{
analytics.TrackEvent("pokemon_sync_stopped", new
{
id = pokemon.Id.ToString(),
species_id = (int)pokemon.Species,
species_name = pokemon.Species.ToString(),
gender = pokemon.Gender.Name,
ball_name = ItemRepository.GetItem(Convert.ToUInt16(pokemon.MetConditions.BallId)).Name,
level = pokemon.Level,
is_shared = isShared,
user_id = user.Id
});
}

public void TrackPokemonDownloadToggle(PokemonMetadataRepresentation pokemon, bool isAllowed, AuthService.User user)
{
analytics.TrackEvent("pokemon_sync_stopped", new
{
id = pokemon.Id.ToString(),
species_id = (int)pokemon.Species,
species_name = pokemon.Species.ToString(),
gender = pokemon.Gender.Name,
ball_name = ItemRepository.GetItem(Convert.ToUInt16(pokemon.MetConditions.BallId)).Name,
level = pokemon.Level,
is_allowed = isAllowed,
user_id = user.Id
});
}

public void TrackPokemonSyncQuotaExceeded(AuthService.User user, int userQuota)
{
analytics.TrackEvent("pokemon_sync_quota_exceeded", new
{
user_id = user.Id,
user_quota = userQuota
});
}

public void TrackItemModified(AddItemModal.ItemToBeAdded itemToBeAdded)
{
analytics.TrackEvent("item_modified", new
Expand Down
13 changes: 11 additions & 2 deletions src/PKHeX.Web/Services/Auth/AuthService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ public async Task<string> GetAuthToken()
return authToken;
}

public async Task<User> GetSignedInUser()
public async Task<User?> GetSignedInUser()
{
return await js.InvokeAsync<User>("getSignedInUser");
return await js.InvokeAsync<User?>("getSignedInUser");
}

[JSInvokable]
Expand All @@ -52,4 +52,13 @@ public record IdTokenChangedArgs(
{
public bool IsSignedIn => !string.IsNullOrEmpty(Token);
}
}

public static class AuthServiceExtensions
{
public static async Task<AuthService.User> GetSignedInUserOrThrow(this AuthService auth)
{
var user = await auth.GetSignedInUser();
return user ?? throw new InvalidOperationException("User is not signed in");
}
}
2 changes: 1 addition & 1 deletion src/PKHeX.Web/_js/lib/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function initFirebase() {
}

window.getSignedInUser = () => {
if (!auth.currentUser) throw new Error('No user found')
if (!auth.currentUser) return null
return {
id: auth.currentUser.uid,
email: auth.currentUser.email,
Expand Down
2 changes: 1 addition & 1 deletion src/PKHeX.Web/_js/lib/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ declare global {
isSignedIn: () => boolean;
getAuthToken: () => Promise<IdToken>;
signInAnonymously: () => Promise<IdToken>;
getSignedInUser: () => User;
getSignedInUser: () => User | null;
signOut: () => Promise<void>;
}
}

0 comments on commit 52f6c87

Please sign in to comment.