Refactoring, database structure changed

This commit is contained in:
2025-03-03 00:56:32 +01:00
Unverified
parent d3805ef3db
commit c603c41c0b
913 changed files with 21764 additions and 32775 deletions

View File

@@ -0,0 +1,50 @@
@using WatchIt.DTO.Models.Controllers.Genders.Gender
@using WatchIt.Website.Components.Subcomponents.Common
@inherits Component
<div class="panel @(Class)">
@if (_loaded)
{
<div class="vstack gap-3">
<h4 class="fw-bold">Basic profile info</h4>
<EditForm Model="@(_data)">
<AntiforgeryToken/>
<div class="container-grid">
<div class="row form-group my-1">
<label for="desc" class="col-2 col-form-label">Description</label>
<div class="col-10">
<InputTextArea id="desc" class="form-control" @bind-Value="_data!.Description"/>
</div>
</div>
<div class="row form-group my-1">
<label for="desc" class="col-2 col-form-label">Gender</label>
<div class="col-10">
<InputSelect TValue="short?" id="desc" class="form-control" @bind-Value="_data!.GenderId">
<option value="">No choice</option>
@foreach (GenderResponse gender in _genders)
{
<option value="@(gender.Id)">@(gender.Name)</option>
}
</InputSelect>
</div>
</div>
<div class="row mt-2">
<div class="col">
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-secondary" disabled="@(_saving)" @onclick="@(Save)">
<LoadingButtonContent IsLoading="@(_saving)" Content="Save" LoadingContent="Saving..."/>
</button>
</div>
</div>
</div>
</div>
</EditForm>
</div>
}
else
{
<Loading Color="@(Loading.Colors.Light)"/>
}
</div>

View File

@@ -0,0 +1,105 @@
using System.Net;
using Blazorise.Snackbar;
using Microsoft.AspNetCore.Components;
using Refit;
using WatchIt.DTO.Models.Controllers.Accounts;
using WatchIt.DTO.Models.Controllers.Accounts.Account;
using WatchIt.DTO.Models.Controllers.Accounts.AccountProfileInfo;
using WatchIt.DTO.Models.Controllers.Genders.Gender;
using WatchIt.Website.Clients;
using WatchIt.Website.Components.Layout;
using WatchIt.Website.Services.Authentication;
namespace WatchIt.Website.Components.Panels.Pages.UserEditPage;
public partial class EditFormPanel : Component
{
#region SERVICES
[Inject] private IAuthenticationService AuthenticationService { get; set; } = null!;
[Inject] private NavigationManager NavigationManager { get; set; } = null!;
[Inject] private IAccountsClient AccountsClient { get; set; } = null!;
[Inject] private IGendersClient GendersClient { get; set; } = null!;
#endregion
#region PARAMETERS
[Parameter] public required AccountResponse Data { get; set; }
[Parameter] public string Class { get; set; } = string.Empty;
#endregion
#region FIELDS
private bool _loaded;
private bool _saving;
private IEnumerable<GenderResponse> _genders = [];
private AccountProfileInfoRequest _data = new AccountProfileInfoRequest();
#endregion
#region PRIVATE METHODS
protected override async Task OnFirstRenderAsync()
{
_data = Data.ToProfileInfoRequest();
IApiResponse<IEnumerable<GenderResponse>> response = await GendersClient.GetGenders();
if (response.IsSuccessful)
{
_genders = response.Content;
}
else
{
await Base.SnackbarStack.PushAsync("An error occured. List of genders could not be obtained.", SnackbarColor.Danger);
}
_loaded = true;
StateHasChanged();
}
private async Task Save()
{
_saving = true;
string token = await AuthenticationService.GetRawAccessTokenAsync() ?? string.Empty;
IApiResponse response = await AccountsClient.PatchAccountProfileInfo(token, _data!);
switch (response)
{
case { IsSuccessful: true}:
await Base.SnackbarStack.PushAsync("Profile info successfully saved.", SnackbarColor.Success);
break;
case { StatusCode: HttpStatusCode.Forbidden } or { StatusCode: HttpStatusCode.Unauthorized }:
await Base.SnackbarStack.PushAsync("Authentication error", SnackbarColor.Danger);
break;
case { StatusCode: HttpStatusCode.BadRequest }:
string? content = "An unknown error occured.";
if (response.Error is ValidationApiException ex)
{
string? exContent = ex.Content?.Errors.SelectMany(x => x.Value).FirstOrDefault();
if (exContent is not null)
{
content = exContent;
}
}
await Base.SnackbarStack.PushAsync(content, SnackbarColor.Danger);
break;
default:
await Base.SnackbarStack.PushAsync("An unknown error occured.", SnackbarColor.Danger);
break;
}
_saving = false;
}
#endregion
}

