rating adding completed

This commit is contained in:
2024-09-20 23:37:55 +02:00
Unverified
parent 774b8832b5
commit 0ffd92d9c8
16 changed files with 561 additions and 114 deletions

View File

@@ -7,6 +7,10 @@ public class Media
public string GetGenres { get; set; }
public string PostGenre { get; set; }
public string DeleteGenre { get; set; }
public string GetMediaRating { get; set; }
public string GetMediaRatingByUser { get; set; }
public string PutMediaRating { get; set; }
public string DeleteMediaRating { get; set; }
public string GetPhotoMediaRandomBackground { get; set; }
public string GetPoster { get; set; }
public string PutPoster { get; set; }

View File

@@ -5,9 +5,16 @@ namespace WatchIt.Website.Services.WebAPI.Media;
public interface IMediaWebAPIService
{
Task Get(long mediaId, Action<MediaResponse> successAction = null, Action? notFoundAction = null);
Task GetGenres(long mediaId, Action<IEnumerable<GenreResponse>>? successAction = null, Action? notFoundAction = null);
Task PostGenre(long mediaId, long genreId, Action? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null, Action? notFoundAction = null);
Task GetMedia(long mediaId, Action<MediaResponse>? successAction = null, Action? notFoundAction = null);
Task GetMediaGenres(long mediaId, Action<IEnumerable<GenreResponse>>? successAction = null, Action? notFoundAction = null);
Task PostMediaGenre(long mediaId, long genreId, Action? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null, Action? notFoundAction = null);
Task GetMediaRating(long mediaId, Action<MediaRatingResponse>? successAction = null, Action? notFoundAction = null);
Task GetMediaRatingByUser(long mediaId, long userId, Action<short>? successAction = null, Action? notFoundAction = null);
Task PutMediaRating(long mediaId, MediaRatingRequest body, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null, Action? notFoundAction = null);
Task DeleteMediaRating(long mediaId, Action? successAction = null, Action? unauthorizedAction = null);
Task GetPhotoMediaRandomBackground(long mediaId, Action<MediaPhotoResponse>? successAction = null, Action? notFoundAction = null);
Task GetPhotoRandomBackground(Action<MediaPhotoResponse>? successAction = null, Action? notFoundAction = null);
Task GetPoster(long mediaId, Action<MediaPosterResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null);

View File

@@ -10,8 +10,10 @@ namespace WatchIt.Website.Services.WebAPI.Media;
public class MediaWebAPIService(IHttpClientService httpClientService, IConfigurationService configurationService) : BaseWebAPIService(configurationService), IMediaWebAPIService
{
#region PUBLIC METHODS
public async Task Get(long mediaId, Action<MediaResponse> successAction = null, Action? notFoundAction = null)
#region Main
public async Task GetMedia(long mediaId, Action<MediaResponse>? successAction = null, Action? notFoundAction = null)
{
string url = GetUrl(EndpointsConfiguration.Media.Get, mediaId);
@@ -23,7 +25,11 @@ public class MediaWebAPIService(IHttpClientService httpClientService, IConfigura
.ExecuteAction();
}
public async Task GetGenres(long mediaId, Action<IEnumerable<GenreResponse>>? successAction = null, Action? notFoundAction = null)
#endregion
#region Genres
public async Task GetMediaGenres(long mediaId, Action<IEnumerable<GenreResponse>>? successAction = null, Action? notFoundAction = null)
{
string url = GetUrl(EndpointsConfiguration.Media.GetGenres, mediaId);
@@ -35,7 +41,7 @@ public class MediaWebAPIService(IHttpClientService httpClientService, IConfigura
.ExecuteAction();
}
public async Task PostGenre(long mediaId, long genreId, Action? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null, Action? notFoundAction = null)
public async Task PostMediaGenre(long mediaId, long genreId, Action? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null, Action? notFoundAction = null)
{
string url = GetUrl(EndpointsConfiguration.Media.PostGenre, mediaId, genreId);
@@ -49,6 +55,67 @@ public class MediaWebAPIService(IHttpClientService httpClientService, IConfigura
.ExecuteAction();
}
#endregion
#region Rating
public async Task GetMediaRating(long mediaId, Action<MediaRatingResponse>? successAction = null, Action? notFoundAction = null)
{
string url = GetUrl(EndpointsConfiguration.Media.GetMediaRating, mediaId);
HttpRequest request = new HttpRequest(HttpMethodType.Get, url);
HttpResponse response = await httpClientService.SendRequestAsync(request);
response.RegisterActionFor2XXSuccess(successAction)
.RegisterActionFor404NotFound(notFoundAction)
.ExecuteAction();
}
public async Task GetMediaRatingByUser(long mediaId, long userId, Action<short>? successAction = null, Action? notFoundAction = null)
{
string url = GetUrl(EndpointsConfiguration.Media.GetMediaRatingByUser, mediaId, userId);
HttpRequest request = new HttpRequest(HttpMethodType.Get, url);
HttpResponse response = await httpClientService.SendRequestAsync(request);
response.RegisterActionFor2XXSuccess(successAction)
.RegisterActionFor404NotFound(notFoundAction)
.ExecuteAction();
}
public async Task PutMediaRating(long mediaId, MediaRatingRequest body, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null, Action? notFoundAction = null)
{
string url = GetUrl(EndpointsConfiguration.Media.PutMediaRating, mediaId);
HttpRequest request = new HttpRequest(HttpMethodType.Put, url)
{
Body = body
};
HttpResponse response = await httpClientService.SendRequestAsync(request);
response.RegisterActionFor2XXSuccess(successAction)
.RegisterActionFor400BadRequest(badRequestAction)
.RegisterActionFor401Unauthorized(unauthorizedAction)
.RegisterActionFor404NotFound(notFoundAction)
.ExecuteAction();
}
public async Task DeleteMediaRating(long mediaId, Action? successAction = null, Action? unauthorizedAction = null)
{
string url = GetUrl(EndpointsConfiguration.Media.DeleteMediaRating, mediaId);
HttpRequest request = new HttpRequest(HttpMethodType.Delete, url);
HttpResponse response = await httpClientService.SendRequestAsync(request);
response.RegisterActionFor2XXSuccess(successAction)
.RegisterActionFor401Unauthorized(unauthorizedAction)
.ExecuteAction();
}
#endregion
public async Task GetPhotoMediaRandomBackground(long mediaId, Action<MediaPhotoResponse>? successAction = null, Action? notFoundAction = null)
{
string url = GetUrl(EndpointsConfiguration.Media.GetPhotoMediaRandomBackground, mediaId);

View File

@@ -10,7 +10,7 @@
<!-- CSS -->
<link rel="stylesheet" href="app.css?version=0.15"/>
<link rel="stylesheet" href="WatchIt.Website.styles.css?version=0.15"/>
<link rel="stylesheet" href="WatchIt.Website.styles.css?version=0.24"/>
<!-- BOOTSTRAP -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>

View File

@@ -1,10 +1,28 @@
@page "/media/{id:long}"
@using System.Text
@using System.Text
@using Microsoft.IdentityModel.Tokens
@using WatchIt.Common.Model.Genres
@page "/media/{id:long}"
@layout MainLayout
@if (_loaded)
{
if (string.IsNullOrWhiteSpace(_error))
{
<PageTitle>@_media.Title@(_media.ReleaseDate is not null ? $" ({_media.ReleaseDate.Value.Year})" : string.Empty) - WatchIt</PageTitle>
}
else
{
<PageTitle>Error - WatchIt</PageTitle>
}
}
else
{
<PageTitle>Loading... - WatchIt</PageTitle>
}
<div class="container-fluid p-1 gy-2 gx-2">
@if (_loaded)
@@ -105,8 +123,61 @@
</div>
</div>
<div class="col-auto">
<div class="rounded-3 panel panel-yellow p-2 h-100">
Oceny tutaj będą
<div class="rounded-3 panel panel-yellow p-4 h-100">
<div class="container-fluid px-0">
<div class="row">
<div class="col">
<h4 class="text-dark">
<strong>Global rating:</strong> @(_globalRating.RatingCount == 0 ? "no ratings" : $"{Math.Round(_globalRating.RatingAverage, 1)}/10")
</h4>
</div>
</div>
<div class="row">
<div class="col">
<hr class="rating-separator"/>
</div>
</div>
<div class="row">
<div class="col">
<h4 class="text-dark">
<strong>Your rating:</strong>
</h4>
</div>
</div>
<div class="row">
<div class="col">
@if (_user is not null)
{
<div class="d-flex rating">
<input id="r1" type="radio" name="rate" checked="@(_userRating == 1 )" onclick="@(async () => await AddRating(1 ))"/>
<label class="text-dark" for="r1">@(_userRating >= 1 ? "\u2605" : "\u2606")</label>
<input id="r2" type="radio" name="rate" checked="@(_userRating == 2 )" onclick="@(async () => await AddRating(2 ))"/>
<label class="text-dark" for="r2">@(_userRating >= 2 ? "\u2605" : "\u2606")</label>
<input id="r3" type="radio" name="rate" checked="@(_userRating == 3 )" onclick="@(async () => await AddRating(3 ))"/>
<label class="text-dark" for="r3">@(_userRating >= 3 ? "\u2605" : "\u2606")</label>
<input id="r4" type="radio" name="rate" checked="@(_userRating == 4 )" onclick="@(async () => await AddRating(4 ))"/>
<label class="text-dark" for="r4">@(_userRating >= 4 ? "\u2605" : "\u2606")</label>
<input id="r5" type="radio" name="rate" checked="@(_userRating == 5 )" onclick="@(async () => await AddRating(5 ))"/>
<label class="text-dark" for="r5">@(_userRating >= 5 ? "\u2605" : "\u2606")</label>
<input id="r6" type="radio" name="rate" checked="@(_userRating == 6 )" onclick="@(async () => await AddRating(6 ))"/>
<label class="text-dark" for="r6">@(_userRating >= 6 ? "\u2605" : "\u2606")</label>
<input id="r7" type="radio" name="rate" checked="@(_userRating == 7 )" onclick="@(async () => await AddRating(7 ))"/>
<label class="text-dark" for="r7">@(_userRating >= 7 ? "\u2605" : "\u2606")</label>
<input id="r8" type="radio" name="rate" checked="@(_userRating == 8 )" onclick="@(async () => await AddRating(8 ))"/>
<label class="text-dark" for="r8">@(_userRating >= 8 ? "\u2605" : "\u2606")</label>
<input id="r9" type="radio" name="rate" checked="@(_userRating == 9 )" onclick="@(async () => await AddRating(9 ))"/>
<label class="text-dark" for="r9">@(_userRating >= 9 ? "\u2605" : "\u2606")</label>
<input id="r10" type="radio" name="rate" checked="@(_userRating == 10)" onclick="@(async () => await AddRating(10))"/>
<label class="text-dark" for="r10">@(_userRating == 10 ? "\u2605" : "\u2606")</label>
</div>
}
else
{
<p class="text-dark">You must be logged in to add a rating</p>
}
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
using System.Diagnostics;
using Microsoft.AspNetCore.Components;
using WatchIt.Common.Model.Genres;
using WatchIt.Common.Model.Media;
using WatchIt.Common.Model.Movies;
@@ -38,9 +39,12 @@ public partial class MediaDataPage : ComponentBase
private MediaResponse? _media;
private MovieResponse? _movie;
private IEnumerable<GenreResponse> _genres;
private MediaRatingResponse _globalRating;
private MediaPhotoResponse? _background;
private MediaPosterResponse? _poster;
private User? _user;
private short? _userRating;
#endregion
@@ -52,14 +56,15 @@ public partial class MediaDataPage : ComponentBase
{
if (firstRender)
{
await MediaWebAPIService.Get(Id, data => _media = data, () => _error = $"Media with id {Id} was not found");
await MediaWebAPIService.GetMedia(Id, data => _media = data, () => _error = $"Media with id {Id} was not found");
if (_error is null)
{
Task backgroundTask = MediaWebAPIService.GetPhotoMediaRandomBackground(Id, data => _background = data);
Task posterTask = MediaWebAPIService.GetPoster(Id, data => _poster = data);
Task<User?> userTask = AuthenticationService.GetUserAsync();
Task genresTask = MediaWebAPIService.GetGenres(Id, data => _genres = data);
Task genresTask = MediaWebAPIService.GetMediaGenres(Id, data => _genres = data);
Task globalRatingTask = MediaWebAPIService.GetMediaRating(Id, data => _globalRating = data);
Task specificMediaTask;
if (_media.Type == MediaType.Movie)
{
@@ -76,17 +81,43 @@ public partial class MediaDataPage : ComponentBase
userTask,
specificMediaTask,
genresTask,
globalRatingTask,
backgroundTask,
posterTask,
]);
_user = await userTask;
}
if (_user is not null)
{
Task userRatingTask = MediaWebAPIService.GetMediaRatingByUser(Id, _user.Id, data => _userRating = data);
await Task.WhenAll(
[
userRatingTask,
]);
}
_loaded = true;
StateHasChanged();
}
}
private async Task AddRating(short rating)
{
if (_userRating == rating)
{
await MediaWebAPIService.DeleteMediaRating(Id);
_userRating = null;
}
else
{
await MediaWebAPIService.PutMediaRating(Id, new MediaRatingRequest(rating));
_userRating = rating;
}
await MediaWebAPIService.GetMediaRating(Id, data => _globalRating = data);
}
#endregion
}

View File

@@ -15,4 +15,24 @@
.description-shadow {
text-shadow: 1px 1px 1px #000;
}
.rating-separator {
border-color: black;
border-width: 1px;
margin: 10px 0;
}
.rating > input {
display: none;
}
.rating > label {
font-size: 30px;
}
.rating > label:hover, .rating > input:hover+label {
color: gray !important;
cursor: pointer;
}

View File

@@ -42,6 +42,11 @@
"GetGenres": "/{0}/genres",
"PostGenre": "/{0}/genres/{1}",
"DeleteGenre": "/{0}/genres/{1}",
"GetMediaRating": "/{0}/rating",
"GetMediaRatingByUser": "/{0}/rating/{1}",
"PutMediaRating": "/{0}/rating",
"DeleteMediaRating": "/{0}/rating",
"GetPhotoMediaRandomBackground": "/{0}/photos/random_background",
"GetPoster": "/{0}/poster",
"PutPoster": "/{0}/poster",