MainLayout - data downloading improved, background displaying improved

This commit is contained in:
2024-09-27 19:38:05 +02:00
Unverified
parent dca28d0794
commit fd99280ebf
8 changed files with 211 additions and 183 deletions

View File

@@ -2,20 +2,8 @@
namespace WatchIt.Common.Model.Accounts; namespace WatchIt.Common.Model.Accounts;
public abstract class AccountProfilePicture public abstract class AccountProfilePicture : Picture
{ {
#region PROPERTIES
[JsonPropertyName("image")]
public required byte[] Image { get; set; }
[JsonPropertyName("mime_type")]
public required string MimeType { get; set; }
#endregion
#region CONSTRUCTORS #region CONSTRUCTORS
[JsonConstructor] [JsonConstructor]

View File

@@ -1,9 +1,13 @@
@using WatchIt.Common.Model.Photos @using WatchIt.Common.Model.Photos
@using WatchIt.Website.Services.WebAPI.Photos @using WatchIt.Website.Services.WebAPI.Photos
@inherits LayoutComponentBase @inherits LayoutComponentBase
@if (_loaded)
{
<CascadingValue Value="this">
@if (_loaded)
{
<div class="container-xl"> <div class="container-xl">
<div class="row align-items-center m-1 my-2 mb-3 rounded-3 header panel panel-header z-3"> <div class="row align-items-center m-1 my-2 mb-3 rounded-3 header panel panel-header z-3">
<div class="col-2"> <div class="col-2">
@@ -23,8 +27,8 @@
else else
{ {
<div class="dropdown z-3"> <div class="dropdown z-3">
<a class="dropdown-toggle align-items-center text-decoration-none d-flex" id="dropdownUser" aria-expanded="false" @onclick="() => _userMenuIsActive = !_userMenuIsActive"> <a class="dropdown-toggle align-items-center text-decoration-none d-flex" id="dropdownUser" aria-expanded="false" @onclick="() => _menuUserIsActive = !_menuUserIsActive">
<img class="rounded-circle" alt="avatar" height="30" src="@(_userProfilePicture)"/> <img class="rounded-circle" alt="avatar" height="30" src="@(_userProfilePicture is null ? "assets/user_placeholder.png" : _userProfilePicture.ToString())"/>
<div class="text-decoration-none mx-2 text-white">@(_user.Username)</div> <div class="text-decoration-none mx-2 text-white">@(_user.Username)</div>
</a> </a>
<ul class="dropdown-menu dropdown-menu-right text-small z-3" id="user-menu" aria-labelledby="dropdownUser"> <ul class="dropdown-menu dropdown-menu-right text-small z-3" id="user-menu" aria-labelledby="dropdownUser">
@@ -50,129 +54,24 @@
</div> </div>
<style> <style>
html { /* TAGS */
height: 100%;
}
body { body {
background-image: url('@_background'); background-image: url('@(BackgroundPhoto?.Background is null ? "assets/background_temp.jpg": BackgroundPhoto.ToString())');
height: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
} }
.logo, .main-button {
background-image: linear-gradient(45deg, @_firstGradientColor, @_secondGradientColor); /* IDS */
}
#user-menu { #user-menu {
display: @(_userMenuIsActive ? "block" : "none"); display: @(_menuUserIsActive ? "block" : "none");
position: fixed; }
/* CLASSES */
.logo, .main-button {
background-image: linear-gradient(45deg, @(BackgroundPhoto?.Background is null ? "#c6721c, #85200c" : $"#{Convert.ToHexString(BackgroundPhoto.Background.FirstGradientColor)}, #{Convert.ToHexString(BackgroundPhoto.Background.SecondGradientColor)}"));
} }
</style> </style>
}
@code
{
#region SERVICES
[Inject] public ILogger<MainLayout> Logger { get; set; } = default!;
[Inject] public NavigationManager NavigationManager { get; set; } = default!;
[Inject] public ITokensService TokensService { get; set; } = default!;
[Inject] public IAuthenticationService AuthenticationService { get; set; } = default!;
[Inject] public IAccountsWebAPIService AccountsWebAPIService { get; set; } = default!;
[Inject] public IMediaWebAPIService MediaWebAPIService { get; set; } = default!;
[Inject] public IPhotosWebAPIService PhotosWebAPIService { get; set; } = default!;
#endregion
#region FIELDS
private bool _loaded = false;
private string _background = "assets/background_temp.jpg";
private string _firstGradientColor = "#c6721c";
private string _secondGradientColor = "#85200c";
private User? _user = null;
private string _userProfilePicture = "assets/user_placeholder.png";
private bool _userMenuIsActive = false;
#endregion
#region METHODS
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
List<Task> bgTasks = new List<Task>();
bgTasks.Add(GetBackground());
await GetAuthenticatedUser();
if (_user is not null)
{
bgTasks.Add(GetProfilePicture());
} }
</CascadingValue>
await Task.WhenAll(bgTasks);
_loaded = true;
StateHasChanged();
}
}
private async Task GetBackground()
{
Action<PhotoResponse> backgroundSuccess = (data) =>
{
string imageBase64 = Convert.ToBase64String(data.Image);
string firstColor = BitConverter.ToString(data.Background.FirstGradientColor)
.Replace("-", string.Empty);
string secondColor = BitConverter.ToString(data.Background.SecondGradientColor)
.Replace("-", string.Empty);
_background = $"data:{data.MimeType};base64,{imageBase64}";
_firstGradientColor = $"#{firstColor}";
_secondGradientColor = $"#{secondColor}";
};
await PhotosWebAPIService.GetPhotoRandomBackground(backgroundSuccess);
}
private async Task GetAuthenticatedUser()
{
_user = await AuthenticationService.GetUserAsync();
}
private async Task GetProfilePicture()
{
Action<AccountProfilePictureResponse> successAction = (data) =>
{
string imageBase64 = Convert.ToBase64String(data.Image);
_userProfilePicture = $"data:{data.MimeType};base64,{imageBase64}";
};
await AccountsWebAPIService.GetAccountProfilePicture(_user.Id, successAction);
}
private async Task UserMenuLogOut()
{
await AuthenticationService.LogoutAsync();
await TokensService.RemoveAuthenticationData();
NavigationManager.Refresh(true);
}
#endregion
}