View File

@@ -0,0 +1,15 @@
@using WatchIt.Website.Components.Subcomponents.Common
@inherits Component
<div class="panel" role="button" @onclick="@(() => NavigationManager.NavigateTo("/user"))">
<div class="d-flex gap-3 align-items-center">
<AccountPicture Item="@(Data)" Size="60"/>
<div class="d-flex-inline flex-column">
<h2 id="primaryText" class="fw-bold m-0">@(Data.Username)</h2>
<span id="secondaryText" class="text-secondary">User settings</span>
</div>
</div>
</div>

View File

@@ -0,0 +1,23 @@
using Microsoft.AspNetCore.Components;
using WatchIt.DTO.Models.Controllers.Accounts.Account;
using WatchIt.Website.Clients;
using WatchIt.Website.Components.Subcomponents.Common;
namespace WatchIt.Website.Components.Panels.Pages.UserEditPage;
public partial class HeaderPanel : Component
{
#region SERVICES
[Inject] public NavigationManager NavigationManager { get; set; } = null!;
#endregion
#region PARAMETERS
[Parameter] public required AccountResponse Data { get; set; }
#endregion
}

View File

@@ -0,0 +1,9 @@
/* IDS */
#primaryText {
margin-top: -8px !important;
}
#secondaryText {
color: lightgray !important;
}

View File

@@ -0,0 +1,44 @@
@using WatchIt.Website.Components.Subcomponents.Common
@inherits Component
<div class="panel">
<div class="vstack gap-3">
<h4 class="fw-bold">Change email</h4>
@if (_data is not null)
{
<EditForm Model="@(_data)">
<AntiforgeryToken/>
<div class="container-grid">
<div class="row form-group my-1">
<label for="email" class="col-2 col-form-label">New email</label>
<div class="col-10">
<InputText id="email" class="form-control" @bind-Value="_data!.Email"/>
</div>
</div>
<div class="row form-group my-1">
<label for="password" class="col-2 col-form-label">Password</label>
<div class="col-10">
<InputText id="password" type="password" class="form-control" @bind-Value="_data!.Password"/>
</div>
</div>
<div class="row mt-2">
<div class="col">
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-secondary" disabled="@(_saving)" @onclick="@(Save)">
<LoadingButtonContent IsLoading="@(_saving)" Content="Save" LoadingContent="Saving..."/>
</button>
</div>
</div>
</div>
</div>
</EditForm>
}
else
{
<Loading Color="@(Loading.Colors.Light)"/>
}
</div>
</div>

View File

@@ -0,0 +1,91 @@
using System.Net;
using Blazorise.Snackbar;
using Microsoft.AspNetCore.Components;
using Refit;
using WatchIt.DTO.Models.Controllers.Accounts.Account;
using WatchIt.DTO.Models.Controllers.Accounts.AccountEmail;
using WatchIt.Website.Clients;
using WatchIt.Website.Components.Layout;
using WatchIt.Website.Services.Authentication;
namespace WatchIt.Website.Components.Panels.Pages.UserEditPage;
public partial class NewEmailPanel : Component
{
#region SERVICES
[Inject] private IAuthenticationService AuthenticationService { get; set; } = default!;
[Inject] private IAccountsClient AccountsClient { get; set; } = null!;
[Inject] private NavigationManager NavigationManager { get; set; } = null!;
#endregion
#region PARAMETERS
[Parameter] public required AccountResponse Data { get; set; }
#endregion
#region FIELDS
private AccountEmailRequest? _data;
private bool _saving;
#endregion
#region PRIVATE METHODS
protected override async Task OnFirstRenderAsync()
{
_data = new AccountEmailRequest
{
Email = Data.Email,
};
StateHasChanged();
}
private async Task Save()
{
_saving = true;
string token = await AuthenticationService.GetRawAccessTokenAsync() ?? string.Empty;
IApiResponse response = await AccountsClient.PatchAccountEmail(token, _data!);
switch (response)
{
case { IsSuccessful: true}:
Data.Email = _data!.Email;
_data.Password = string.Empty;
await Base.SnackbarStack.PushAsync("Email successfully saved.", SnackbarColor.Success);
break;
case { StatusCode: HttpStatusCode.Forbidden } or { StatusCode: HttpStatusCode.Unauthorized }:
await Base.SnackbarStack.PushAsync("Incorrect password", SnackbarColor.Danger);
break;
case { StatusCode: HttpStatusCode.BadRequest }:
string? content = "An unknown error occured.";
if (response.Error is ValidationApiException ex)
{
string? exContent = ex.Content?.Errors.SelectMany(x => x.Value).FirstOrDefault();
if (exContent is not null)
{
content = exContent;
}
}
await Base.SnackbarStack.PushAsync(content, SnackbarColor.Danger);
break;
default:
await Base.SnackbarStack.PushAsync("An unknown error occured.", SnackbarColor.Danger);
break;
}
_saving = false;
}
#endregion
}

View File

@@ -0,0 +1,50 @@
@using WatchIt.Website.Components.Subcomponents.Common
@inherits Component
<div class="panel">
<div class="vstack gap-3">
<h4 class="fw-bold">Change password</h4>
@if (_data is not null)
{
<EditForm Model="@(_data)">
<AntiforgeryToken/>
<div class="container-grid">
<div class="row form-group my-1">
<label for="oldPassword" class="col-2 col-form-label">Old password</label>
<div class="col-10">
<InputText id="oldPassword" type="password" class="form-control" @bind-Value="_data.OldPassword"/>
</div>
</div>
<div class="row form-group my-1">
<label for="newPassword" class="col-2 col-form-label">New password</label>
<div class="col-10">
<InputText id="newPassword" type="password" class="form-control" @bind-Value="_data.Password"/>
</div>
</div>
<div class="row form-group my-1">
<label for="newPasswordConf" class="col-2 col-form-label">Confirm new password</label>
<div class="col-10">
<InputText id="newPasswordConf" type="password" class="form-control" @bind-Value="_data.PasswordConfirmation"/>
</div>
</div>
<div class="row mt-2">
<div class="col">
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-secondary" disabled="@(_saving)" @onclick="@(Save)">
<LoadingButtonContent IsLoading="@(_saving)" Content="Save" LoadingContent="Saving..."/>
</button>
</div>
</div>
</div>
</div>
</EditForm>
}
else
{
<Loading Color="@(Loading.Colors.Light)"/>
}
</div>
</div>

View File

