Implement online story features and photos taken in levels (#389)

* Initial commit to support developer slots

* Remove hearting story levels, prevent race condition in adding dev slots, and remove LastContactHelper local db object.

* Fix photos taken in pod showing wrong level.

* Add support for pod and create mode photos

* Add time display to photos and added photo display to level page

* Add pagination to in game photos

* Update in pod description

* Fix migration

* Adjust wording of photos taken on local slots

* Set slot default type to User

Fixes old slots being set to developer slots

* Apply suggestions

* Add player count to developer slots

Co-authored-by: Jayden <jvyden@jvyden.xyz>
This commit is contained in:
Josh 2022-08-01 14:46:29 -05:00 committed by GitHub
commit fdf1988a34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 483 additions and 47 deletions

View file

@ -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();
}

View file

@ -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>

View file

@ -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)

View file

@ -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
@ -162,7 +163,21 @@
</div>
</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.IsAdmin)
{
<div class="ui yellow segment">

View file

@ -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,7 +26,10 @@ 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();
this.Slot = slot;
@ -57,6 +61,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)

View file

@ -55,6 +55,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,6 +67,7 @@ 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 => targetGame == null || p.GameVersion == targetGame)

View file

@ -28,7 +28,7 @@ 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();
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)