Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor profile and slot pages to use iFrames for pagination #839

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,7 @@ public async Task<IActionResult> GetComments(string? username, string? slotType,

if (targetId == 0) return this.NotFound();

List<int> blockedUsers = await (
from blockedProfile in this.database.BlockedProfiles
where blockedProfile.UserId == token.UserId
select blockedProfile.BlockedUserId).ToListAsync();
List<int> blockedUsers = await this.database.GetBlockedUsers(token.UserId);

List<GameComment> comments = (await this.database.Comments.Where(p => p.TargetId == targetId && p.Type == type)
.OrderByDescending(p => p.Timestamp)
Expand Down
82 changes: 82 additions & 0 deletions ProjectLighthouse.Servers.Website/Controllers/CommentController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using LBPUnion.ProjectLighthouse.Types.Logging;
using Microsoft.AspNetCore.Mvc;

namespace LBPUnion.ProjectLighthouse.Servers.Website.Controllers;

[Route("{type}/{id:int}")]
public class CommentController : ControllerBase
{
private readonly DatabaseContext database;

public CommentController(DatabaseContext database)
{
this.database = database;
}

private static CommentType? ParseType(string type) =>
type switch
{
"slot" => CommentType.Level,
"user" => CommentType.Profile,
_ => null,
};

[HttpGet("rateComment")]
public async Task<IActionResult> RateComment(string type, int id, [FromQuery] int? commentId, [FromQuery] int? rating, [FromQuery] string? redirect)
{
WebTokenEntity? token = this.database.WebTokenFromRequest(this.Request);
if (token == null) return this.Redirect("~/login");

CommentType? commentType = ParseType(type);
if (commentType == null) return this.BadRequest();

await this.database.RateComment(token.UserId, commentId.GetValueOrDefault(), rating.GetValueOrDefault());

return this.Redirect(redirect ?? $"~/user/{id}#{commentId}");
}

[HttpPost("postComment")]
public async Task<IActionResult> PostComment(string type, int id, [FromForm] string? msg, [FromQuery] string? redirect)
{
WebTokenEntity? token = this.database.WebTokenFromRequest(this.Request);
if (token == null) return this.Redirect("~/login");

CommentType? commentType = ParseType(type);
if (commentType == null) return this.BadRequest();

if (msg == null)
{
Logger.Error($"Refusing to post comment from {token.UserId} on {commentType} {id}, {nameof(msg)} is null",
LogArea.Comments);
return this.Redirect("~/user/" + id);
}

string username = await this.database.UsernameFromWebToken(token);
string filteredText = CensorHelper.FilterMessage(msg);

if (ServerConfiguration.Instance.LogChatFiltering && filteredText != msg)
Logger.Info(
$"Censored profane word(s) from {commentType} comment sent by {username}: \"{msg}\" => \"{filteredText}\"",
LogArea.Filter);

bool success = await this.database.PostComment(token.UserId, id, (CommentType)commentType, filteredText);
if (success)
{
Logger.Success($"Posted comment from {username}: \"{filteredText}\" on {commentType} {id}",
LogArea.Comments);
}
else
{
Logger.Error($"Failed to post comment from {username}: \"{filteredText}\" on {commentType} {id}",
LogArea.Comments);
}

return this.Redirect(redirect ?? $"~/{type}/" + id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,49 +46,6 @@ public async Task<IActionResult> UnpublishSlot([FromRoute] int id)
return this.Redirect("~/slots/0");
}

[HttpGet("rateComment")]
public async Task<IActionResult> RateComment([FromRoute] int id, [FromQuery] int commentId, [FromQuery] int rating)
{
WebTokenEntity? token = this.database.WebTokenFromRequest(this.Request);
if (token == null) return this.Redirect("~/login");

await this.database.RateComment(token.UserId, commentId, rating);

return this.Redirect($"~/slot/{id}#{commentId}");
}

[HttpPost("postComment")]
public async Task<IActionResult> PostComment([FromRoute] int id, [FromForm] string? msg)
{
WebTokenEntity? token = this.database.WebTokenFromRequest(this.Request);
if (token == null) return this.Redirect("~/login");

if (msg == null)
{
Logger.Error($"Refusing to post comment from {token.UserId} on level {id}, {nameof(msg)} is null", LogArea.Comments);
return this.Redirect("~/slot/" + id);
}

string username = await this.database.UsernameFromWebToken(token);
string filteredText = CensorHelper.FilterMessage(msg);

if (ServerConfiguration.Instance.LogChatFiltering && filteredText != msg)
Logger.Info($"Censored profane word(s) from slot comment sent by {username}: \"{msg}\" => \"{filteredText}\"",
LogArea.Filter);

bool success = await this.database.PostComment(token.UserId, id, CommentType.Level, filteredText);
if (success)
{
Logger.Success($"Posted comment from {username}: \"{filteredText}\" on level {id}", LogArea.Comments);
}
else
{
Logger.Error($"Failed to post comment from {username}: \"{filteredText}\" on level {id}", LogArea.Comments);
}

return this.Redirect("~/slot/" + id);
}

[HttpGet("heart")]
public async Task<IActionResult> HeartLevel([FromRoute] int id, [FromQuery] string? callbackUrl)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
#nullable enable
using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using LBPUnion.ProjectLighthouse.Types.Logging;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

Expand All @@ -22,49 +18,6 @@ public UserPageController(DatabaseContext database)
this.database = database;
}

[HttpGet("rateComment")]
public async Task<IActionResult> RateComment([FromRoute] int id, [FromQuery] int? commentId, [FromQuery] int? rating)
{
WebTokenEntity? token = this.database.WebTokenFromRequest(this.Request);
if (token == null) return this.Redirect("~/login");

await this.database.RateComment(token.UserId, commentId.GetValueOrDefault(), rating.GetValueOrDefault());

return this.Redirect($"~/user/{id}#{commentId}");
}

[HttpPost("postComment")]
public async Task<IActionResult> PostComment([FromRoute] int id, [FromForm] string? msg)
{
WebTokenEntity? token = this.database.WebTokenFromRequest(this.Request);
if (token == null) return this.Redirect("~/login");

if (msg == null)
{
Logger.Error($"Refusing to post comment from {token.UserId} on user {id}, {nameof(msg)} is null", LogArea.Comments);
return this.Redirect("~/user/" + id);
}

string username = await this.database.UsernameFromWebToken(token);
string filteredText = CensorHelper.FilterMessage(msg);

if (ServerConfiguration.Instance.LogChatFiltering && filteredText != msg)
Logger.Info($"Censored profane word(s) from user comment sent by {username}: \"{msg}\" => \"{filteredText}\"",
LogArea.Filter);

bool success = await this.database.PostComment(token.UserId, id, CommentType.Profile, filteredText);
if (success)
{
Logger.Success($"Posted comment from {username}: \"{filteredText}\" on user {id}", LogArea.Comments);
}
else
{
Logger.Error($"Failed to post comment from {username}: \"{filteredText}\" on user {id}", LogArea.Comments);
}

return this.Redirect("~/user/" + id);
}

[HttpGet("heart")]
public async Task<IActionResult> HeartUser([FromRoute] int id)
{
Expand Down
45 changes: 45 additions & 0 deletions ProjectLighthouse.Servers.Website/Pages/Errors/ErrorPage.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
@page "/error"
@using System.Globalization
@using LBPUnion.ProjectLighthouse.Configuration
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.Errors.ErrorPage

@{
Layout = null;
}

<!DOCTYPE html>

<html lang="en">
<head>
<title>An error has occurred</title>
<link rel="stylesheet" type="text/css" href="~/css/styles.css">
<link rel="stylesheet" type="text/css" href="~/css/semantic.min.css">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="pageContainer">
<div class="ui grid middle aligned">
<div class="eight center aligned column wide">
<img src="~/@(ServerConfiguration.Instance.WebsiteConfiguration.PrideEventEnabled && DateTime.Now.Month == 6 ? "logo-pride.png" : "logo-color.png")"
alt="Instance logo"
class="image"
style="width: 15vw;"/>
<h1>An error has occurred</h1>
<p>The server encountered an error while processing your request</p>
<p>
Try to refresh this page, if the problem persists, <br/>please <a href="https://github.com/LBPUnion/ProjectLighthouse/issues/new">report</a>
your problem and mention this error message
</p>
<h6>
Request ID: @Model.RequestId
<br/>
Timestamp: @DateTime.UtcNow.ToString(CultureInfo.InvariantCulture) UTC
</h6>
</div>
</div>
</div>
</body>
</html>
23 changes: 23 additions & 0 deletions ProjectLighthouse.Servers.Website/Pages/Errors/ErrorPage.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages.Errors;

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorPage : PageModel
{
public string? RequestId { get; set; }

public IActionResult OnGet()
{
this.RequestId = this.HttpContext.TraceIdentifier;

IExceptionHandlerPathFeature? exceptionHandlerPathFeature = this.HttpContext.Features.Get<IExceptionHandlerPathFeature>();

if (exceptionHandlerPathFeature?.Error == null) return this.NotFound();

return this.Page();
}
}
50 changes: 50 additions & 0 deletions ProjectLighthouse.Servers.Website/Pages/Frames/CommentFrame.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@page "/comments/{type}/{id:int}"
@using LBPUnion.ProjectLighthouse.Servers.Website.Extensions
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.Frames.CommentFrame

@{
Model.Title = "Comments";
Layout = "PaginatedFrame";

string language = Model.GetLanguage();
string timeZone = Model.GetTimeZone();
}

<div class="ui yellow segment" id="comments">
@if (!Model.CanViewComments)
{
if (Model.Type == "user")
{
<span>This user's privacy settings prevent you from viewing this page.</span>
}
else
{
<span>This level creator's privacy settings prevent you from viewing this page.</span>
}
}
else if (Model.Comments.Count == 0 && Model.CommentsEnabled)
{
<p>There are no comments.</p>
}
else if (!Model.CommentsEnabled)
{
<i>Comments are disabled.</i>
}
else
{
int count = Model.TotalItems;
<p>There @(count == 1 ? "is" : "are") @count comment@(count == 1 ? "" : "s").</p>
@await Html.PartialAsync("Partials/CommentsPartial", (Model.User, Model.Comments, Model.CommentsEnabled), new ViewDataDictionary(ViewData.WithLang(language).WithTime(timeZone))
{
{
"PageOwner", Model.PageOwner
},
{
"BaseUrl", $"/{Model.Type}/{Model.Id}"
},
{
"RedirectUrl", $"/comments/{Model.Type}/{Model.Id}?page=" + Model.CurrentPage
},
})
}
</div>
Loading