View File

@@ -0,0 +1,102 @@
using Microsoft.AspNetCore.Components;
using WatchIt.Common.Model.Accounts;
using WatchIt.Common.Model.Photos;
using WatchIt.Website.Services.Utility.Authentication;
using WatchIt.Website.Services.Utility.Tokens;
using WatchIt.Website.Services.WebAPI.Accounts;
using WatchIt.Website.Services.WebAPI.Media;
using WatchIt.Website.Services.WebAPI.Photos;
namespace WatchIt.Website.Layout;
public partial class MainLayout : LayoutComponentBase
{
#region SERVICES
[Inject] public ILogger<MainLayout> Logger { get; set; } = default!;
[Inject] public NavigationManager NavigationManager { get; set; } = default!;
[Inject] public ITokensService TokensService { get; set; } = default!;
[Inject] public IAuthenticationService AuthenticationService { get; set; } = default!;
[Inject] public IAccountsWebAPIService AccountsWebAPIService { get; set; } = default!;
[Inject] public IMediaWebAPIService MediaWebAPIService { get; set; } = default!;
[Inject] public IPhotosWebAPIService PhotosWebAPIService { get; set; } = default!;
#endregion
#region FIELDS
private bool _loaded = false;
private User? _user = null;
private AccountProfilePictureResponse? _userProfilePicture;
private bool _menuUserIsActive;
#endregion
#region PROPERTIES
public PhotoResponse? BackgroundPhoto { get; set; }
#endregion
#region PRIVATE METHODS
#region Main
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
List<Task> endTasks = new List<Task>();
List<Task> step1Tasks = new List<Task>();
// STEP 0
step1Tasks.AddRange(
[
Task.Run(async () => _user = await AuthenticationService.GetUserAsync())
]);
endTasks.AddRange(
[
PhotosWebAPIService.GetPhotoRandomBackground(data => BackgroundPhoto = data)
]);
// STEP 1
await Task.WhenAll(step1Tasks);
if (_user is not null)
{
endTasks.AddRange(
[
AccountsWebAPIService.GetAccountProfilePicture(_user.Id, data => _userProfilePicture = data)
]);
}
// END
await Task.WhenAll(endTasks);
_loaded = true;
StateHasChanged();
}
}
#endregion
#region User menu
private async Task UserMenuLogOut()
{
await AuthenticationService.LogoutAsync();
await TokensService.RemoveAuthenticationData();
NavigationManager.Refresh(true);
}
#endregion
#endregion
}

View File

@@ -1,7 +1,21 @@
body { /* TAGS */
background-size: cover;
h1 {
margin: 0;
} }
/* IDS */
#user-menu {
position: fixed;
}
/* CLASSES */
.logo { .logo {
font-size: 40px; font-size: 40px;
} }
@@ -15,7 +29,3 @@ body {
.body-content { .body-content {
padding-top: 100px; padding-top: 100px;
} }
h1 {
margin: 0;
}

View File

@@ -0,0 +1,5 @@
@page "/search"
<h3>SearchPage</h3>

View File

@@ -0,0 +1,7 @@
using Microsoft.AspNetCore.Components;
namespace WatchIt.Website.Pages;
public partial class SearchPage : ComponentBase
{
}

View File

@@ -1,5 +1,22 @@
/* TAGS */
html {
height: 100%;
}
body {
background-position: center;
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
height: 100%;
}
body, html { body, html {
background-color: transparent; background-color: transparent;
height: 100%; height: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;