profile editing finished
This commit is contained in:
@@ -0,0 +1,24 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
|
public class AccountProfileBackgroundRequest
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public required Guid Id { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
[SetsRequiredMembers]
|
||||||
|
public AccountProfileBackgroundRequest(Guid id)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using WatchIt.Common.Model.Accounts;
|
using WatchIt.Common.Model.Accounts;
|
||||||
using WatchIt.Common.Model.Movies;
|
using WatchIt.Common.Model.Movies;
|
||||||
using WatchIt.Common.Model.Persons;
|
using WatchIt.Common.Model.Persons;
|
||||||
|
using WatchIt.Common.Model.Photos;
|
||||||
using WatchIt.Common.Model.Series;
|
using WatchIt.Common.Model.Series;
|
||||||
using WatchIt.WebAPI.Services.Controllers.Accounts;
|
using WatchIt.WebAPI.Services.Controllers.Accounts;
|
||||||
|
|
||||||
@@ -14,6 +15,8 @@ namespace WatchIt.WebAPI.Controllers;
|
|||||||
[Route("accounts")]
|
[Route("accounts")]
|
||||||
public class AccountsController(IAccountsControllerService accountsControllerService) : ControllerBase
|
public class AccountsController(IAccountsControllerService accountsControllerService) : ControllerBase
|
||||||
{
|
{
|
||||||
|
#region Basic
|
||||||
|
|
||||||
[HttpPost("register")]
|
[HttpPost("register")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[ProducesResponseType(typeof(RegisterResponse), StatusCodes.Status201Created)]
|
[ProducesResponseType(typeof(RegisterResponse), StatusCodes.Status201Created)]
|
||||||
@@ -39,6 +42,10 @@ public class AccountsController(IAccountsControllerService accountsControllerSer
|
|||||||
[ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)]
|
[ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)]
|
||||||
public async Task<ActionResult> Logout() => await accountsControllerService.Logout();
|
public async Task<ActionResult> Logout() => await accountsControllerService.Logout();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Profile picture
|
||||||
|
|
||||||
[HttpGet("{id}/profile_picture")]
|
[HttpGet("{id}/profile_picture")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[ProducesResponseType(typeof(AccountProfilePictureResponse), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(AccountProfilePictureResponse), StatusCodes.Status200OK)]
|
||||||
@@ -59,6 +66,32 @@ public class AccountsController(IAccountsControllerService accountsControllerSer
|
|||||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
public async Task<ActionResult> DeleteAccountProfilePicture() => await accountsControllerService.DeleteAccountProfilePicture();
|
public async Task<ActionResult> DeleteAccountProfilePicture() => await accountsControllerService.DeleteAccountProfilePicture();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Profile background
|
||||||
|
|
||||||
|
[HttpGet("{id}/profile_background")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[ProducesResponseType(typeof(PhotoResponse), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult> GetAccountProfileBackground([FromRoute(Name = "id")]long id) => await accountsControllerService.GetAccountProfileBackground(id);
|
||||||
|
|
||||||
|
[HttpPut("profile_background")]
|
||||||
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||||
|
[ProducesResponseType(typeof(PhotoResponse), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
public async Task<ActionResult> PutAccountProfileBackground([FromBody]AccountProfileBackgroundRequest body) => await accountsControllerService.PutAccountProfileBackground(body);
|
||||||
|
|
||||||
|
[HttpDelete("profile_background")]
|
||||||
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
public async Task<ActionResult> DeleteAccountProfileBackground() => await accountsControllerService.DeleteAccountProfileBackground();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
[HttpGet("{id}/info")]
|
[HttpGet("{id}/info")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[ProducesResponseType(typeof(AccountResponse), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(AccountResponse), StatusCodes.Status200OK)]
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using WatchIt.Common.Model.Accounts;
|
|||||||
using WatchIt.Common.Model.Media;
|
using WatchIt.Common.Model.Media;
|
||||||
using WatchIt.Common.Model.Movies;
|
using WatchIt.Common.Model.Movies;
|
||||||
using WatchIt.Common.Model.Persons;
|
using WatchIt.Common.Model.Persons;
|
||||||
|
using WatchIt.Common.Model.Photos;
|
||||||
using WatchIt.Common.Model.Series;
|
using WatchIt.Common.Model.Series;
|
||||||
using WatchIt.Database;
|
using WatchIt.Database;
|
||||||
using WatchIt.Database.Model.Account;
|
using WatchIt.Database.Model.Account;
|
||||||
@@ -32,6 +33,8 @@ public class AccountsControllerService(
|
|||||||
{
|
{
|
||||||
#region PUBLIC METHODS
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
#region Basic
|
||||||
|
|
||||||
public async Task<RequestResult> Register(RegisterRequest data)
|
public async Task<RequestResult> Register(RegisterRequest data)
|
||||||
{
|
{
|
||||||
string leftSalt = StringExtensions.CreateRandom(20);
|
string leftSalt = StringExtensions.CreateRandom(20);
|
||||||
@@ -125,6 +128,10 @@ public class AccountsControllerService(
|
|||||||
return RequestResult.NoContent();
|
return RequestResult.NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Profile picture
|
||||||
|
|
||||||
public async Task<RequestResult> GetAccountProfilePicture(long id)
|
public async Task<RequestResult> GetAccountProfilePicture(long id)
|
||||||
{
|
{
|
||||||
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
@@ -185,6 +192,55 @@ public class AccountsControllerService(
|
|||||||
return RequestResult.NoContent();
|
return RequestResult.NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Profile background
|
||||||
|
|
||||||
|
public async Task<RequestResult> GetAccountProfileBackground(long id)
|
||||||
|
{
|
||||||
|
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
|
if (account is null)
|
||||||
|
{
|
||||||
|
return RequestResult.BadRequest()
|
||||||
|
.AddValidationError("id", "Account with this id does not exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account.BackgroundPicture is null)
|
||||||
|
{
|
||||||
|
return RequestResult.NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
PhotoResponse response = new PhotoResponse(account.BackgroundPicture);
|
||||||
|
return RequestResult.Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> PutAccountProfileBackground(AccountProfileBackgroundRequest data)
|
||||||
|
{
|
||||||
|
Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId());
|
||||||
|
|
||||||
|
account.BackgroundPictureId = data.Id;
|
||||||
|
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
|
PhotoResponse returnData = new PhotoResponse(account.BackgroundPicture!);
|
||||||
|
return RequestResult.Ok(returnData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> DeleteAccountProfileBackground()
|
||||||
|
{
|
||||||
|
Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId());
|
||||||
|
|
||||||
|
if (account.BackgroundPicture is not null)
|
||||||
|
{
|
||||||
|
account.BackgroundPictureId = null;
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
return RequestResult.NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public async Task<RequestResult> GetAccountInfo(long id)
|
public async Task<RequestResult> GetAccountInfo(long id)
|
||||||
{
|
{
|
||||||
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ public interface IAccountsControllerService
|
|||||||
Task<RequestResult> GetAccountProfilePicture(long id);
|
Task<RequestResult> GetAccountProfilePicture(long id);
|
||||||
Task<RequestResult> PutAccountProfilePicture(AccountProfilePictureRequest data);
|
Task<RequestResult> PutAccountProfilePicture(AccountProfilePictureRequest data);
|
||||||
Task<RequestResult> DeleteAccountProfilePicture();
|
Task<RequestResult> DeleteAccountProfilePicture();
|
||||||
|
Task<RequestResult> GetAccountProfileBackground(long id);
|
||||||
|
Task<RequestResult> PutAccountProfileBackground(AccountProfileBackgroundRequest data);
|
||||||
|
Task<RequestResult> DeleteAccountProfileBackground();
|
||||||
Task<RequestResult> GetAccountInfo(long id);
|
Task<RequestResult> GetAccountInfo(long id);
|
||||||
Task<RequestResult> PutAccountProfileInfo(AccountProfileInfoRequest data);
|
Task<RequestResult> PutAccountProfileInfo(AccountProfileInfoRequest data);
|
||||||
Task<RequestResult> GetAccountRatedMovies(long id, MovieRatedQueryParameters query);
|
Task<RequestResult> GetAccountRatedMovies(long id, MovieRatedQueryParameters query);
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Database;
|
||||||
|
|
||||||
|
namespace WatchIt.WebAPI.Validators.Accounts;
|
||||||
|
|
||||||
|
public class AccountProfileBackgroundRequestValidator : AbstractValidator<AccountProfileBackgroundRequest>
|
||||||
|
{
|
||||||
|
public AccountProfileBackgroundRequestValidator(DatabaseContext database)
|
||||||
|
{
|
||||||
|
RuleFor(x => x.Id).MustBeIn(database.MediaPhotoImages.Where(x => x.MediaPhotoImageBackground != null), x => x.Id)
|
||||||
|
.WithMessage("Image has to be background");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using WatchIt.Common.Model.Accounts;
|
using WatchIt.Common.Model.Accounts;
|
||||||
using WatchIt.Common.Model.Movies;
|
using WatchIt.Common.Model.Movies;
|
||||||
using WatchIt.Common.Model.Persons;
|
using WatchIt.Common.Model.Persons;
|
||||||
|
using WatchIt.Common.Model.Photos;
|
||||||
using WatchIt.Common.Model.Series;
|
using WatchIt.Common.Model.Series;
|
||||||
using WatchIt.Common.Services.HttpClient;
|
using WatchIt.Common.Services.HttpClient;
|
||||||
using WatchIt.Website.Services.Configuration;
|
using WatchIt.Website.Services.Configuration;
|
||||||
@@ -109,6 +110,46 @@ public class AccountsClientService(IHttpClientService httpClientService, IConfig
|
|||||||
.ExecuteAction();
|
.ExecuteAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task GetAccountProfileBackground(long id, Action<PhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountProfileBackground, id);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Get, url);
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.RegisterActionFor404NotFound(notFoundAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PutAccountProfileBackground(AccountProfileBackgroundRequest data, Action<PhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.PutAccountProfileBackground);
|
||||||
|
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Put, url)
|
||||||
|
{
|
||||||
|
Body = data
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteAccountProfileBackground(Action? successAction = null, Action? unauthorizedAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.DeleteAccountProfileBackground);
|
||||||
|
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Delete, url);
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task GetAccountInfo(long id, Action<AccountResponse>? successAction = null, Action? notFoundAction = null)
|
public async Task GetAccountInfo(long id, Action<AccountResponse>? successAction = null, Action? notFoundAction = null)
|
||||||
{
|
{
|
||||||
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountInfo, id);
|
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountInfo, id);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using WatchIt.Common.Model.Accounts;
|
using WatchIt.Common.Model.Accounts;
|
||||||
using WatchIt.Common.Model.Movies;
|
using WatchIt.Common.Model.Movies;
|
||||||
using WatchIt.Common.Model.Persons;
|
using WatchIt.Common.Model.Persons;
|
||||||
|
using WatchIt.Common.Model.Photos;
|
||||||
using WatchIt.Common.Model.Series;
|
using WatchIt.Common.Model.Series;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.Client.Accounts;
|
namespace WatchIt.Website.Services.Client.Accounts;
|
||||||
@@ -14,6 +15,9 @@ public interface IAccountsClientService
|
|||||||
Task GetAccountProfilePicture(long id, Action<AccountProfilePictureResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null);
|
Task GetAccountProfilePicture(long id, Action<AccountProfilePictureResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null);
|
||||||
Task PutAccountProfilePicture(AccountProfilePictureRequest data, Action<AccountProfilePictureResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
Task PutAccountProfilePicture(AccountProfilePictureRequest data, Action<AccountProfilePictureResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
||||||
Task DeleteAccountProfilePicture(Action? successAction = null, Action? unauthorizedAction = null);
|
Task DeleteAccountProfilePicture(Action? successAction = null, Action? unauthorizedAction = null);
|
||||||
|
Task GetAccountProfileBackground(long id, Action<PhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null);
|
||||||
|
Task PutAccountProfileBackground(AccountProfileBackgroundRequest data, Action<PhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
||||||
|
Task DeleteAccountProfileBackground(Action? successAction = null, Action? unauthorizedAction = null);
|
||||||
Task GetAccountInfo(long id, Action<AccountResponse>? successAction = null, Action? notFoundAction = null);
|
Task GetAccountInfo(long id, Action<AccountResponse>? successAction = null, Action? notFoundAction = null);
|
||||||
Task PutAccountProfileInfo(AccountProfileInfoRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
Task PutAccountProfileInfo(AccountProfileInfoRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
||||||
Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query, Action<IEnumerable<MovieRatedResponse>>? successAction = null, Action? notFoundAction = null);
|
Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query, Action<IEnumerable<MovieRatedResponse>>? successAction = null, Action? notFoundAction = null);
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ public class Accounts
|
|||||||
public string GetAccountProfilePicture { get; set; }
|
public string GetAccountProfilePicture { get; set; }
|
||||||
public string PutAccountProfilePicture { get; set; }
|
public string PutAccountProfilePicture { get; set; }
|
||||||
public string DeleteAccountProfilePicture { get; set; }
|
public string DeleteAccountProfilePicture { get; set; }
|
||||||
|
public string GetAccountProfileBackground { get; set; }
|
||||||
|
public string PutAccountProfileBackground { get; set; }
|
||||||
|
public string DeleteAccountProfileBackground { get; set; }
|
||||||
public string GetAccountInfo { get; set; }
|
public string GetAccountInfo { get; set; }
|
||||||
public string PutAccountProfileInfo { get; set; }
|
public string PutAccountProfileInfo { get; set; }
|
||||||
public string GetAccountRatedMovies { get; set; }
|
public string GetAccountRatedMovies { get; set; }
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<link rel="stylesheet" href="css/panel.css?version=0.3.0.5"/>
|
<link rel="stylesheet" href="css/panel.css?version=0.3.0.5"/>
|
||||||
<link rel="stylesheet" href="css/main_button.css?version=0.3.0.0"/>
|
<link rel="stylesheet" href="css/main_button.css?version=0.3.0.0"/>
|
||||||
<link rel="stylesheet" href="css/gaps.css?version=0.3.0.1"/>
|
<link rel="stylesheet" href="css/gaps.css?version=0.3.0.1"/>
|
||||||
<link rel="stylesheet" href="WatchIt.Website.styles.css?version=0.4.0.16"/>
|
<link rel="stylesheet" href="WatchIt.Website.styles.css?version=0.4.0.17"/>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
|
||||||
<!-- BOOTSTRAP -->
|
<!-- BOOTSTRAP -->
|
||||||
|
|||||||
@@ -1,5 +1,121 @@
|
|||||||
|
@using Blazorise.Components
|
||||||
|
@using WatchIt.Common.Model.Photos
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="vstack gap-3">
|
@if (_loaded)
|
||||||
<h4 class="fw-bold">Profile background</h4>
|
{
|
||||||
|
<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>
|
||||||
|
<button class="btn btn-danger" @onclick="@(Remove)">
|
||||||
|
<LoadingButtonContentComponent LoadingContent="Removing..." Content="Remove" IsLoading="@(_removeLoading)"/>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@if (_editMode)
|
||||||
|
{
|
||||||
|
<div class="vstack gap-3">
|
||||||
|
<div class="container-grid">
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col">
|
||||||
|
<Autocomplete ElementId="actorFormMedia"
|
||||||
|
TItem="MediaResponse"
|
||||||
|
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)" @onclick="@(LoadBackgrounds)">
|
||||||
|
<LoadingButtonContentComponent 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">
|
||||||
|
<PictureComponent Picture="@(photo)" AlternativeText="photo" Width="350" Placeholder="/assets/photo.png" AspectRatio="PictureComponent.PictureComponentAspectRatio.Photo"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row gx-2">
|
||||||
|
<div class="col">
|
||||||
|
<div class="border rounded-3" style="height: 30px; background: linear-gradient(45deg, @($"#{Convert.ToHexString(photo.Background!.FirstGradientColor)}, #{Convert.ToHexString(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.Id))">
|
||||||
|
<LoadingButtonContentComponent 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">
|
||||||
|
<PictureComponent Picture="@(_selectedPhoto)" AlternativeText="background" Width="500" Placeholder="/assets/photo.png" AspectRatio="PictureComponent.PictureComponentAspectRatio.Photo"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="rounded-3 border h-100" style="height: 30px; background: linear-gradient(45deg, @($"#{Convert.ToHexString(_selectedPhoto.Background!.FirstGradientColor)}, #{Convert.ToHexString(_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
|
||||||
|
{
|
||||||
|
<LoadingComponent Color="@(LoadingComponent.LoadingComponentColors.Light)"/>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -1,7 +1,128 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Common.Model.Media;
|
||||||
|
using WatchIt.Common.Model.Photos;
|
||||||
|
using WatchIt.Website.Services.Authentication;
|
||||||
|
using WatchIt.Website.Services.Client.Accounts;
|
||||||
|
using WatchIt.Website.Services.Client.Media;
|
||||||
|
|
||||||
namespace WatchIt.Website.Components.Pages.UserEditPage.Panels;
|
namespace WatchIt.Website.Components.Pages.UserEditPage.Panels;
|
||||||
|
|
||||||
public partial class ProfileBackgroundEditorPanelComponent : ComponentBase
|
public partial class ProfileBackgroundEditorPanelComponent : ComponentBase
|
||||||
{
|
{
|
||||||
|
#region SERVICES
|
||||||
|
|
||||||
|
[Inject] private IMediaClientService MediaClientService { get; set; } = default!;
|
||||||
|
[Inject] private IAccountsClientService AccountsClientService { get; set; } = default!;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PARAMETERS
|
||||||
|
|
||||||
|
[Parameter] public required long Id { get; set; }
|
||||||
|
[Parameter] public Action<PhotoResponse?>? OnBackgroundChanged { 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<MediaResponse> _mediaList = default!;
|
||||||
|
|
||||||
|
private PhotoResponse? _selectedPhoto;
|
||||||
|
private MediaResponse? _selectedPhotoMedia;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
await Task.WhenAll(
|
||||||
|
[
|
||||||
|
MediaClientService.GetAllMedia(successAction: data => _mediaList = data),
|
||||||
|
AccountsClientService.GetAccountProfileBackground(Id, data => _selectedPhoto = data)
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (_selectedPhoto is not null)
|
||||||
|
{
|
||||||
|
_selectedPhotoMedia = _mediaList.First(x => x.Id == _selectedPhoto.MediaId);
|
||||||
|
}
|
||||||
|
|
||||||
|
_loaded = true;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Save(Guid id)
|
||||||
|
{
|
||||||
|
_saveLoading = true;
|
||||||
|
await AccountsClientService.PutAccountProfileBackground(new AccountProfileBackgroundRequest(id), data =>
|
||||||
|
{
|
||||||
|
OnBackgroundChanged?.Invoke(data);
|
||||||
|
_selectedPhoto = data;
|
||||||
|
_selectedPhotoMedia = _mediaList.First(x => x.Id == _selectedMedia!.Value);
|
||||||
|
_saveLoading = false;
|
||||||
|
Cancel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Cancel()
|
||||||
|
{
|
||||||
|
_editMode = false;
|
||||||
|
_selectedMedia = default;
|
||||||
|
_saveLoading = false;
|
||||||
|
_backgroundsLoading = false;
|
||||||
|
_mediaPhotos = default;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Edit()
|
||||||
|
{
|
||||||
|
_editMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Remove()
|
||||||
|
{
|
||||||
|
_removeLoading = true;
|
||||||
|
await AccountsClientService.DeleteAccountProfileBackground(() =>
|
||||||
|
{
|
||||||
|
OnBackgroundChanged?.Invoke(null);
|
||||||
|
_selectedPhoto = null;
|
||||||
|
_selectedPhotoMedia = null;
|
||||||
|
_removeLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadBackgrounds()
|
||||||
|
{
|
||||||
|
_backgroundsLoading = true;
|
||||||
|
PhotoQueryParameters query = new PhotoQueryParameters
|
||||||
|
{
|
||||||
|
IsBackground = true
|
||||||
|
};
|
||||||
|
await MediaClientService.GetMediaPhotos(_selectedMedia!.Value, query, successAction: data =>
|
||||||
|
{
|
||||||
|
_mediaPhotos = data;
|
||||||
|
_backgroundsLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
@using System.Text
|
@using System.Text
|
||||||
@using WatchIt.Common.Model
|
@using WatchIt.Common.Model
|
||||||
|
@using WatchIt.Common.Model.Photos
|
||||||
@using WatchIt.Website.Components.Pages.UserEditPage.Panels
|
@using WatchIt.Website.Components.Pages.UserEditPage.Panels
|
||||||
|
|
||||||
|
|
||||||
@page "/user/edit"
|
@page "/user/edit"
|
||||||
|
|
||||||
@{
|
@{
|
||||||
@@ -60,7 +62,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row mt-default">
|
<div class="row mt-default">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<ProfileBackgroundEditorPanelComponent/>
|
<ProfileBackgroundEditorPanelComponent Id="@(_user.Id)"
|
||||||
|
OnBackgroundChanged="BackgroundChanged"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using WatchIt.Common.Model;
|
using WatchIt.Common.Model;
|
||||||
|
using WatchIt.Common.Model.Photos;
|
||||||
using WatchIt.Website.Components.Pages.UserEditPage.Panels;
|
using WatchIt.Website.Components.Pages.UserEditPage.Panels;
|
||||||
using WatchIt.Website.Layout;
|
using WatchIt.Website.Layout;
|
||||||
using WatchIt.Website.Services.Authentication;
|
using WatchIt.Website.Services.Authentication;
|
||||||
@@ -50,11 +51,12 @@ public partial class UserEditPage : ComponentBase
|
|||||||
if (_user is null)
|
if (_user is null)
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo($"/auth?redirect_to={WebUtility.UrlEncode("/user/edit")}");
|
NavigationManager.NavigateTo($"/auth?redirect_to={WebUtility.UrlEncode("/user/edit")}");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
|
||||||
|
await AccountsClientService.GetAccountProfileBackground(_user.Id, data => Layout.BackgroundPhoto = data);
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,5 +66,10 @@ public partial class UserEditPage : ComponentBase
|
|||||||
Layout.ReloadProfilePicture()
|
Layout.ReloadProfilePicture()
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
private void BackgroundChanged(PhotoResponse? background)
|
||||||
|
{
|
||||||
|
Layout.BackgroundPhoto = background;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
<HorizontalListPanelComponent TItem="MovieRatedResponse"
|
<HorizontalListPanelComponent TItem="MovieRatedResponse"
|
||||||
Title="Recently rated movies"
|
Title="Recently rated movies"
|
||||||
Count="6"
|
Count="6"
|
||||||
GetItemsAction="@(action => AccountsClientService.GetAccountRatedMovies(Id!.Value, new MovieRatedQueryParameters { First = 6, OrderBy = "user_rating_date" }, successAction: action))"
|
GetItemsAction="@(action => AccountsClientService.GetAccountRatedMovies(_accountData.Id, new MovieRatedQueryParameters { First = 6, OrderBy = "user_rating_date" }, successAction: action))"
|
||||||
ItemUrlFormatString="/media/{0}"
|
ItemUrlFormatString="/media/{0}"
|
||||||
IdSource="@(item => item.Id)"
|
IdSource="@(item => item.Id)"
|
||||||
NameSource="@(item => item.ReleaseDate.HasValue ? $"{item.Title} ({item.ReleaseDate.Value.Year})" : item.Title)"
|
NameSource="@(item => item.ReleaseDate.HasValue ? $"{item.Title} ({item.ReleaseDate.Value.Year})" : item.Title)"
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
<HorizontalListPanelComponent TItem="SeriesRatedResponse"
|
<HorizontalListPanelComponent TItem="SeriesRatedResponse"
|
||||||
Title="Recently rated TV series"
|
Title="Recently rated TV series"
|
||||||
Count="6"
|
Count="6"
|
||||||
GetItemsAction="@(action => AccountsClientService.GetAccountRatedSeries(Id!.Value, new SeriesRatedQueryParameters { First = 6, OrderBy = "user_rating_date" }, successAction: action))"
|
GetItemsAction="@(action => AccountsClientService.GetAccountRatedSeries(_accountData.Id, new SeriesRatedQueryParameters { First = 6, OrderBy = "user_rating_date" }, successAction: action))"
|
||||||
ItemUrlFormatString="/media/{0}"
|
ItemUrlFormatString="/media/{0}"
|
||||||
IdSource="@(item => item.Id)"
|
IdSource="@(item => item.Id)"
|
||||||
NameSource="@(item => item.ReleaseDate.HasValue ? $"{item.Title} ({item.ReleaseDate.Value.Year})" : item.Title)"
|
NameSource="@(item => item.ReleaseDate.HasValue ? $"{item.Title} ({item.ReleaseDate.Value.Year})" : item.Title)"
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
<HorizontalListPanelComponent TItem="PersonRatedResponse"
|
<HorizontalListPanelComponent TItem="PersonRatedResponse"
|
||||||
Title="Recently rated people"
|
Title="Recently rated people"
|
||||||
Count="6"
|
Count="6"
|
||||||
GetItemsAction="@(action => AccountsClientService.GetAccountRatedPersons(Id!.Value, new PersonRatedQueryParameters { First = 6, OrderBy = "user_rating_last_date" }, successAction: action))"
|
GetItemsAction="@(action => AccountsClientService.GetAccountRatedPersons(_accountData.Id, new PersonRatedQueryParameters { First = 6, OrderBy = "user_rating_last_date" }, successAction: action))"
|
||||||
ItemUrlFormatString="/person/{0}"
|
ItemUrlFormatString="/person/{0}"
|
||||||
IdSource="@(item => item.Id)"
|
IdSource="@(item => item.Id)"
|
||||||
NameSource="@(item => item.Name)"
|
NameSource="@(item => item.Name)"
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
SecondaryRatingTitle="User rating"
|
SecondaryRatingTitle="User rating"
|
||||||
UrlIdTemplate="/media/{0}"
|
UrlIdTemplate="/media/{0}"
|
||||||
PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))"
|
PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))"
|
||||||
ItemDownloadingTask="@((query, action) => AccountsClientService.GetAccountRatedMovies(Id!.Value, query, action))"
|
ItemDownloadingTask="@((query, action) => AccountsClientService.GetAccountRatedMovies(_accountData.Id, query, action))"
|
||||||
SortingOptions="@(new Dictionary<string, string> { { "user_rating", "User rating" }, { "user_rating_date", "User rating date" }, { "rating.count", "Number of ratings" }, { "rating.average", "Average rating" }, { "title", "Title" }, { "release_date", "Release date" } })"
|
SortingOptions="@(new Dictionary<string, string> { { "user_rating", "User rating" }, { "user_rating_date", "User rating date" }, { "rating.count", "Number of ratings" }, { "rating.average", "Average rating" }, { "title", "Title" }, { "release_date", "Release date" } })"
|
||||||
PosterPlaceholder="/assets/media_poster.png"
|
PosterPlaceholder="/assets/media_poster.png"
|
||||||
GetGlobalRatingMethod="@((id, action) => MediaClientService.GetMediaRating(id, action))"
|
GetGlobalRatingMethod="@((id, action) => MediaClientService.GetMediaRating(id, action))"
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
SecondaryRatingTitle="User rating"
|
SecondaryRatingTitle="User rating"
|
||||||
UrlIdTemplate="/media/{0}"
|
UrlIdTemplate="/media/{0}"
|
||||||
PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))"
|
PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))"
|
||||||
ItemDownloadingTask="@((query, action) => AccountsClientService.GetAccountRatedSeries(Id!.Value, query, action))"
|
ItemDownloadingTask="@((query, action) => AccountsClientService.GetAccountRatedSeries(_accountData.Id, query, action))"
|
||||||
SortingOptions="@(new Dictionary<string, string> { { "user_rating", "User rating" }, { "user_rating_date", "User rating date" }, { "rating.count", "Number of ratings" }, { "rating.average", "Average rating" }, { "title", "Title" }, { "release_date", "Release date" } })"
|
SortingOptions="@(new Dictionary<string, string> { { "user_rating", "User rating" }, { "user_rating_date", "User rating date" }, { "rating.count", "Number of ratings" }, { "rating.average", "Average rating" }, { "title", "Title" }, { "release_date", "Release date" } })"
|
||||||
PosterPlaceholder="/assets/media_poster.png"
|
PosterPlaceholder="/assets/media_poster.png"
|
||||||
GetGlobalRatingMethod="@((id, action) => MediaClientService.GetMediaRating(id, action))"
|
GetGlobalRatingMethod="@((id, action) => MediaClientService.GetMediaRating(id, action))"
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
SecondaryRatingTitle="User rating"
|
SecondaryRatingTitle="User rating"
|
||||||
UrlIdTemplate="/media/{0}"
|
UrlIdTemplate="/media/{0}"
|
||||||
PictureDownloadingTask="@((id, action) => PersonsClientService.GetPersonPhoto(id, action))"
|
PictureDownloadingTask="@((id, action) => PersonsClientService.GetPersonPhoto(id, action))"
|
||||||
ItemDownloadingTask="@((query, action) => AccountsClientService.GetAccountRatedPersons(Id!.Value, query, action))"
|
ItemDownloadingTask="@((query, action) => AccountsClientService.GetAccountRatedPersons(_accountData.Id, query, action))"
|
||||||
SortingOptions="@(new Dictionary<string, string>
|
SortingOptions="@(new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
{ "user_rating.average", "Average user rating" },
|
{ "user_rating.average", "Average user rating" },
|
||||||
|
|||||||
@@ -50,17 +50,25 @@ public partial class UserPage : ComponentBase
|
|||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
|
List<Task> step1Tasks = new List<Task>();
|
||||||
List<Task> endTasks = new List<Task>();
|
List<Task> endTasks = new List<Task>();
|
||||||
|
|
||||||
// INIT
|
// INIT
|
||||||
Layout.BackgroundPhoto = null;
|
Layout.BackgroundPhoto = null;
|
||||||
|
|
||||||
// STEP 0
|
// STEP 0
|
||||||
endTasks.AddRange(
|
step1Tasks.AddRange(
|
||||||
[
|
[
|
||||||
GetUserData()
|
GetUserData()
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// STEP 1
|
||||||
|
await Task.WhenAll(step1Tasks);
|
||||||
|
endTasks.AddRange(
|
||||||
|
[
|
||||||
|
AccountsClientService.GetAccountProfileBackground(_accountData.Id, data => Layout.BackgroundPhoto = data)
|
||||||
|
]);
|
||||||
|
|
||||||
// END
|
// END
|
||||||
await Task.WhenAll(endTasks);
|
await Task.WhenAll(endTasks);
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,9 @@
|
|||||||
"GetAccountProfilePicture": "/{0}/profile_picture",
|
"GetAccountProfilePicture": "/{0}/profile_picture",
|
||||||
"PutAccountProfilePicture": "/profile_picture",
|
"PutAccountProfilePicture": "/profile_picture",
|
||||||
"DeleteAccountProfilePicture": "/profile_picture",
|
"DeleteAccountProfilePicture": "/profile_picture",
|
||||||
|
"GetAccountProfileBackground": "/{0}/profile_background",
|
||||||
|
"PutAccountProfileBackground": "/profile_background",
|
||||||
|
"DeleteAccountProfileBackground": "/profile_background",
|
||||||
"GetAccountInfo": "/{0}/info",
|
"GetAccountInfo": "/{0}/info",
|
||||||
"PutAccountProfileInfo": "/profile_info",
|
"PutAccountProfileInfo": "/profile_info",
|
||||||
"GetAccountRatedMovies": "/{0}/movies",
|
"GetAccountRatedMovies": "/{0}/movies",
|
||||||
|
|||||||
Reference in New Issue
Block a user