Skip to content

Commit

Permalink
Merge branch 'develop' into test
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrispyPeaches committed Aug 15, 2024
2 parents a13f802 + 10e57f6 commit 7040fdd
Show file tree
Hide file tree
Showing 55 changed files with 1,336 additions and 793 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,14 @@ Focus Friends is a mobile app that uses a timer to track and record user focus s

[Visual Mockup](https://www.figma.com/file/HG8eqMzI47otQWYFIv5iK7/Focus-Timer-App-MockUp?type=design&node-id=0%3A1&mode=design&t=gdzpRvpkRlAWQJPb-1)


l

### Contributors
| Github Link | Name | Email |
| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------: | :---------------------: |
| <a href="https://github.com/chrispypeaches"><img src="https://avatars.githubusercontent.com/u/26045099?v=4" alt="chrispypeaches" width="50" height="50" style="border-radius: 50%;"></a> | Chris Perry | [email protected] |
| <a href="https://github.com/iggy808"><img src="https://avatars.githubusercontent.com/u/63073663?v=4" alt="iggy808" width="50" height="50" style="border-radius: 50%;"></a> | Evan Gray | [email protected] |
| <a href="https://github.com/JohnParks032"><img src="https://avatars.githubusercontent.com/u/80427077?v=4" alt="JohnParks032" width="50" height="50" style="border-radius: 50%;"></a> | John Parks | [email protected] |
| <a href="https://github.com/wesleypayton"><img src="https://avatars.githubusercontent.com/u/80854811?v=4" alt="wesleypayton" width="50" height="50" style="border-radius: 50%;"></a> | Elijah Payton | [email protected] |

1 change: 1 addition & 0 deletions src/FocusApp.Client/AppShell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using FocusApp.Client.Views.Social;
using SimpleToolkit.SimpleShell.Extensions;
using Microsoft.Maui;
using FocusApp.Client.Views.Settings;

namespace FocusApp.Client;

Expand Down
9 changes: 2 additions & 7 deletions src/FocusApp.Client/FocusApp.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@

<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
<MauiIcon Include="Resources\AppIcon\appicon.svg" Color="#BB8EFF" />

<!-- Splash Screen -->
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#BB8EFF" BaseSize="128,128" />
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#BB8EFF" BaseSize="456, 456" />

<!-- Images -->
<MauiImage Include="Resources\Images\*" />
Expand Down Expand Up @@ -105,11 +105,6 @@
</ItemGroup>

<PropertyGroup Condition="$(TargetFramework.Contains('-android')) and '$(Configuration)' == 'Release'">
<AndroidKeyStore>True</AndroidKeyStore>
<AndroidSigningKeyStore>ff.keystore</AndroidSigningKeyStore>
<AndroidSigningKeyAlias>MyAppkey</AndroidSigningKeyAlias>
<AndroidSigningKeyPass>2x4WFl6FUbU3</AndroidSigningKeyPass>
<AndroidSigningStorePass>2x4WFl6FUbU3</AndroidSigningStorePass>
</PropertyGroup>

</Project>
90 changes: 82 additions & 8 deletions src/FocusApp.Client/Helpers/AuthenticationService.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,52 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Auth0.OidcClient;
using FocusApp.Client.Views;
using FocusApp.Shared.Models;

namespace FocusApp.Client.Helpers;

internal interface IAuthenticationService
{
bool IsLoggedIn { get; }
Guid? Id { get; set; }
string? Auth0Id { get; set; }
string? Email { get; set; }
string? AuthToken { get; set; }
User? CurrentUser { get; set; }
string? UserName { get; set; }
string? Pronouns { get; set; }
int Balance { get; set; }
DateTime? DateCreated { get; set; }
byte[]? ProfilePicture { get; set; }
Island? SelectedIsland { get; set; }
Pet? SelectedPet { get; set; }
Badge? SelectedBadge { get; set; }
Decor? SelectedDecor { get; set; }
Task? StartupSyncTask { get; set; }

event PropertyChangedEventHandler? PropertyChanged;
void ClearUser();
Task Logout(IAuth0Client auth0Client);
void PopulateWithUserData(User user);
}

public class AuthenticationService : INotifyPropertyChanged, IAuthenticationService
{
public bool IsLoggedIn => Auth0Id is not null;
public event PropertyChangedEventHandler? PropertyChanged;
public Guid? Id { get; set; }
public string? Auth0Id { get; set; } = "";
public string? Email { get; set; } = "";
public string? AuthToken { get; set; } = "";

private User? _currentUser;
public User? CurrentUser
public string? UserName { get; set; } = "";
public string? Pronouns { get; set; } = "";
public DateTime? DateCreated { get; set; }
public byte[]? ProfilePicture { get; set; }
public Task? StartupSyncTask { get; set; }

private int? _balance;
public int Balance
{
get => _currentUser;
set => SetProperty(ref _currentUser, value);
get => _balance ?? 0;
set => SetProperty(ref _balance, value);
}

private Island? _selectedIsland;
Expand Down Expand Up @@ -60,6 +77,63 @@ public Decor? SelectedDecor
set => SetProperty(ref _selectedDecor, value);
}

/// <summary>
/// Remove user data from auth service and secure storage,
/// navigate to the login page,and
/// log the user out using the auth0 client.
/// </summary>
/// <remarks>
/// Note that the auth0Client.LogoutAsync needs to happen after the navigation
/// to LoginPage due to an issue with Maui navigation handlers.
/// Details here: https://github.com/dotnet/maui/issues/11259
/// </remarks>
public async Task Logout(IAuth0Client auth0Client)
{
ClearUser();

SecureStorage.Default.Remove("id_token");
SecureStorage.Default.Remove("access_token");

await Shell.Current.GoToAsync("///" + nameof(LoginPage));

await auth0Client.LogoutAsync();
}

/// <summary>
/// Remove all data for the "logged in" user.
/// </summary>
public void ClearUser()
{
Id = null;
Auth0Id = null;
Email = null;
UserName = null;
Pronouns = null;
Balance = 0;
DateCreated = DateTime.MinValue;
ProfilePicture = null;
SelectedIsland = null;
SelectedBadge = null;
SelectedDecor = null;
SelectedPet = null;
}

public void PopulateWithUserData(User user)
{
Id = user.Id;
Auth0Id = user.Auth0Id;
Email = user.Email;
UserName = user.UserName;
Pronouns = user.Pronouns;
Balance = user.Balance;
DateCreated = user.DateCreated;
ProfilePicture = user.ProfilePicture;
SelectedIsland = user.SelectedIsland;
SelectedBadge = user.SelectedBadge;
SelectedDecor = user.SelectedDecor;
SelectedPet = user.SelectedPet;
}

#region Property Changed Notification Logic

private void SetProperty<T>(ref T backingStore, in T value, [CallerMemberName] in string propertyname = "")
Expand Down
119 changes: 117 additions & 2 deletions src/FocusApp.Client/Helpers/SyncService.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,51 @@
using FocusApp.Shared.Data;
using FocusApp.Client.Methods.Sync;
using FocusApp.Shared.Data;
using FocusApp.Shared.Models;
using MediatR;
using Microsoft.Extensions.Logging;

namespace FocusApp.Client.Helpers;

public interface ISyncService
{
IQueryable<Island> GetInitialIslandQuery();
IQueryable<Pet> GetInitialPetQuery();

/// <summary>
/// Ensure the database is created and migrations are applied, then run the startup logic.
/// </summary>
Task RunStartupLogic();

/// <summary>
/// Populates the database with initial data requested from the API for any of
/// the island, pets, or decor tables if they don't have any entries.
/// </summary>
Task GatherEssentialDatabaseData();

/// <summary>
/// Syncs all item types in the <see cref="SyncItems.SyncItemType"/> enum between the API and mobile database
/// if the last sync happened over a week ago or this is the first time starting the app.
/// </summary>
/// <remarks>
/// If there's an unexpected error, the critical data for app functionality will be retrieved.
/// </remarks>
Task StartupSync();
}

public class SyncService : ISyncService
{
private readonly FocusAppContext _context;
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<ISyncService> _logger;

public SyncService(FocusAppContext context)
public SyncService(
FocusAppContext context,
IServiceProvider serviceProvider,
ILogger<ISyncService> logger)
{
_context = context;
_serviceProvider = serviceProvider;
_logger = logger;
}

public IQueryable<Island> GetInitialIslandQuery()
Expand All @@ -29,4 +59,89 @@ public IQueryable<Pet> GetInitialPetQuery()
return _context.Pets
.Where(pet => pet.Name == FocusCore.Consts.NameOfInitialPet);
}

/// <summary>
/// Ensure the database is created and migrations are applied, then run the startup logic.
/// </summary>
public async Task RunStartupLogic()
{

}

/// <summary>
/// Syncs all item types in the <see cref="SyncItems.SyncItemType"/> enum between the API and mobile database
/// if the last sync happened over a week ago or this is the first time starting the app.
/// </summary>
/// <remarks>
/// If there's an unexpected error, the critical data for app functionality will be retrieved.
/// </remarks>
public async Task StartupSync()
{
try
{

// If not in debug and a sync has been done in the past week, don't sync
#if !DEBUG
string lastSyncTimeString = PreferencesHelper.Get<string>(PreferencesHelper.PreferenceNames.last_sync_time);
if (!string.IsNullOrEmpty(lastSyncTimeString))
{
DateTimeOffset lastSyncTime = DateTimeOffset.Parse(lastSyncTimeString);

if (DateTimeOffset.UtcNow < lastSyncTime.AddDays(7))
return;
}
#endif

IList<Task> tasks = new List<Task>();
var scopedServiceProvider = _serviceProvider
.CreateScope()
.ServiceProvider;
_ = scopedServiceProvider.GetRequiredService<FocusAppContext>();

foreach (SyncItems.SyncItemType syncType in Enum.GetValues(typeof(SyncItems.SyncItemType)))
{
IMediator mediator = _serviceProvider
.CreateScope()
.ServiceProvider
.GetRequiredService<IMediator>();

tasks.Add(
Task.Run(() => mediator.Send(
new SyncItems.Query() { ItemType = syncType }
))
);
}

await Task.WhenAll(tasks);

PreferencesHelper.Set(PreferencesHelper.PreferenceNames.last_sync_time, DateTimeOffset.UtcNow.ToString("O"));
}
catch (Exception ex)
{
// If there's an error with island or pet sync, ensure the essential database information is gathered
_logger.LogError(ex, "Error occurred when syncing selectable items and mindfulness tips. Running essential database population.");
await GatherEssentialDatabaseData();
}
}

/// <summary>
/// Populates the database with initial data requested from the API for any of
/// the island, pets, or decor tables if they don't have any entries.
/// </summary>
public async Task GatherEssentialDatabaseData()
{
try
{
var scopedServiceProvider = _serviceProvider
.CreateScope()
.ServiceProvider;
IMediator mediator = scopedServiceProvider.GetRequiredService<IMediator>();

await mediator.Send(new SyncInitialData.Query());
}
catch (Exception ex)
{
_logger.LogError(ex, "Error when running essential database population.");
}
}
}
7 changes: 7 additions & 0 deletions src/FocusApp.Client/Helpers/UserManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ public UserManager(string domain, string clientId)
_clientId = clientId;
}

public async Task<string?> GetIdToken()
{
return await SecureStorage.Default.GetAsync("id_token");
}



public async Task<ClaimsPrincipal> GetAuthenticatedUser()
{
ClaimsPrincipal user = null;
Expand Down
Loading

0 comments on commit 7040fdd

Please sign in to comment.