mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-09-02 07:37:13 +00:00
Merge main into mod-panel
This commit is contained in:
commit
b6da930e20
300 changed files with 8417 additions and 700 deletions
|
@ -43,13 +43,14 @@ public class LandingPage : BaseLayout
|
|||
const int maxShownLevels = 5;
|
||||
|
||||
this.LatestTeamPicks = await this.Database.Slots.Where
|
||||
(s => s.TeamPick)
|
||||
(s => s.Type == SlotType.User)
|
||||
.Where(s => s.TeamPick)
|
||||
.OrderByDescending(s => s.FirstUploaded)
|
||||
.Take(maxShownLevels)
|
||||
.Include(s => s.Creator)
|
||||
.ToListAsync();
|
||||
|
||||
this.NewestLevels = await this.Database.Slots.OrderByDescending(s => s.FirstUploaded).Take(maxShownLevels).Include(s => s.Creator).ToListAsync();
|
||||
this.NewestLevels = await this.Database.Slots.Where(s => s.Type == SlotType.User).OrderByDescending(s => s.FirstUploaded).Take(maxShownLevels).Include(s => s.Creator).ToListAsync();
|
||||
|
||||
return this.Page();
|
||||
}
|
||||
|
|
|
@ -127,28 +127,36 @@
|
|||
<div class="ui container">
|
||||
<div style="display: flex; align-items: center; font-size: 1.2rem;">
|
||||
<i class="warning icon"></i>
|
||||
<span style="font-size: 1.2rem;">JavaScript not enabled</span>
|
||||
<span style="font-size: 1.2rem;">@Model.Translate(BaseLayoutStrings.JavaScriptWarnTitle)</span>
|
||||
</div>
|
||||
<p>
|
||||
While we intend to have as little JavaScript as possible, we can not
|
||||
guarantee everything will work without it. We recommend that you whitelist JavaScript for Project Lighthouse.
|
||||
It's not <i>too</i> bloated, we promise.
|
||||
</p>
|
||||
<p>@Model.Translate(BaseLayoutStrings.JavaScriptWarn)</p>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
@* ReSharper disable HeuristicUnreachableCode *@
|
||||
@* ReSharper disable CSharpWarnings::CS0162 *@
|
||||
@if (!ServerStatics.IsDebug && VersionHelper.IsDirty)
|
||||
{
|
||||
<div class="ui bottom attached red message large">
|
||||
<div class="ui container">
|
||||
<i class="warning icon"></i>
|
||||
<span style="font-size: 1.2rem;">Potential License Violation</span>
|
||||
<p>This instance is a public-facing instance that has been modified without the changes published. You may be in violation of the <a href="https://github.com/LBPUnion/project-lighthouse/blob/main/LICENSE">GNU Affero General Public License v3.0</a>.</p>
|
||||
<p>If you believe this is an error, please create an issue with the output of <code>git status</code> ran from the root of the server source code in the description on our <a href="https://github.com/LBPUnion/project-lighthouse/issues">issue tracker</a>.</p>
|
||||
<p>If not, please publish the source code somewhere accessible to your users.</p>
|
||||
<span style="font-size: 1.2rem;">@Model.Translate(BaseLayoutStrings.LicenseWarnTitle)</span>
|
||||
<p>
|
||||
@Html.Raw(Model.Translate(BaseLayoutStrings.LicenseWarn1,
|
||||
"<a href=\"https://github.com/LBPUnion/project-lighthouse/blob/main/LICENSE\">GNU Affero General Public License v3.0</a>"))
|
||||
</p>
|
||||
<p>
|
||||
@Html.Raw(Model.Translate(BaseLayoutStrings.LicenseWarn2,
|
||||
"<code>git status</code>", "<a href=\"https://github.com/LBPUnion/project-lighthouse/issues\">", "</a>"))
|
||||
</p>
|
||||
<p>
|
||||
@Html.Raw(Model.Translate(BaseLayoutStrings.LicenseWarn3))
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@* ReSharper restore CSharpWarnings::CS0162 *@
|
||||
@* ReSharper restore HeuristicUnreachableCode *@
|
||||
</header>
|
||||
<div class="main">
|
||||
<div class="ui container">
|
||||
|
@ -165,10 +173,10 @@
|
|||
<div class="ui black attached inverted segment">
|
||||
<div class="ui container">
|
||||
|
||||
<p>Page generated by @VersionHelper.FullVersion.</p>
|
||||
<p>@Model.Translate(BaseLayoutStrings.GeneratedBy, VersionHelper.FullVersion)</p>
|
||||
@if (VersionHelper.IsDirty)
|
||||
{
|
||||
<p>This page was generated using a modified version of Project Lighthouse. Please make sure you are properly disclosing the source code to any users who may be using this instance.</p>
|
||||
<p>@Model.Translate(BaseLayoutStrings.GeneratedModified)</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -52,6 +52,8 @@ public class BaseLayout : PageModel
|
|||
{
|
||||
if (ServerStatics.IsUnitTesting) return LocalizationManager.DefaultLang;
|
||||
if (this.language != null) return this.language;
|
||||
|
||||
if (this.User?.IsAPirate ?? false) return "en-PT";
|
||||
|
||||
IRequestCultureFeature? requestCulture = Request.HttpContext.Features.Get<IRequestCultureFeature>();
|
||||
if (requestCulture == null) return this.language = LocalizationManager.DefaultLang;
|
||||
|
|
|
@ -3,6 +3,7 @@ using JetBrains.Annotations;
|
|||
using LBPUnion.ProjectLighthouse.Configuration;
|
||||
using LBPUnion.ProjectLighthouse.Extensions;
|
||||
using LBPUnion.ProjectLighthouse.Helpers;
|
||||
using LBPUnion.ProjectLighthouse.Localization.StringLists;
|
||||
using LBPUnion.ProjectLighthouse.Logging;
|
||||
using LBPUnion.ProjectLighthouse.PlayerData;
|
||||
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
|
||||
|
@ -26,19 +27,19 @@ public class LoginForm : BaseLayout
|
|||
{
|
||||
if (string.IsNullOrWhiteSpace(username))
|
||||
{
|
||||
this.Error = "The username field is required.";
|
||||
this.Error = this.Translate(ErrorStrings.UsernameInvalid);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(password))
|
||||
{
|
||||
this.Error = "The password field is required.";
|
||||
this.Error = this.Translate(ErrorStrings.PasswordInvalid);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
if (!await this.Request.CheckCaptchaValidity())
|
||||
{
|
||||
this.Error = "You must complete the captcha correctly.";
|
||||
this.Error = this.Translate(ErrorStrings.CaptchaFailed);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
|
@ -60,7 +61,7 @@ public class LoginForm : BaseLayout
|
|||
if (user.IsBanned)
|
||||
{
|
||||
Logger.Warn($"User {user.Username} (id: {user.UserId}) failed to login on web due to being banned", LogArea.Login);
|
||||
this.Error = "You have been banned. Please contact an administrator for more information.\nReason: " + user.BannedReason;
|
||||
this.Error = this.Translate(ErrorStrings.UserIsBanned, user.BannedReason);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
|
@ -73,6 +74,7 @@ public class LoginForm : BaseLayout
|
|||
UserId = user.UserId,
|
||||
User = user,
|
||||
EmailToken = CryptoHelper.GenerateAuthToken(),
|
||||
ExpiresAt = DateTime.Now + TimeSpan.FromHours(6),
|
||||
};
|
||||
|
||||
this.Database.EmailSetTokens.Add(emailSetToken);
|
||||
|
@ -85,6 +87,7 @@ public class LoginForm : BaseLayout
|
|||
{
|
||||
UserId = user.UserId,
|
||||
UserToken = CryptoHelper.GenerateAuthToken(),
|
||||
ExpiresAt = DateTime.Now + TimeSpan.FromDays(7),
|
||||
};
|
||||
|
||||
this.Database.WebTokens.Add(webToken);
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
string style = "";
|
||||
if (Model.User?.UserId == comment.PosterUserId)
|
||||
{
|
||||
style = "visibility: hidden";
|
||||
style = "pointer-events: none";
|
||||
}
|
||||
}
|
||||
<div class="voting" style="@(style)">
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
@using System.Globalization
|
||||
@using LBPUnion.ProjectLighthouse.Levels
|
||||
@using LBPUnion.ProjectLighthouse.PlayerData
|
||||
@using LBPUnion.ProjectLighthouse.Types
|
||||
@model LBPUnion.ProjectLighthouse.PlayerData.Photo
|
||||
|
||||
|
||||
|
@ -18,6 +19,27 @@
|
|||
<b>
|
||||
<a href="/user/@Model.Creator?.UserId">@Model.Creator?.Username</a>
|
||||
</b>
|
||||
@if (Model.Slot != null)
|
||||
{
|
||||
switch (Model.Slot.Type)
|
||||
{
|
||||
case SlotType.User:
|
||||
<span>
|
||||
in level <b><a href="/slot/@Model.SlotId">@Model.Slot.Name</a></b>
|
||||
</span>
|
||||
break;
|
||||
case SlotType.Developer:
|
||||
<span>in a story mode level</span>
|
||||
break;
|
||||
case SlotType.Pod:
|
||||
<span>in the pod</span>
|
||||
break;
|
||||
case SlotType.Local:
|
||||
<span>in a level on the moon</span>
|
||||
break;
|
||||
}
|
||||
}
|
||||
at @DateTime.UnixEpoch.AddSeconds(Model.Timestamp).ToString(CultureInfo.CurrentCulture)
|
||||
</i>
|
||||
</p>
|
||||
|
||||
|
@ -124,4 +146,4 @@
|
|||
context.setTransform(1, 0, 0, 1, 0, 0);
|
||||
})
|
||||
}, false);
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@page "/passwordReset"
|
||||
@using LBPUnion.ProjectLighthouse.Localization.StringLists
|
||||
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.PasswordResetPage
|
||||
|
||||
@{
|
||||
|
@ -26,7 +27,7 @@
|
|||
{
|
||||
<div class="ui negative message">
|
||||
<div class="header">
|
||||
Uh oh!
|
||||
@Model.Translate(GeneralStrings.Error)
|
||||
</div>
|
||||
<p>@Model.Error</p>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@page "/passwordResetRequest"
|
||||
@using LBPUnion.ProjectLighthouse.Localization.StringLists
|
||||
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.PasswordResetRequestForm
|
||||
|
||||
@{
|
||||
|
@ -10,7 +11,7 @@
|
|||
{
|
||||
<div class="ui negative message">
|
||||
<div class="header">
|
||||
Uh oh!
|
||||
@Model.Translate(GeneralStrings.Error)
|
||||
</div>
|
||||
<p style="white-space: pre-line">@Model.Error</p>
|
||||
</div>
|
||||
|
@ -20,7 +21,7 @@
|
|||
{
|
||||
<div class="ui positive message">
|
||||
<div class="header">
|
||||
Success!
|
||||
@Model.Translate(GeneralStrings.Success)
|
||||
</div>
|
||||
<p style="white-space: pre-line">@Model.Status</p>
|
||||
</div>
|
||||
|
|
|
@ -40,6 +40,7 @@ public class PhotosPage : BaseLayout
|
|||
|
||||
this.Photos = await this.Database.Photos.Include
|
||||
(p => p.Creator)
|
||||
.Include(p => p.Slot)
|
||||
.Where(p => p.Creator!.Username.Contains(this.SearchValue) || p.PhotoSubjectCollection.Contains(this.SearchValue))
|
||||
.OrderByDescending(p => p.Timestamp)
|
||||
.Skip(pageNumber * ServerStatics.PageSize)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
@page "/pirate"
|
||||
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.PirateSignupPage
|
||||
|
||||
@{
|
||||
Layout = "Layouts/BaseLayout";
|
||||
Model.Title = "ARRRRRRRRRR!";
|
||||
}
|
||||
<!--suppress GrazieInspection -->
|
||||
|
||||
@if (!Model.User!.IsAPirate)
|
||||
{
|
||||
<p>So, ye wanna be a pirate? Well, ye came to the right place!</p>
|
||||
<p>Just click this 'ere button, and welcome aboard!</p>
|
||||
<p>If you ever wanna walk the plank, come back 'ere.</p>
|
||||
|
||||
<form method="post">
|
||||
@Html.AntiForgeryToken()
|
||||
<input type="submit" class="ui blue button" value="Aye aye, captain!"/>
|
||||
</form>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>Back so soon, aye?</p>
|
||||
<p>If you're gonna walk the plank, then do it!</p>
|
||||
|
||||
<form method="post">
|
||||
@Html.AntiForgeryToken()
|
||||
<input type="submit" class="ui red button" value="Walk the plank"/>
|
||||
</form>
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
|
||||
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages;
|
||||
|
||||
public class PirateSignupPage : BaseLayout
|
||||
{
|
||||
public PirateSignupPage(Database database) : base(database)
|
||||
{}
|
||||
|
||||
public async Task<IActionResult> OnGet()
|
||||
{
|
||||
User? user = this.Database.UserFromWebRequest(this.Request);
|
||||
if (user == null) return this.RedirectToPage("/login");
|
||||
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPost()
|
||||
{
|
||||
User? user = this.Database.UserFromWebRequest(this.Request);
|
||||
if (user == null) return this.Redirect("/login");
|
||||
|
||||
user.IsAPirate = !user.IsAPirate;
|
||||
await this.Database.SaveChangesAsync();
|
||||
|
||||
return this.Redirect("/");
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
@page "/register"
|
||||
@using LBPUnion.ProjectLighthouse.Configuration
|
||||
@using LBPUnion.ProjectLighthouse.Localization.StringLists
|
||||
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.RegisterForm
|
||||
|
||||
@{
|
||||
|
@ -26,12 +27,14 @@
|
|||
{
|
||||
<div class="ui negative message">
|
||||
<div class="header">
|
||||
Uh oh!
|
||||
@Model.Translate(GeneralStrings.Error)
|
||||
</div>
|
||||
<p>@Model.Error</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
<p><b>@Model.Translate(RegisterStrings.UsernameNotice)</b></p>
|
||||
|
||||
<form class="ui form" onsubmit="return onSubmit(this)" method="post">
|
||||
@Html.AntiForgeryToken()
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ using JetBrains.Annotations;
|
|||
using LBPUnion.ProjectLighthouse.Configuration;
|
||||
using LBPUnion.ProjectLighthouse.Extensions;
|
||||
using LBPUnion.ProjectLighthouse.Helpers;
|
||||
using LBPUnion.ProjectLighthouse.Localization.StringLists;
|
||||
using LBPUnion.ProjectLighthouse.PlayerData;
|
||||
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
|
||||
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
|
||||
|
@ -28,7 +29,7 @@ public class RegisterForm : BaseLayout
|
|||
if (this.Request.Query.ContainsKey("token"))
|
||||
{
|
||||
if (!this.Database.IsRegistrationTokenValid(this.Request.Query["token"]))
|
||||
return this.StatusCode(403, "Invalid Token");
|
||||
return this.StatusCode(403, this.Translate(ErrorStrings.TokenInvalid));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -42,44 +43,44 @@ public class RegisterForm : BaseLayout
|
|||
|
||||
if (string.IsNullOrWhiteSpace(username))
|
||||
{
|
||||
this.Error = "The username field is blank.";
|
||||
this.Error = this.Translate(ErrorStrings.UsernameInvalid);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(password))
|
||||
{
|
||||
this.Error = "Password field is required.";
|
||||
this.Error = this.Translate(ErrorStrings.PasswordInvalid);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(emailAddress) && ServerConfiguration.Instance.Mail.MailEnabled)
|
||||
{
|
||||
this.Error = "Email address field is required.";
|
||||
this.Error = this.Translate(ErrorStrings.EmailInvalid);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
if (password != confirmPassword)
|
||||
{
|
||||
this.Error = "Passwords do not match!";
|
||||
this.Error = this.Translate(ErrorStrings.PasswordDoesntMatch);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
if (await this.Database.Users.FirstOrDefaultAsync(u => u.Username.ToLower() == username.ToLower()) != null)
|
||||
{
|
||||
this.Error = "The username you've chosen is already taken.";
|
||||
this.Error = this.Translate(ErrorStrings.UsernameTaken);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
if (ServerConfiguration.Instance.Mail.MailEnabled &&
|
||||
await this.Database.Users.FirstOrDefaultAsync(u => u.EmailAddress != null && u.EmailAddress.ToLower() == emailAddress.ToLower()) != null)
|
||||
{
|
||||
this.Error = "The email address you've chosen is already taken.";
|
||||
this.Error = this.Translate(ErrorStrings.EmailTaken);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
if (!await this.Request.CheckCaptchaValidity())
|
||||
{
|
||||
this.Error = "You must complete the captcha correctly.";
|
||||
this.Error = this.Translate(ErrorStrings.CaptchaFailed);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
|
@ -94,6 +95,7 @@ public class RegisterForm : BaseLayout
|
|||
{
|
||||
UserId = user.UserId,
|
||||
UserToken = CryptoHelper.GenerateAuthToken(),
|
||||
ExpiresAt = DateTime.Now + TimeSpan.FromDays(7),
|
||||
};
|
||||
|
||||
this.Database.WebTokens.Add(webToken);
|
||||
|
@ -116,7 +118,7 @@ public class RegisterForm : BaseLayout
|
|||
if (this.Request.Query.ContainsKey("token"))
|
||||
{
|
||||
if (!this.Database.IsRegistrationTokenValid(this.Request.Query["token"]))
|
||||
return this.StatusCode(403, "Invalid Token");
|
||||
return this.StatusCode(403, this.Translate(ErrorStrings.TokenInvalid));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ public class ReportPage : BaseLayout
|
|||
public ReportPage(Database database) : base(database)
|
||||
{}
|
||||
|
||||
public GriefReport Report;
|
||||
public GriefReport Report = null!; // Report is not used if it's null in OnGet
|
||||
|
||||
public async Task<IActionResult> OnGet([FromRoute] int reportId)
|
||||
{
|
||||
|
|
|
@ -49,15 +49,18 @@ public class SetEmailForm : BaseLayout
|
|||
UserId = user.UserId,
|
||||
User = user,
|
||||
EmailToken = CryptoHelper.GenerateAuthToken(),
|
||||
ExpiresAt = DateTime.Now + TimeSpan.FromHours(6),
|
||||
};
|
||||
|
||||
this.Database.EmailVerificationTokens.Add(emailVerifyToken);
|
||||
|
||||
// The user just set their email address. Now, let's grant them a token to proceed with verifying the email.
|
||||
// TODO: insecure
|
||||
WebToken webToken = new()
|
||||
{
|
||||
UserId = user.UserId,
|
||||
UserToken = CryptoHelper.GenerateAuthToken(),
|
||||
ExpiresAt = DateTime.Now + TimeSpan.FromDays(7),
|
||||
};
|
||||
|
||||
this.Response.Cookies.Append
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
@using LBPUnion.ProjectLighthouse.Administration
|
||||
@using LBPUnion.ProjectLighthouse.Configuration
|
||||
@using LBPUnion.ProjectLighthouse.Extensions
|
||||
@using LBPUnion.ProjectLighthouse.PlayerData
|
||||
@using LBPUnion.ProjectLighthouse.PlayerData.Reviews
|
||||
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.SlotPage
|
||||
|
||||
|
@ -163,6 +164,22 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
@if (Model.Photos.Count != 0)
|
||||
{
|
||||
<div class="ui purple segment">
|
||||
<h2>Most recent photos</h2>
|
||||
|
||||
<div class="ui center aligned grid">
|
||||
@foreach (Photo photo in Model.Photos)
|
||||
{
|
||||
<div class="eight wide column">
|
||||
@await Html.PartialAsync("Partials/PhotoPartial", photo)
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.User != null && Model.User.IsModerator)
|
||||
{
|
||||
<div class="ui green segment">
|
||||
|
|
|
@ -15,6 +15,7 @@ public class SlotPage : BaseLayout
|
|||
{
|
||||
public List<Comment> Comments = new();
|
||||
public List<Review> Reviews = new();
|
||||
public List<Photo> Photos = new();
|
||||
|
||||
public readonly bool CommentsEnabled = ServerConfiguration.Instance.UserGeneratedContentLimits.LevelCommentsEnabled;
|
||||
public readonly bool ReviewsEnabled = ServerConfiguration.Instance.UserGeneratedContentLimits.LevelReviewsEnabled;
|
||||
|
@ -25,8 +26,34 @@ public class SlotPage : BaseLayout
|
|||
|
||||
public async Task<IActionResult> OnGet([FromRoute] int id)
|
||||
{
|
||||
Slot? slot = await this.Database.Slots.Include(s => s.Creator).FirstOrDefaultAsync(s => s.SlotId == id);
|
||||
Slot? slot = await this.Database.Slots.Include
|
||||
(s => s.Creator)
|
||||
.Where(s => s.Type == SlotType.User)
|
||||
.FirstOrDefaultAsync(s => s.SlotId == id);
|
||||
if (slot == null) return this.NotFound();
|
||||
System.Diagnostics.Debug.Assert(slot.Creator != null);
|
||||
|
||||
// Determine if user can view slot according to creator's privacy settings
|
||||
if (this.User == null || !this.User.IsAdmin)
|
||||
{
|
||||
switch (slot.Creator.ProfileVisibility)
|
||||
{
|
||||
case PrivacyType.PSN:
|
||||
{
|
||||
if (this.User != null) return this.NotFound();
|
||||
|
||||
break;
|
||||
}
|
||||
case PrivacyType.Game:
|
||||
{
|
||||
if (slot.Creator != this.User) return this.NotFound();
|
||||
|
||||
break;
|
||||
}
|
||||
case PrivacyType.All: break;
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
this.Slot = slot;
|
||||
|
||||
|
@ -57,6 +84,12 @@ public class SlotPage : BaseLayout
|
|||
this.Reviews = new List<Review>();
|
||||
}
|
||||
|
||||
this.Photos = await this.Database.Photos.Include(p => p.Creator)
|
||||
.OrderByDescending(p => p.Timestamp)
|
||||
.Where(r => r.SlotId == id)
|
||||
.Take(10)
|
||||
.ToListAsync();
|
||||
|
||||
if (this.User == null) return this.Page();
|
||||
|
||||
foreach (Comment c in this.Comments)
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Text;
|
|||
using LBPUnion.ProjectLighthouse.Configuration;
|
||||
using LBPUnion.ProjectLighthouse.Levels;
|
||||
using LBPUnion.ProjectLighthouse.PlayerData;
|
||||
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
|
||||
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
@ -55,6 +56,7 @@ public class SlotsPage : BaseLayout
|
|||
this.SearchValue = name.Trim();
|
||||
|
||||
this.SlotCount = await this.Database.Slots.Include(p => p.Creator)
|
||||
.Where(p => p.Type == SlotType.User)
|
||||
.Where(p => p.Name.Contains(finalSearch.ToString()))
|
||||
.Where(p => p.Creator != null && (targetAuthor == null || string.Equals(p.Creator.Username.ToLower(), targetAuthor.ToLower())))
|
||||
.Where(p => targetGame == null || p.GameVersion == targetGame)
|
||||
|
@ -66,8 +68,10 @@ public class SlotsPage : BaseLayout
|
|||
if (this.PageNumber < 0 || this.PageNumber >= this.PageAmount) return this.Redirect($"/slots/{Math.Clamp(this.PageNumber, 0, this.PageAmount - 1)}");
|
||||
|
||||
this.Slots = await this.Database.Slots.Include(p => p.Creator)
|
||||
.Where(p => p.Type == SlotType.User)
|
||||
.Where(p => p.Name.Contains(finalSearch.ToString()))
|
||||
.Where(p => p.Creator != null && (targetAuthor == null || string.Equals(p.Creator.Username.ToLower(), targetAuthor.ToLower())))
|
||||
.Where(p => p.Creator!.LevelVisibility == PrivacyType.All) // TODO: change check for when user is logged in
|
||||
.Where(p => targetGame == null || p.GameVersion == targetGame)
|
||||
.OrderByDescending(p => p.FirstUploaded)
|
||||
.Skip(pageNumber * ServerStatics.PageSize)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@page "/user/{userId:int}"
|
||||
@using System.Web
|
||||
@using LBPUnion.ProjectLighthouse.Extensions
|
||||
@using LBPUnion.ProjectLighthouse.Localization.StringLists
|
||||
@using LBPUnion.ProjectLighthouse.PlayerData
|
||||
@using LBPUnion.ProjectLighthouse.Types
|
||||
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.UserPage
|
||||
|
@ -9,7 +10,7 @@
|
|||
Layout = "Layouts/BaseLayout";
|
||||
Model.ShowTitleInPage = false;
|
||||
|
||||
Model.Title = Model.ProfileUser!.Username + "'s user page";
|
||||
Model.Title = Model.Translate(ProfileStrings.Title, Model.ProfileUser!.Username);
|
||||
Model.Description = Model.ProfileUser!.Biography;
|
||||
}
|
||||
|
||||
|
@ -74,16 +75,16 @@
|
|||
{
|
||||
<a class="ui blue button" href="/passwordReset">
|
||||
<i class="key icon"></i>
|
||||
<span>Reset Password</span>
|
||||
<span>@Model.Translate(GeneralStrings.ResetPassword)</span>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
<div class="eight wide column">
|
||||
<div class="ui blue segment">
|
||||
<h2>Biography</h2>
|
||||
<h2>@Model.Translate(ProfileStrings.Biography)</h2>
|
||||
@if (string.IsNullOrWhiteSpace(Model.ProfileUser.Biography))
|
||||
{
|
||||
<p>@Model.ProfileUser.Username hasn't introduced themselves yet</p>
|
||||
<p>@Model.Translate(ProfileStrings.NoBiography, Model.ProfileUser.Username)</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -93,8 +94,8 @@
|
|||
</div>
|
||||
<div class="eight wide column">
|
||||
<div class="ui red segment">
|
||||
<h2>Recent Activity</h2>
|
||||
<p>Coming soon?</p>
|
||||
<h2>@Model.Translate(GeneralStrings.RecentActivity)</h2>
|
||||
<p>@Model.Translate(GeneralStrings.Soon)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -103,7 +104,7 @@
|
|||
@if (Model.Photos != null && Model.Photos.Count != 0)
|
||||
{
|
||||
<div class="ui purple segment">
|
||||
<h2>Most recent photos</h2>
|
||||
<h2>@Model.Translate(GeneralStrings.RecentPhotos)</h2>
|
||||
|
||||
<div class="ui center aligned grid">
|
||||
@foreach (Photo photo in Model.Photos)
|
||||
|
|
|
@ -28,7 +28,29 @@ public class UserPage : BaseLayout
|
|||
this.ProfileUser = await this.Database.Users.FirstOrDefaultAsync(u => u.UserId == userId);
|
||||
if (this.ProfileUser == null) return this.NotFound();
|
||||
|
||||
this.Photos = await this.Database.Photos.OrderByDescending(p => p.Timestamp).Where(p => p.CreatorId == userId).Take(6).ToListAsync();
|
||||
// Determine if user can view profile according to profileUser's privacy settings
|
||||
if (this.User == null || !this.User.IsAdmin)
|
||||
{
|
||||
switch (this.ProfileUser.ProfileVisibility)
|
||||
{
|
||||
case PrivacyType.PSN:
|
||||
{
|
||||
if (this.User != null) return this.NotFound();
|
||||
|
||||
break;
|
||||
}
|
||||
case PrivacyType.Game:
|
||||
{
|
||||
if (this.ProfileUser != this.User) return this.NotFound();
|
||||
|
||||
break;
|
||||
}
|
||||
case PrivacyType.All: break;
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
this.Photos = await this.Database.Photos.Include(p => p.Slot).OrderByDescending(p => p.Timestamp).Where(p => p.CreatorId == userId).Take(6).ToListAsync();
|
||||
if (this.CommentsEnabled)
|
||||
{
|
||||
this.Comments = await this.Database.Comments.Include(p => p.Poster)
|
||||
|
|
|
@ -38,6 +38,7 @@ public class UsersPage : BaseLayout
|
|||
if (this.PageNumber < 0 || this.PageNumber >= this.PageAmount) return this.Redirect($"/users/{Math.Clamp(this.PageNumber, 0, this.PageAmount - 1)}");
|
||||
|
||||
this.Users = await this.Database.Users.Where(u => u.PermissionLevel != PermissionLevel.Banned && u.Username.Contains(this.SearchValue))
|
||||
.Where(u => u.ProfileVisibility == PrivacyType.All) // TODO: change check for when user is logged in
|
||||
.OrderByDescending(b => b.UserId)
|
||||
.Skip(pageNumber * ServerStatics.PageSize)
|
||||
.Take(ServerStatics.PageSize)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue