mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-04-19 19:14:51 +00:00
Sort team picks by the time they were team picked (#980)
This commit is contained in:
parent
983b1e9984
commit
a2eaedc85b
16 changed files with 136 additions and 21 deletions
|
@ -61,7 +61,7 @@ public struct ApiSlot
|
|||
MoveRequired = slot.MoveRequired,
|
||||
FirstUploaded = slot.FirstUploaded,
|
||||
LastUpdated = slot.LastUpdated,
|
||||
TeamPick = slot.TeamPick,
|
||||
TeamPick = slot.TeamPickTime != 0,
|
||||
Location = slot.Location,
|
||||
GameVersion = slot.GameVersion,
|
||||
Plays = slot.Plays,
|
||||
|
|
|
@ -31,7 +31,7 @@ public struct MinimalApiSlot
|
|||
Type = slot.Type,
|
||||
Name = slot.Name,
|
||||
IconHash = slot.IconHash,
|
||||
TeamPick = slot.TeamPick,
|
||||
TeamPick = slot.TeamPickTime != 0,
|
||||
IsAdventure = slot.IsAdventurePlanet,
|
||||
Location = slot.Location,
|
||||
GameVersion = slot.GameVersion,
|
||||
|
|
|
@ -247,7 +247,8 @@ public class SlotsController : ControllerBase
|
|||
pageData.TotalElements = await StatisticsHelper.SlotCount(this.database, queryBuilder);
|
||||
|
||||
SlotSortBuilder<SlotEntity> sortBuilder = new();
|
||||
sortBuilder.AddSort(new LastUpdatedSort());
|
||||
sortBuilder.AddSort(new TeamPickSort());
|
||||
sortBuilder.AddSort(new FirstUploadedSort());
|
||||
|
||||
List<SlotBase> slots = await this.database.GetSlots(token, queryBuilder, pageData, sortBuilder);
|
||||
|
||||
|
|
|
@ -19,5 +19,5 @@ public class TeamPicksCategory : SlotCategory
|
|||
|
||||
public override IQueryable<SlotEntity> GetItems(DatabaseContext database, GameTokenEntity token, SlotQueryBuilder queryBuilder) =>
|
||||
database.Slots.Where(queryBuilder.Clone().AddFilter(new TeamPickFilter()).Build())
|
||||
.ApplyOrdering(new SlotSortBuilder<SlotEntity>().AddSort(new FirstUploadedSort()));
|
||||
.ApplyOrdering(new SlotSortBuilder<SlotEntity>().AddSort(new TeamPickSort()).AddSort(new FirstUploadedSort()));
|
||||
}
|
|
@ -28,7 +28,7 @@ public class ModerationSlotController : ControllerBase
|
|||
SlotEntity? slot = await this.database.Slots.Include(s => s.Creator).FirstOrDefaultAsync(s => s.SlotId == id);
|
||||
if (slot == null) return this.NotFound();
|
||||
|
||||
slot.TeamPick = true;
|
||||
slot.TeamPickTime = TimeHelper.TimestampMillis;
|
||||
|
||||
// Send webhook with slot.Name and slot.Creator.Username
|
||||
await WebhookHelper.SendWebhook("New Team Pick!", $"The level [**{slot.Name}**]({ServerConfiguration.Instance.ExternalUrl}/slot/{slot.SlotId}) by **{slot.Creator?.Username}** has been team picked");
|
||||
|
@ -51,7 +51,7 @@ public class ModerationSlotController : ControllerBase
|
|||
SlotEntity? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == id);
|
||||
if (slot == null) return this.NotFound();
|
||||
|
||||
slot.TeamPick = false;
|
||||
slot.TeamPickTime = 0;
|
||||
|
||||
// Send a notification to the creator
|
||||
await this.database.SendNotification(slot.CreatorId,
|
||||
|
|
|
@ -41,8 +41,9 @@ public class LandingPage : BaseLayout
|
|||
const int maxShownLevels = 5;
|
||||
|
||||
this.LatestTeamPicks = await this.Database.Slots.Where(s => s.Type == SlotType.User && !s.SubLevel && !s.Hidden)
|
||||
.Where(s => s.TeamPick)
|
||||
.OrderByDescending(s => s.FirstUploaded)
|
||||
.Where(s => s.TeamPickTime != 0)
|
||||
.OrderByDescending(s => s.TeamPickTime)
|
||||
.ThenByDescending(s => s.FirstUploaded)
|
||||
.Take(maxShownLevels)
|
||||
.Include(s => s.Creator)
|
||||
.ToListAsync();
|
||||
|
|
|
@ -217,9 +217,9 @@ else
|
|||
<div class="ui green segment">
|
||||
<h2>Moderation Options</h2>
|
||||
|
||||
@if (Model.Slot?.TeamPick ?? false)
|
||||
@if ((Model.Slot?.TeamPickTime ?? 0) != 0)
|
||||
{
|
||||
<a href="/moderation/slot/@Model.Slot.SlotId/removeTeamPick">
|
||||
<a href="/moderation/slot/@Model.Slot?.SlotId/removeTeamPick">
|
||||
<div class="ui pink button">
|
||||
<i class="star icon"></i>
|
||||
<span>Remove Team Pick</span>
|
||||
|
|
|
@ -495,4 +495,62 @@ public class SlotControllerTests
|
|||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Team Picks
|
||||
[Fact]
|
||||
public async Task TeamPick_ShouldOnlyIncludeTeamPickedLevels()
|
||||
{
|
||||
DatabaseContext db = await MockHelper.GetTestDatabase(new List<SlotEntity>
|
||||
{
|
||||
new()
|
||||
{
|
||||
SlotId = 1,
|
||||
CreatorId = 1,
|
||||
TeamPickTime = 1,
|
||||
},
|
||||
new()
|
||||
{
|
||||
SlotId = 2,
|
||||
CreatorId = 1,
|
||||
TeamPickTime = 0,
|
||||
},
|
||||
});
|
||||
SlotsController controller = new(db);
|
||||
controller.SetupTestController();
|
||||
|
||||
IActionResult result = await controller.TeamPickedSlots();
|
||||
GenericSlotResponse slotResponse = result.CastTo<OkObjectResult, GenericSlotResponse>();
|
||||
Assert.Single(slotResponse.Slots);
|
||||
Assert.Equal(1, slotResponse.Slots.OfType<GameUserSlot>().First().SlotId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TeamPick_LevelsAreSortedByTimestamp()
|
||||
{
|
||||
DatabaseContext db = await MockHelper.GetTestDatabase(new List<SlotEntity>
|
||||
{
|
||||
new()
|
||||
{
|
||||
SlotId = 1,
|
||||
CreatorId = 1,
|
||||
TeamPickTime = 1,
|
||||
},
|
||||
new()
|
||||
{
|
||||
SlotId = 2,
|
||||
CreatorId = 1,
|
||||
TeamPickTime = 5,
|
||||
},
|
||||
});
|
||||
SlotsController controller = new(db);
|
||||
controller.SetupTestController();
|
||||
|
||||
IActionResult result = await controller.TeamPickedSlots();
|
||||
|
||||
GenericSlotResponse slotResponse = result.CastTo<OkObjectResult, GenericSlotResponse>();
|
||||
Assert.Equal(2, slotResponse.Slots.Count);
|
||||
Assert.Equal(2, slotResponse.Slots.OfType<GameUserSlot>().First().SlotId);
|
||||
Assert.Equal(1, slotResponse.Slots.OfType<GameUserSlot>().Last().SlotId);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public class StatisticsControllerTests
|
|||
{
|
||||
SlotId = 3,
|
||||
CreatorId = 1,
|
||||
TeamPick = true,
|
||||
TeamPickTime = 1,
|
||||
},
|
||||
};
|
||||
await using DatabaseContext db = await MockHelper.GetTestDatabase(slots);
|
||||
|
@ -90,7 +90,7 @@ public class StatisticsControllerTests
|
|||
{
|
||||
SlotId = 3,
|
||||
CreatorId = 1,
|
||||
TeamPick = true,
|
||||
TeamPickTime = 1,
|
||||
GameVersion = GameVersion.LittleBigPlanet2,
|
||||
},
|
||||
};
|
||||
|
@ -130,7 +130,7 @@ public class StatisticsControllerTests
|
|||
{
|
||||
SlotId = 3,
|
||||
CreatorId = 1,
|
||||
TeamPick = true,
|
||||
TeamPickTime = 1,
|
||||
GameVersion = GameVersion.LittleBigPlanet1,
|
||||
},
|
||||
};
|
||||
|
@ -168,7 +168,7 @@ public class StatisticsControllerTests
|
|||
{
|
||||
SlotId = 3,
|
||||
CreatorId = 1,
|
||||
TeamPick = true,
|
||||
TeamPickTime = 1,
|
||||
GameVersion = GameVersion.LittleBigPlanet2,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -729,7 +729,7 @@ public class FilterTests
|
|||
|
||||
SlotEntity slot = new()
|
||||
{
|
||||
TeamPick = true,
|
||||
TeamPickTime = 1,
|
||||
};
|
||||
|
||||
Assert.True(teamPickFunc(slot));
|
||||
|
@ -743,7 +743,7 @@ public class FilterTests
|
|||
|
||||
SlotEntity slot = new()
|
||||
{
|
||||
TeamPick = false,
|
||||
TeamPickTime = 0,
|
||||
};
|
||||
|
||||
Assert.False(teamPickFunc(slot));
|
||||
|
|
|
@ -7,5 +7,5 @@ namespace LBPUnion.ProjectLighthouse.Filter.Filters;
|
|||
|
||||
public class TeamPickFilter : ISlotFilter
|
||||
{
|
||||
public Expression<Func<SlotEntity, bool>> GetPredicate() => s => s.TeamPick;
|
||||
public Expression<Func<SlotEntity, bool>> GetPredicate() => s => s.TeamPickTime != 0;
|
||||
}
|
11
ProjectLighthouse/Filter/Sorts/TeamPickSort.cs
Normal file
11
ProjectLighthouse/Filter/Sorts/TeamPickSort.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Level;
|
||||
using LBPUnion.ProjectLighthouse.Types.Filter.Sorts;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Filter.Sorts;
|
||||
|
||||
public class TeamPickSort : ISlotSort
|
||||
{
|
||||
public Expression<Func<SlotEntity, dynamic>> GetExpression() => s => s.TeamPickTime;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
using LBPUnion.ProjectLighthouse.Database;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ProjectLighthouse.Migrations
|
||||
{
|
||||
[DbContext(typeof(DatabaseContext))]
|
||||
[Migration("20240214031744_UpdateTeamPickBoolToTimestamp")]
|
||||
public partial class UpdateTeamPickBoolToTimestamp : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<long>(name: "TeamPickTime",
|
||||
table: "Slots",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
defaultValue: 0L);
|
||||
|
||||
migrationBuilder.Sql("UPDATE `Slots` SET TeamPickTime = 1 WHERE TeamPick = 1");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TeamPick",
|
||||
table: "Slots");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TeamPickTime",
|
||||
table: "Slots");
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "TeamPick",
|
||||
table: "Slots",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -472,8 +472,8 @@ namespace ProjectLighthouse.Migrations
|
|||
b.Property<bool>("SubLevel")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("TeamPick")
|
||||
.HasColumnType("tinyint(1)");
|
||||
b.Property<long>("TeamPickTime")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int");
|
||||
|
|
|
@ -102,7 +102,7 @@ public class SlotEntity
|
|||
|
||||
public long LastUpdated { get; set; }
|
||||
|
||||
public bool TeamPick { get; set; }
|
||||
public long TeamPickTime { get; set; }
|
||||
|
||||
public GameVersion GameVersion { get; set; }
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ public abstract class SlotBase : ILbpSerializable
|
|||
InitiallyLocked = slot.InitiallyLocked,
|
||||
RootLevel = slot.RootLevel,
|
||||
IsShareable = slot.Shareable,
|
||||
IsTeamPicked = slot.TeamPick,
|
||||
IsTeamPicked = slot.TeamPickTime != 0,
|
||||
FirstUploaded = slot.FirstUploaded,
|
||||
LastUpdated = slot.LastUpdated,
|
||||
IsCrossControlRequired = slot.CrossControllerRequired,
|
||||
|
|
Loading…
Add table
Reference in a new issue