From 3d39bfedb69765b7ad04d6aa6c5a61cc85560246 Mon Sep 17 00:00:00 2001 From: jvyden Date: Sun, 28 Nov 2021 23:35:40 -0500 Subject: [PATCH] Add page for browsing levels --- .../Controllers/ListController.cs | 42 +++------ .../Controllers/Website/SlotPageController.cs | 77 +++++++++++++++++ ProjectLighthouse/Database.cs | 50 +++++++++++ .../Pages/Layouts/BaseLayout.cshtml.cs | 1 + ProjectLighthouse/Pages/PhotosPage.cshtml.cs | 6 +- ProjectLighthouse/Pages/SlotsPage.cshtml | 86 +++++++++++++++++++ ProjectLighthouse/Pages/SlotsPage.cshtml.cs | 41 +++++++++ ProjectLighthouse/Pages/UserPage.cshtml | 2 +- ProjectLighthouse/StaticFiles/css/styles.css | 4 +- .../Types/Settings/ServerStatics.cs | 2 + 10 files changed, 275 insertions(+), 36 deletions(-) create mode 100644 ProjectLighthouse/Controllers/Website/SlotPageController.cs create mode 100644 ProjectLighthouse/Pages/SlotsPage.cshtml create mode 100644 ProjectLighthouse/Pages/SlotsPage.cshtml.cs diff --git a/ProjectLighthouse/Controllers/ListController.cs b/ProjectLighthouse/Controllers/ListController.cs index 3c5520d9..8accb958 100644 --- a/ProjectLighthouse/Controllers/ListController.cs +++ b/ProjectLighthouse/Controllers/ListController.cs @@ -59,19 +59,10 @@ namespace LBPUnion.ProjectLighthouse.Controllers User? user = await this.database.UserFromGameRequest(this.Request); if (user == null) return this.StatusCode(403, ""); - QueuedLevel? queuedLevel = await this.database.QueuedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == id); - if (queuedLevel != null) return this.Ok(); + Slot? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == id); + if (slot == null) return this.NotFound(); - this.database.QueuedLevels.Add - ( - new QueuedLevel - { - SlotId = id, - UserId = user.UserId, - } - ); - - await this.database.SaveChangesAsync(); + await this.database.QueueLevel(user, slot); return this.Ok(); } @@ -82,10 +73,10 @@ namespace LBPUnion.ProjectLighthouse.Controllers User? user = await this.database.UserFromGameRequest(this.Request); if (user == null) return this.StatusCode(403, ""); - QueuedLevel? queuedLevel = await this.database.QueuedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == id); - if (queuedLevel != null) this.database.QueuedLevels.Remove(queuedLevel); + Slot? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == id); + if (slot == null) return this.NotFound(); - await this.database.SaveChangesAsync(); + await this.database.UnqueueLevel(user, slot); return this.Ok(); } @@ -140,19 +131,10 @@ namespace LBPUnion.ProjectLighthouse.Controllers User? user = await this.database.UserFromGameRequest(this.Request); if (user == null) return this.StatusCode(403, ""); - HeartedLevel? heartedLevel = await this.database.HeartedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == id); - if (heartedLevel != null) return this.Ok(); + Slot? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == id); + if (slot == null) return this.NotFound(); - this.database.HeartedLevels.Add - ( - new HeartedLevel - { - SlotId = id, - UserId = user.UserId, - } - ); - - await this.database.SaveChangesAsync(); + await this.database.HeartLevel(user, slot); return this.Ok(); } @@ -163,10 +145,10 @@ namespace LBPUnion.ProjectLighthouse.Controllers User? user = await this.database.UserFromGameRequest(this.Request); if (user == null) return this.StatusCode(403, ""); - HeartedLevel? heartedLevel = await this.database.HeartedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == id); - if (heartedLevel != null) this.database.HeartedLevels.Remove(heartedLevel); + Slot? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == id); + if (slot == null) return this.NotFound(); - await this.database.SaveChangesAsync(); + await this.database.UnheartLevel(user, slot); return this.Ok(); } diff --git a/ProjectLighthouse/Controllers/Website/SlotPageController.cs b/ProjectLighthouse/Controllers/Website/SlotPageController.cs new file mode 100644 index 00000000..705e3291 --- /dev/null +++ b/ProjectLighthouse/Controllers/Website/SlotPageController.cs @@ -0,0 +1,77 @@ +#nullable enable +using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Types; +using LBPUnion.ProjectLighthouse.Types.Levels; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace LBPUnion.ProjectLighthouse.Controllers.Website +{ + [ApiController] + [Route("slot/{id:int}")] + public class SlotPageController : ControllerBase + { + private readonly Database database; + + public SlotPageController(Database database) + { + this.database = database; + } + + [HttpGet("heart")] + public async Task HeartLevel([FromRoute] int id) + { + User? user = this.database.UserFromWebRequest(this.Request); + if (user == null) return this.Redirect("~/login"); + + Slot? heartedSlot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == id); + if (heartedSlot == null) return this.NotFound(); + + await this.database.HeartLevel(user, heartedSlot); + + return this.Redirect("~/slot/" + id); + } + + [HttpGet("unheart")] + public async Task UnheartLevel([FromRoute] int id) + { + User? user = this.database.UserFromWebRequest(this.Request); + if (user == null) return this.Redirect("~/login"); + + Slot? heartedSlot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == id); + if (heartedSlot == null) return this.NotFound(); + + await this.database.UnheartLevel(user, heartedSlot); + + return this.Redirect("~/slot/" + id); + } + + [HttpGet("queue")] + public async Task QueueLevel([FromRoute] int id) + { + User? user = this.database.UserFromWebRequest(this.Request); + if (user == null) return this.Redirect("~/login"); + + Slot? queuedSlot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == id); + if (queuedSlot == null) return this.NotFound(); + + await this.database.QueueLevel(user, queuedSlot); + + return this.Redirect("~/slot/" + id); + } + + [HttpGet("unqueue")] + public async Task UnqueueLevel([FromRoute] int id) + { + User? user = this.database.UserFromWebRequest(this.Request); + if (user == null) return this.Redirect("~/login"); + + Slot? queuedSlot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == id); + if (queuedSlot == null) return this.NotFound(); + + await this.database.UnqueueLevel(user, queuedSlot); + + return this.Redirect("~/slot/" + id); + } + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs index a8b6e29a..b8a9a599 100644 --- a/ProjectLighthouse/Database.cs +++ b/ProjectLighthouse/Database.cs @@ -116,6 +116,56 @@ namespace LBPUnion.ProjectLighthouse await this.SaveChangesAsync(); } + public async Task HeartLevel(User user, Slot heartedSlot) + { + HeartedLevel? heartedLevel = await this.HeartedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == heartedSlot.SlotId); + if (heartedLevel != null) return; + + this.HeartedLevels.Add + ( + new HeartedLevel + { + SlotId = heartedSlot.SlotId, + UserId = user.UserId, + } + ); + + await this.SaveChangesAsync(); + } + + public async Task UnheartLevel(User user, Slot heartedSlot) + { + HeartedLevel? heartedLevel = await this.HeartedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == heartedSlot.SlotId); + if (heartedLevel != null) this.HeartedLevels.Remove(heartedLevel); + + await this.SaveChangesAsync(); + } + + public async Task QueueLevel(User user, Slot queuedSlot) + { + QueuedLevel? queuedLevel = await this.QueuedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == queuedSlot.SlotId); + if (queuedLevel != null) return; + + this.QueuedLevels.Add + ( + new QueuedLevel + { + SlotId = queuedSlot.SlotId, + UserId = user.UserId, + } + ); + + await this.SaveChangesAsync(); + } + + public async Task UnqueueLevel(User user, Slot queuedSlot) + { + QueuedLevel? queuedLevel = await this.QueuedLevels.FirstOrDefaultAsync(q => q.UserId == user.UserId && q.SlotId == queuedSlot.SlotId); + if (queuedLevel != null) this.QueuedLevels.Remove(queuedLevel); + + await this.SaveChangesAsync(); + } + #endregion #region Game Token Shenanigans diff --git a/ProjectLighthouse/Pages/Layouts/BaseLayout.cshtml.cs b/ProjectLighthouse/Pages/Layouts/BaseLayout.cshtml.cs index 9ebe8b9f..e77b3f11 100644 --- a/ProjectLighthouse/Pages/Layouts/BaseLayout.cshtml.cs +++ b/ProjectLighthouse/Pages/Layouts/BaseLayout.cshtml.cs @@ -29,6 +29,7 @@ namespace LBPUnion.ProjectLighthouse.Pages.Layouts { new PageNavigationItem("Home", "/", "home"), new PageNavigationItem("Photos", "/photos/0", "camera"), + new PageNavigationItem("Levels", "/slots/0", "certificate"), }; public readonly List NavigationItemsRight = new() diff --git a/ProjectLighthouse/Pages/PhotosPage.cshtml.cs b/ProjectLighthouse/Pages/PhotosPage.cshtml.cs index f7be042a..e9e94007 100644 --- a/ProjectLighthouse/Pages/PhotosPage.cshtml.cs +++ b/ProjectLighthouse/Pages/PhotosPage.cshtml.cs @@ -5,6 +5,7 @@ using JetBrains.Annotations; using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Pages.Layouts; using LBPUnion.ProjectLighthouse.Types; +using LBPUnion.ProjectLighthouse.Types.Settings; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -23,7 +24,6 @@ namespace LBPUnion.ProjectLighthouse.Pages public async Task OnGet([FromRoute] int pageNumber) { - const int pageSize = 20; this.PhotoCount = await StatisticsHelper.PhotoCount(); this.PageNumber = pageNumber; @@ -31,8 +31,8 @@ namespace LBPUnion.ProjectLighthouse.Pages this.Photos = await this.Database.Photos.Include (p => p.Creator) .OrderByDescending(p => p.Timestamp) - .Skip(pageNumber * pageSize) - .Take(pageSize) + .Skip(pageNumber * ServerStatics.PageSize) + .Take(ServerStatics.PageSize) .ToListAsync(); return this.Page(); diff --git a/ProjectLighthouse/Pages/SlotsPage.cshtml b/ProjectLighthouse/Pages/SlotsPage.cshtml new file mode 100644 index 00000000..28bf3741 --- /dev/null +++ b/ProjectLighthouse/Pages/SlotsPage.cshtml @@ -0,0 +1,86 @@ +@page "/slots/{pageNumber:int}" +@using LBPUnion.ProjectLighthouse.Types +@using LBPUnion.ProjectLighthouse.Types.Levels +@using Microsoft.EntityFrameworkCore +@model LBPUnion.ProjectLighthouse.Pages.SlotsPage + +@{ + Layout = "Layouts/BaseLayout"; +} + +

Levels

+

There are @Model.SlotCount total levels!

+ +@foreach (Slot slot in Model.Slots) +{ + string slotName = string.IsNullOrEmpty(slot.Name) ? "Unnamed Level" : slot.Name; + + bool isQueued = false; + bool isHearted = false; + + if (Model.User != null) + { + isQueued = await Model.Database.QueuedLevels.FirstOrDefaultAsync(h => h.SlotId == slot.SlotId && h.UserId == Model.User.UserId) != null; + + isHearted = await Model.Database.HeartedLevels.FirstOrDefaultAsync(h => h.SlotId == slot.SlotId && h.UserId == Model.User.UserId) != null; + } + +
+
+
+

@slotName

+
+ @slot.Hearts + @slot.Plays + @slot.Thumbsup + @slot.Thumbsdown + + @if (slot.GameVersion == GameVersion.LittleBigPlanet1) + { + + @slot.RatingLBP1 + } +
+

+ Created by @slot.Creator?.Username +

+
+
+ @if (Model.User != null) + { + if (isHearted) + { + + + + } + else + { + + + + } + + if (isQueued) + { + + + + } + else + { + + + + } + } +
+
+
+} + +@if (Model.PageNumber != 0) +{ + Previous Page +} +Next Page \ No newline at end of file diff --git a/ProjectLighthouse/Pages/SlotsPage.cshtml.cs b/ProjectLighthouse/Pages/SlotsPage.cshtml.cs new file mode 100644 index 00000000..dc7c6248 --- /dev/null +++ b/ProjectLighthouse/Pages/SlotsPage.cshtml.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using JetBrains.Annotations; +using LBPUnion.ProjectLighthouse.Helpers; +using LBPUnion.ProjectLighthouse.Pages.Layouts; +using LBPUnion.ProjectLighthouse.Types.Levels; +using LBPUnion.ProjectLighthouse.Types.Settings; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace LBPUnion.ProjectLighthouse.Pages +{ + public class SlotsPage : BaseLayout + { + public SlotsPage([NotNull] Database database) : base(database) + {} + + public int SlotCount; + + public List Slots; + + public int PageNumber; + + public async Task OnGet([FromRoute] int pageNumber) + { + this.SlotCount = await StatisticsHelper.SlotCount(); + + this.PageNumber = pageNumber; + + this.Slots = await this.Database.Slots.Include + (p => p.Creator) + .OrderByDescending(p => p.FirstUploaded) + .Skip(pageNumber * ServerStatics.PageSize) + .Take(ServerStatics.PageSize) + .ToListAsync(); + + return this.Page(); + } + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Pages/UserPage.cshtml b/ProjectLighthouse/Pages/UserPage.cshtml index 1fc50e7f..d9e127e3 100644 --- a/ProjectLighthouse/Pages/UserPage.cshtml +++ b/ProjectLighthouse/Pages/UserPage.cshtml @@ -14,7 +14,7 @@

@Model.ProfileUser.Status

-
+
@Model.ProfileUser.Hearts @Model.ProfileUser.Comments @Model.ProfileUser.UsedSlots / @ServerSettings.Instance.EntitledSlots diff --git a/ProjectLighthouse/StaticFiles/css/styles.css b/ProjectLighthouse/StaticFiles/css/styles.css index 6ba1642b..53cbfaa5 100644 --- a/ProjectLighthouse/StaticFiles/css/styles.css +++ b/ProjectLighthouse/StaticFiles/css/styles.css @@ -8,11 +8,11 @@ div.main { flex: 1; } -div.userStats > i { +div.statsUnderTitle > i { margin-right: 2px; } -div.userStats > span { +div.statsUnderTitle > span { margin-right: 5px; } diff --git a/ProjectLighthouse/Types/Settings/ServerStatics.cs b/ProjectLighthouse/Types/Settings/ServerStatics.cs index 900f9d66..1bb8227c 100644 --- a/ProjectLighthouse/Types/Settings/ServerStatics.cs +++ b/ProjectLighthouse/Types/Settings/ServerStatics.cs @@ -25,5 +25,7 @@ namespace LBPUnion.ProjectLighthouse.Types.Settings } public static bool IsUnitTesting => AppDomain.CurrentDomain.GetAssemblies().Any(assembly => assembly.FullName.StartsWith("xunit")); + + public const int PageSize = 20; } } \ No newline at end of file