@@ -0,0 +1,81 @@
using System.Net;
using Blazorise.Snackbar;
using Microsoft.AspNetCore.Components;
using Refit;
using WatchIt.DTO.Models.Controllers.Accounts.Account;
using WatchIt.DTO.Models.Controllers.Accounts.AccountPassword;
using WatchIt.Website.Clients;
using WatchIt.Website.Components.Layout;
using WatchIt.Website.Services.Authentication;
namespace WatchIt.Website.Components.Panels.Pages.UserEditPage;
public partial class NewPasswordPanel : Component
{
#region SERVICES
[Inject] private IAuthenticationService AuthenticationService { get; set; } = null!;
[Inject] private IAccountsClient AccountsClient { get; set; } = null!;
[Inject] private NavigationManager NavigationManager { get; set; } = null!;
#endregion
#region PARAMETERS
[Parameter] public required AccountResponse Data { get; set; }
#endregion
#region FIELDS
private AccountPasswordRequest? _data = new AccountPasswordRequest();
private bool _saving;
#endregion
#region PRIVATE METHODS
private async Task Save()
{
_saving = true;
string token = await AuthenticationService.GetRawAccessTokenAsync() ?? string.Empty;
IApiResponse response = await AccountsClient.PatchAccountPassword(token, _data!);
switch (response)
{
case { IsSuccessful: true}:
_data = new AccountPasswordRequest();
await Base.SnackbarStack.PushAsync("Password successfully saved.", SnackbarColor.Success);
break;
case { StatusCode: HttpStatusCode.Forbidden } or { StatusCode: HttpStatusCode.Unauthorized }:
await Base.SnackbarStack.PushAsync("Incorrect password", SnackbarColor.Danger);
break;
case { StatusCode: HttpStatusCode.BadRequest }:
string? content = "An unknown error occured.";
if (response.Error is ValidationApiException ex)
{
string? exContent = ex.Content?.Errors.SelectMany(x => x.Value).FirstOrDefault();
if (exContent is not null)
{
content = exContent;
}
}
await Base.SnackbarStack.PushAsync(content, SnackbarColor.Danger);
break;
default:
await Base.SnackbarStack.PushAsync("An unknown error occured.", SnackbarColor.Danger);
break;
}
_saving = false;
}
#endregion
}

View File

@@ -0,0 +1,44 @@
@using WatchIt.Website.Components.Subcomponents.Common
@inherits Component
<div class="panel">
<div class="vstack gap-3">
<h4 class="fw-bold">Change username</h4>
@if (_data is not null)
{
<EditForm Model="@(_data)">
<AntiforgeryToken/>
<div class="container-grid">
<div class="row form-group my-1">
<label for="username" class="col-2 col-form-label">New username</label>
<div class="col-10">
<InputText id="username" class="form-control" @bind-Value="_data!.Username"/>
</div>
</div>
<div class="row form-group my-1">
<label for="password" class="col-2 col-form-label">Password</label>
<div class="col-10">
<InputText id="password" type="password" class="form-control" @bind-Value="_data!.Password"/>
</div>
</div>
<div class="row mt-2">
<div class="col">
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-secondary" disabled="@(_saving)" @onclick="@(Save)">
<LoadingButtonContent IsLoading="@(_saving)" Content="Save" LoadingContent="Saving..."/>
</button>
</div>
</div>
</div>
</div>
</EditForm>
}
else
{
<Loading Color="@(Loading.Colors.Light)"/>
}
</div>
</div>

View File

@@ -0,0 +1,91 @@
using System.Net;
using Blazorise.Snackbar;
using Microsoft.AspNetCore.Components;
using Refit;
using WatchIt.DTO.Models.Controllers.Accounts.Account;
using WatchIt.DTO.Models.Controllers.Accounts.AccountUsername;
using WatchIt.Website.Clients;
using WatchIt.Website.Components.Layout;
using WatchIt.Website.Services.Authentication;
namespace WatchIt.Website.Components.Panels.Pages.UserEditPage;
public partial class NewUsernamePanel : Component
{
#region SERVICES
[Inject] private IAuthenticationService AuthenticationService { get; set; } = null!;
[Inject] private IAccountsClient AccountsClient { get; set; } = null!;
[Inject] private NavigationManager NavigationManager { get; set; } = null!;
#endregion
#region PARAMETERS
[Parameter] public required AccountResponse Data { get; set; }
#endregion
#region FIELDS
private AccountUsernameRequest? _data;
private bool _saving;
#endregion
#region PRIVATE METHODS
protected override async Task OnFirstRenderAsync()
{
_data = new AccountUsernameRequest
{
Username = Data.Username,
};
StateHasChanged();
}
private async Task Save()
{
_saving = true;
string token = await AuthenticationService.GetRawAccessTokenAsync() ?? string.Empty;
IApiResponse response = await AccountsClient.PatchAccountUsername(token, _data!);
switch (response)
{
case { IsSuccessful: true}:
Data.Username = _data!.Username;
_data.Password = string.Empty;
await Base.SnackbarStack.PushAsync("Username successfully saved.", SnackbarColor.Success);
break;
case { StatusCode: HttpStatusCode.Forbidden } or { StatusCode: HttpStatusCode.Unauthorized }:
await Base.SnackbarStack.PushAsync("Incorrect password", SnackbarColor.Danger);
break;
case { StatusCode: HttpStatusCode.BadRequest }:
string? content = "An unknown error occured.";
if (response.Error is ValidationApiException ex)
{
string? exContent = ex.Content?.Errors.SelectMany(x => x.Value).FirstOrDefault();
if (exContent is not null)
{
content = exContent;
}
}
await Base.SnackbarStack.PushAsync(content, SnackbarColor.Danger);
break;
default:
await Base.SnackbarStack.PushAsync("An unknown error occured.", SnackbarColor.Danger);
break;
}
_saving = false;
}
#endregion
}

View File

@@ -0,0 +1,129 @@
@using System.Drawing
@using WatchIt.DTO.Models.Controllers.Photos.Photo
@using WatchIt.Website.Components.Subcomponents.Common
@using Blazorise.Components
@using WatchIt.DTO.Models.Controllers.Media.Medium.Response
@inherits Component
<div class="panel">
@if (_loaded)
{
<div class="vstack gap-4">
<div class="d-flex align-items-center gap-3">
<h4 class="me-auto m-0 fw-bold">Profile background</h4>
@if (_editMode)
{
<button class="btn btn-danger" @onclick="@(Cancel)">Cancel</button>
}
else
{
<button class="btn btn-secondary" @onclick="@(Edit)">Edit</button>
if (Base.CustomBackground is not null)
{
<button class="btn btn-danger" @onclick="@(Remove)">
<LoadingButtonContent LoadingContent="Removing..." Content="Remove" IsLoading="@(_removeLoading)"/>
</button>
}
}
</div>
@if (_editMode)
{
<div class="vstack gap-3">
<div class="container-grid">
<div class="row gx-2">
<div class="col">
<Autocomplete ElementId="actorFormMedia"
TItem="MediumResponse"
TValue="long?"
Data="@(_mediaList)"
TextField="@(item => item.ReleaseDate.HasValue ? $"{item.Title} ({item.ReleaseDate.Value.Year})" : item.Title)"
ValueField="@(item => item.Id)"
@bind-SelectedValue="@(_selectedMedia)"
Placeholder="Search media..."
Filter="AutocompleteFilter.Contains">
<NotFoundContent Context="not_found_context"> Sorry... @not_found_context was not found</NotFoundContent>
</Autocomplete>
</div>
<div class="col-auto">
<button class="btn btn-secondary" disabled="@(_backgroundsLoading || _selectedMedia is null)" @onclick="@(LoadBackgrounds)">
<LoadingButtonContent LoadingContent="Loading..." Content="Load backgrounds" IsLoading="@(_backgroundsLoading)"/>
</button>
</div>
</div>
</div>
@if (_mediaPhotos is null)
{
<span class="text-center">Select media first</span>
}
else if (!_mediaPhotos.Any())
{
<span class="text-center">No backgrounds for this media</span>
}
else
{
<div id="scrollPhotos" class="d-flex p-3 gap-3" data-bs-spy="scroll" tabindex="0">
@foreach (PhotoResponse photo in _mediaPhotos)
{
<div class="photo-container">
<div class="container-grid">
<div class="row mb-2">
<div class="col">
<Image Content="@(photo)" AlternativeText="photo" Width="350" Placeholder="/assets/photo.png" AspectRatio="Image.ImageComponentAspectRatio.Photo"/>
</div>
</div>
<div class="row gx-2">
<div class="col">
<div class="border rounded-3" style="height: 30px; background: linear-gradient(45deg, @($"{ColorTranslator.ToHtml(photo.Background!.FirstGradientColor)}, {ColorTranslator.ToHtml(photo.Background!.SecondGradientColor)}")"></div>
</div>
<div class="col-auto">
<button type="button" class="btn btn-secondary btn-sm" disabled="@(_saveLoading)" @onclick="@(async () => await Save(photo.Background.Id))">
<LoadingButtonContent LoadingContent="Saving..." Content="Select" IsLoading="@(_saveLoading)"/>
</button>
</div>
</div>
</div>
</div>
}
</div>
}
</div>
}
else
{
if (_selectedPhoto is not null)
{
<div class="container-grid">
<div class="row gx-3 mb-2">
<div class="col">
<Image Class="w-100" Content="@(_selectedPhoto)" AlternativeText="background" Placeholder="/assets/placeholders/photo.png" AspectRatio="Image.ImageComponentAspectRatio.Photo"/>
</div>
<div class="col">
<div class="rounded-3 border h-100" style="height: 30px; background: linear-gradient(45deg, @($"{ColorTranslator.ToHtml(_selectedPhoto.Background!.FirstGradientColor)}, {ColorTranslator.ToHtml(_selectedPhoto.Background!.SecondGradientColor)}"));"></div>
</div>
</div>
<div class="row">
<div class="col">
<div class="d-flex justify-content-center">
<a class="text-decoration-none text-reset" href="/media/@(_selectedPhotoMedia!.Id)">
from <span class="fw-bold">@(_selectedPhotoMedia.Title)</span>@(_selectedPhotoMedia.ReleaseDate.HasValue ? $" ({_selectedPhotoMedia.ReleaseDate.Value.Year})" : string.Empty)
</a>
</div>
</div>
</div>
</div>
}
else
{
<span class="text-center">You don't have selected background. Click "Edit" to choose one.</span>
}
}
</div>
}
else
{
<Loading Color="@(Loading.Colors.Light)"/>
}
</div>

View File

@@ -0,0 +1,179 @@
using System.Net;
using Blazorise.Snackbar;
using Microsoft.AspNetCore.Components;
using Refit;
using WatchIt.DTO.Models.Controllers.Accounts.AccountBackgroundPicture;
using WatchIt.DTO.Models.Controllers.Media.Medium.Response;
using WatchIt.DTO.Models.Controllers.Photos.Photo;
using WatchIt.Website.Clients;
using WatchIt.Website.Components.Layout;
using WatchIt.Website.Services.Authentication;
namespace WatchIt.Website.Components.Panels.Pages.UserEditPage;
public partial class ProfileBackgroundEditorPanel : Component
{
#region SERVICES
[Inject] private IAuthenticationService AuthenticationService { get; set; } = null!;
[Inject] private IMediaClient MediaClient { get; set; } = null!;
[Inject] private IPhotosClient PhotosClient { get; set; } = null!;
[Inject] private IAccountsClient AccountsClient { get; set; } = null!;
#endregion
#region PARAMETERS
[Parameter] public required long Id { get; set; }
#endregion
#region FIELDS
private bool _loaded;
private bool _editMode;
private long? _selectedMedia;
private IEnumerable<PhotoResponse>? _mediaPhotos;
private bool _backgroundsLoading;
private bool _saveLoading;
private bool _removeLoading;
private IEnumerable<MediumResponse> _mediaList = null!;
private PhotoResponse? _selectedPhoto;
private MediumResponse? _selectedPhotoMedia;
#endregion
#region PRIVATE METHODS
protected override async Task OnFirstRenderAsync()
{
await LoadMedia();
_selectedPhoto = Base.CustomBackground;
if (_selectedPhoto is not null)
{
_selectedPhotoMedia = _mediaList.First(x => x.Id == _selectedPhoto.MediumId);
}
_loaded = true;
StateHasChanged();
}
private async Task LoadMedia()
{
IApiResponse<IEnumerable<MediumResponse>> response = await MediaClient.GetMedia();
if (response.IsSuccessful)
{
_mediaList = response.Content;
}
else
{
await Base.SnackbarStack.PushAsync("An error occured. List of media could not be loaded.", SnackbarColor.Danger);
}
}
private async Task Save(Guid id)
{
_saveLoading = true;
string token = await AuthenticationService.GetRawAccessTokenAsync() ?? string.Empty;
IApiResponse<PhotoResponse> response = await AccountsClient.PutAccountBackgroundPicture(token, new AccountBackgroundPictureRequest { Id = id });
switch (response)
{
case { IsSuccessful: true}:
Base.CustomBackground = response.Content;
_selectedPhoto = Base.CustomBackground;
_selectedPhotoMedia = _mediaList.First(x => x.Id == _selectedMedia!.Value);
await Base.SnackbarStack.PushAsync("Background picture successfully saved.", SnackbarColor.Success);
break;
case { StatusCode: HttpStatusCode.Forbidden } or { StatusCode: HttpStatusCode.Unauthorized }:
await Base.SnackbarStack.PushAsync("Authentication error", SnackbarColor.Danger);
break;
case { StatusCode: HttpStatusCode.BadRequest }:
string? content = "An unknown error occured.";
if (response.Error is ValidationApiException ex)
{
string? exContent = ex.Content?.Errors.SelectMany(x => x.Value).FirstOrDefault();
if (exContent is not null)
{
content = exContent;
}
}
await Base.SnackbarStack.PushAsync(content, SnackbarColor.Danger);
break;
default:
await Base.SnackbarStack.PushAsync("An unknown error occured.", SnackbarColor.Danger);
break;
}
_saveLoading = false;
Cancel();
}
private void Cancel()
{
_editMode = false;
_selectedMedia = null;
_saveLoading = false;
_backgroundsLoading = false;
_mediaPhotos = null;
}
private void Edit()
{
_editMode = true;
}
private async Task Remove()
{
_removeLoading = true;
string token = await AuthenticationService.GetRawAccessTokenAsync() ?? string.Empty;
IApiResponse response = await AccountsClient.DeleteAccountBackgroundPicture(token);
if (response.IsSuccessful)
{
Base.CustomBackground = null;
_selectedPhoto = null;
_selectedPhotoMedia = null;
await Base.SnackbarStack.PushAsync("Background picture successfully removed.", SnackbarColor.Success);
}
else
{
await Base.SnackbarStack.PushAsync("An error occured. Background picture could not be removed.", SnackbarColor.Danger);
}
_removeLoading = false;
}
private async Task LoadBackgrounds()
{
_backgroundsLoading = true;
IApiResponse<IEnumerable<PhotoResponse>> response = await PhotosClient.GetPhotos(new PhotoFilterQuery()
{
IsBackground = true,
MediumId = _selectedMedia!.Value
});
if (!response.IsSuccessful)
{
await Base.SnackbarStack.PushAsync("An error occured. Background photos could not be obtained.", SnackbarColor.Danger);
}
_mediaPhotos = response.Content;
_backgroundsLoading = false;
}
#endregion
}

View File

@@ -0,0 +1,23 @@
/* IDS */
#scrollPhotos {
overflow-x: scroll;
border-color: grey;
border-width: 1px;
border-style: solid;
border-radius: 10px;
}
#backgroundIndicator {
height: 30px;
width: 30px;
}
/* CLASSES */
.photo-container {
width: 350px;
}