mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-07-28 16:08:38 +00:00
Add level comments and yays and boos for all comments
This commit is contained in:
parent
075bef6d68
commit
19a29ca328
15 changed files with 370 additions and 46 deletions
|
@ -1,4 +1,5 @@
|
|||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
@ -7,6 +8,7 @@ using System.Xml.Serialization;
|
|||
using LBPUnion.ProjectLighthouse.Helpers;
|
||||
using LBPUnion.ProjectLighthouse.Serialization;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using LBPUnion.ProjectLighthouse.Types.Levels;
|
||||
using LBPUnion.ProjectLighthouse.Types.Profiles;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
@ -24,37 +26,130 @@ public class CommentController : ControllerBase
|
|||
this.database = database;
|
||||
}
|
||||
|
||||
[HttpGet("userComments/{username}")]
|
||||
public async Task<IActionResult> GetComments(string username)
|
||||
[HttpPost("rateUserComment/{username}")]
|
||||
[HttpPost("rateComment/user/{slotId:int}")]
|
||||
public async Task<IActionResult> RateComment([FromQuery] int commentId, [FromQuery] int rating, string? username, int? slotId)
|
||||
{
|
||||
List<Comment> comments = await this.database.Comments.Include
|
||||
(c => c.Target)
|
||||
User? user = await this.database.UserFromGameRequest(this.Request);
|
||||
if (user == null) return this.StatusCode(403, "");
|
||||
|
||||
Comment? comment = await this.database.Comments.Include(c => c.Poster).FirstOrDefaultAsync(c => commentId == c.CommentId);
|
||||
|
||||
if (comment == null) return this.BadRequest();
|
||||
|
||||
Reaction? reaction = await this.database.Reactions.FirstOrDefaultAsync(r => r.UserId == user.UserId && r.TargetId == commentId);
|
||||
if (reaction == null)
|
||||
{
|
||||
Reaction newReaction = new Reaction()
|
||||
{
|
||||
UserId = user.UserId,
|
||||
TargetId = commentId,
|
||||
Rating = 0,
|
||||
};
|
||||
this.database.Reactions.Add(newReaction);
|
||||
await this.database.SaveChangesAsync();
|
||||
reaction = newReaction;
|
||||
}
|
||||
int oldRating = reaction.Rating;
|
||||
if (oldRating == rating) return this.Ok();
|
||||
|
||||
reaction.Rating = rating;
|
||||
// if rating changed then we count the number of reactions to ensure accuracy
|
||||
List<Reaction> reactions = await this.database.Reactions
|
||||
.Where(c => c.TargetId == commentId)
|
||||
.ToListAsync();
|
||||
int yay = 0;
|
||||
int boo = 0;
|
||||
foreach (Reaction r in reactions)
|
||||
{
|
||||
switch (r.Rating)
|
||||
{
|
||||
case -1:
|
||||
boo++;
|
||||
break;
|
||||
case 1:
|
||||
yay++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
comment.ThumbsDown = boo;
|
||||
comment.ThumbsUp = yay;
|
||||
await this.database.SaveChangesAsync();
|
||||
return this.Ok();
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("comments/user/{slotId:int}")]
|
||||
[HttpGet("userComments/{username}")]
|
||||
public async Task<IActionResult> GetComments([FromQuery] int pageStart, [FromQuery] int pageSize, string? username, int? slotId)
|
||||
{
|
||||
User? user = await this.database.UserFromGameRequest(this.Request);
|
||||
if (user == null) return this.StatusCode(403, "");
|
||||
|
||||
int targetId = slotId.GetValueOrDefault();
|
||||
CommentType type = CommentType.Level;
|
||||
if (!string.IsNullOrWhiteSpace(username))
|
||||
{
|
||||
targetId = this.database.Users.First(u => u.Username.Equals(username)).UserId;
|
||||
type = CommentType.Profile;
|
||||
}
|
||||
|
||||
List<Comment> comments = await this.database.Comments
|
||||
.Include(c => c.Poster)
|
||||
.Where(c => c.Target.Username == username)
|
||||
.Where(c => c.TargetId == targetId && c.Type == type)
|
||||
.OrderByDescending(c => c.Timestamp)
|
||||
.Skip(pageStart - 1)
|
||||
.Take(Math.Min(pageSize,
|
||||
30))
|
||||
.ToListAsync();
|
||||
|
||||
string outputXml = comments.Aggregate(string.Empty, (current, comment) => current + comment.Serialize());
|
||||
string outputXml = comments.Aggregate(string.Empty, (current, comment) => current +
|
||||
comment.Serialize(this.getReaction(user.UserId, comment.CommentId).Result));
|
||||
return this.Ok(LbpSerializer.StringElement("comments", outputXml));
|
||||
}
|
||||
|
||||
[HttpPost("postUserComment/{username}")]
|
||||
public async Task<IActionResult> PostComment(string username)
|
||||
public async Task<int> getReaction(int userId, int commentId)
|
||||
{
|
||||
this.Request.Body.Position = 0;
|
||||
Reaction? reaction = await this.database.Reactions.FirstOrDefaultAsync(r => r.UserId == userId && r.TargetId == commentId);
|
||||
if (reaction == null) return 0;
|
||||
return reaction.Rating;
|
||||
}
|
||||
|
||||
[HttpPost("postUserComment/{username}")]
|
||||
[HttpPost("postComment/user/{slotId:int}")]
|
||||
public async Task<IActionResult> PostComment(string? username, int? slotId)
|
||||
{
|
||||
this.Request.Body.Position = 0;
|
||||
string bodyString = await new StreamReader(this.Request.Body).ReadToEndAsync();
|
||||
|
||||
XmlSerializer serializer = new(typeof(Comment));
|
||||
Comment? comment = (Comment?)serializer.Deserialize(new StringReader(bodyString));
|
||||
Comment? comment = (Comment?) serializer.Deserialize(new StringReader(bodyString));
|
||||
|
||||
CommentType type = (slotId.GetValueOrDefault() == 0 ? CommentType.Profile : CommentType.Level);
|
||||
|
||||
User? poster = await this.database.UserFromGameRequest(this.Request);
|
||||
if (poster == null) return this.StatusCode(403, "");
|
||||
|
||||
User? target = await this.database.Users.FirstOrDefaultAsync(u => u.Username == username);
|
||||
if (comment == null || target == null) return this.BadRequest();
|
||||
if (comment == null) return this.BadRequest();
|
||||
|
||||
int targetId = slotId.GetValueOrDefault();
|
||||
|
||||
if (type == CommentType.Profile)
|
||||
{
|
||||
User? target = await this.database.Users.FirstOrDefaultAsync(u => u.Username == username);
|
||||
if (target == null) return this.BadRequest();
|
||||
targetId = target.UserId;
|
||||
}
|
||||
else
|
||||
{
|
||||
Slot? target = await this.database.Slots.FirstOrDefaultAsync(u => u.SlotId == slotId);
|
||||
if (target == null) return this.BadRequest();
|
||||
}
|
||||
|
||||
comment.PosterUserId = poster.UserId;
|
||||
comment.TargetUserId = target.UserId;
|
||||
comment.TargetId = targetId;
|
||||
comment.Type = type;
|
||||
|
||||
comment.Timestamp = TimeHelper.UnixTimeMilliseconds();
|
||||
|
||||
|
@ -64,17 +159,40 @@ public class CommentController : ControllerBase
|
|||
}
|
||||
|
||||
[HttpPost("deleteUserComment/{username}")]
|
||||
public async Task<IActionResult> DeleteComment([FromQuery] int commentId, string username)
|
||||
[HttpPost("deleteComment/user/{slotId:int}")]
|
||||
public async Task<IActionResult> DeleteComment([FromQuery] int commentId, string? username, int? slotId)
|
||||
{
|
||||
User? user = await this.database.UserFromGameRequest(this.Request);
|
||||
if (user == null) return this.StatusCode(403, "");
|
||||
|
||||
Comment? comment = await this.database.Comments.FirstOrDefaultAsync(c => c.CommentId == commentId);
|
||||
if (comment == null) return this.NotFound();
|
||||
// if you are not the poster
|
||||
if (comment.PosterUserId != user.UserId)
|
||||
{
|
||||
if (comment.Type == CommentType.Profile)
|
||||
{
|
||||
// if you aren't the poster and aren't the profile owner
|
||||
if (comment.TargetId != user.UserId)
|
||||
{
|
||||
return this.StatusCode(403, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Slot? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == comment.TargetId);
|
||||
// if you aren't the creator of the level
|
||||
if (slot == null || slot.CreatorId != user.UserId || slotId.GetValueOrDefault() != slot.SlotId)
|
||||
{
|
||||
return this.StatusCode(403, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (comment.TargetUserId != user.UserId && comment.PosterUserId != user.UserId) return this.StatusCode(403, "");
|
||||
comment.Deleted = true;
|
||||
comment.DeletedBy = user.Username;
|
||||
comment.DeletedType = "user";
|
||||
|
||||
this.database.Comments.Remove(comment);
|
||||
await this.database.SaveChangesAsync();
|
||||
|
||||
return this.Ok();
|
||||
|
|
|
@ -36,6 +36,7 @@ public class Database : DbContext
|
|||
public DbSet<RatedReview> RatedReviews { get; set; }
|
||||
public DbSet<UserApprovedIpAddress> UserApprovedIpAddresses { get; set; }
|
||||
public DbSet<DatabaseCategory> CustomCategories { get; set; }
|
||||
public DbSet<Reaction> Reactions { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder options)
|
||||
=> options.UseMySql(ServerSettings.Instance.DbConnectionString, MySqlServerVersion.LatestSupportedServerVersion);
|
||||
|
@ -272,6 +273,7 @@ public class Database : DbContext
|
|||
this.Comments.RemoveRange(this.Comments.Where(c => c.PosterUserId == user.UserId));
|
||||
this.Reviews.RemoveRange(this.Reviews.Where(r => r.ReviewerId == user.UserId));
|
||||
this.Photos.RemoveRange(this.Photos.Where(p => p.CreatorId == user.UserId));
|
||||
this.Reactions.RemoveRange(this.Reactions.Where(p => p.UserId == user.UserId));
|
||||
|
||||
this.Users.Remove(user);
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ProjectLighthouse.Migrations
|
||||
{
|
||||
public partial class CommentRefactor : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Comments_Slots_TargetId",
|
||||
table: "Comments");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Comments_Users_TargetId",
|
||||
table: "Comments");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Comments_TargetId",
|
||||
table: "Comments");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Comments_TargetId",
|
||||
table: "Comments",
|
||||
column: "TargetId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Comments_Slots_TargetId",
|
||||
table: "Comments",
|
||||
column: "TargetId",
|
||||
principalTable: "Slots",
|
||||
principalColumn: "SlotId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Comments_Users_TargetId",
|
||||
table: "Comments",
|
||||
column: "TargetId",
|
||||
principalTable: "Users",
|
||||
principalColumn: "UserId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -412,13 +412,22 @@ namespace ProjectLighthouse.Migrations
|
|||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Deleted")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("DeletedBy")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("DeletedType")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("PosterUserId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("TargetUserId")
|
||||
b.Property<int>("TargetId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ThumbsDown")
|
||||
|
@ -430,12 +439,13 @@ namespace ProjectLighthouse.Migrations
|
|||
b.Property<long>("Timestamp")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("CommentId");
|
||||
|
||||
b.HasIndex("PosterUserId");
|
||||
|
||||
b.HasIndex("TargetUserId");
|
||||
|
||||
b.ToTable("Comments");
|
||||
});
|
||||
|
||||
|
@ -473,6 +483,26 @@ namespace ProjectLighthouse.Migrations
|
|||
b.ToTable("Locations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reaction", b =>
|
||||
{
|
||||
b.Property<int>("RatingId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Rating")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("TargetId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("RatingId");
|
||||
|
||||
b.ToTable("Reactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.RatedReview", b =>
|
||||
{
|
||||
b.Property<int>("RatedReviewId")
|
||||
|
@ -829,15 +859,7 @@ namespace ProjectLighthouse.Migrations
|
|||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Target")
|
||||
.WithMany()
|
||||
.HasForeignKey("TargetUserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Poster");
|
||||
|
||||
b.Navigation("Target");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Reviews.RatedReview", b =>
|
||||
|
|
|
@ -10,11 +10,13 @@
|
|||
|
||||
<script>
|
||||
function onSubmit(form) {
|
||||
const password = form['password'];
|
||||
const confirmPassword = form['confirmPassword'];
|
||||
const passwordInput = document.getElementById("password");
|
||||
const confirmPasswordInput = document.getElementById("confirmPassword");
|
||||
const passwordSubmit = document.getElementById("password-submit");
|
||||
const confirmPasswordSubmit = document.getElementById("confirmPassword-submit");
|
||||
|
||||
password.value = sha256(password.value);
|
||||
confirmPassword.value = sha256(confirmPassword.value);
|
||||
passwordSubmit.value = sha256(passwordInput.value);
|
||||
confirmPasswordSubmit.value = sha256(confirmPasswordInput.value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -35,12 +37,14 @@
|
|||
|
||||
<div class="ui left labeled input">
|
||||
<label for="password" class="ui blue label">Password: </label>
|
||||
<input type="password" name="password" id="password">
|
||||
<input type="password" id="password">
|
||||
<input type="hidden" id="password-submit" name="password">
|
||||
</div><br><br>
|
||||
|
||||
<div class="ui left labeled input">
|
||||
<label for="password" class="ui blue label">Confirm Password: </label>
|
||||
<input type="password" name="confirmPassword" id="confirmPassword">
|
||||
<input type="password" id="confirmPassword">
|
||||
<input type="hidden" id="confirmPassword-submit" name="confirmPassword">
|
||||
</div><br><br><br>
|
||||
|
||||
<input type="submit" value="Reset password and continue" id="submit" class="ui green button"><br>
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
@page "/slot/{id:int}"
|
||||
@using System.IO
|
||||
@using System.Web
|
||||
@using LBPUnion.ProjectLighthouse.Helpers.Extensions
|
||||
@using LBPUnion.ProjectLighthouse.Types.Profiles
|
||||
@model LBPUnion.ProjectLighthouse.Pages.SlotPage
|
||||
|
||||
@{
|
||||
|
@ -54,6 +57,36 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui yellow segment">
|
||||
<h1>Comments</h1>
|
||||
@if (Model.Comments.Count == 0)
|
||||
{
|
||||
<p>There are no comments.</p>
|
||||
}
|
||||
|
||||
@foreach (Comment comment in Model.Comments!)
|
||||
{
|
||||
DateTimeOffset timestamp = DateTimeOffset.FromUnixTimeSeconds(comment.Timestamp / 1000);
|
||||
StringWriter messageWriter = new();
|
||||
HttpUtility.HtmlDecode(comment.getComment(), messageWriter);
|
||||
string decodedMessage = messageWriter.ToString();
|
||||
<div>
|
||||
<b><a href="/user/@comment.PosterUserId">@comment.Poster.Username</a>: </b>
|
||||
@if (comment.Deleted)
|
||||
{
|
||||
<i><span>@decodedMessage</span></i>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>@decodedMessage</span>
|
||||
}
|
||||
<p>
|
||||
<i>@timestamp.ToString("MM/dd/yyyy @ h:mm tt") UTC</i>
|
||||
</p>
|
||||
<div class="ui divider"></div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@if (Model.User != null && Model.User.IsAdmin)
|
||||
{
|
||||
<div class="ui yellow segment">
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using LBPUnion.ProjectLighthouse.Pages.Layouts;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using LBPUnion.ProjectLighthouse.Types.Levels;
|
||||
using LBPUnion.ProjectLighthouse.Types.Profiles;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
|
@ -10,6 +14,7 @@ namespace LBPUnion.ProjectLighthouse.Pages;
|
|||
|
||||
public class SlotPage : BaseLayout
|
||||
{
|
||||
public List<Comment> Comments;
|
||||
|
||||
public Slot Slot;
|
||||
public SlotPage([NotNull] Database database) : base(database)
|
||||
|
@ -20,6 +25,12 @@ public class SlotPage : BaseLayout
|
|||
Slot? slot = await this.Database.Slots.Include(s => s.Creator).FirstOrDefaultAsync(s => s.SlotId == id);
|
||||
if (slot == null) return this.NotFound();
|
||||
|
||||
this.Comments = await this.Database.Comments.Include(p => p.Poster)
|
||||
.OrderByDescending(p => p.Timestamp)
|
||||
.Where(c => c.TargetId == id && c.Type == CommentType.Level)
|
||||
.Take(50)
|
||||
.ToListAsync();
|
||||
|
||||
this.Slot = slot;
|
||||
|
||||
return this.Page();
|
||||
|
|
|
@ -126,11 +126,19 @@
|
|||
{
|
||||
DateTimeOffset timestamp = DateTimeOffset.FromUnixTimeSeconds(comment.Timestamp / 1000);
|
||||
StringWriter messageWriter = new();
|
||||
HttpUtility.HtmlDecode(comment.Message, messageWriter);
|
||||
HttpUtility.HtmlDecode(comment.getComment(), messageWriter);
|
||||
string decodedMessage = messageWriter.ToString();
|
||||
<div>
|
||||
<b><a href="/user/@comment.PosterUserId">@comment.Poster.Username</a>: </b>
|
||||
<span>@decodedMessage</span>
|
||||
@if (comment.Deleted)
|
||||
{
|
||||
<i><span>@decodedMessage</span></i>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>@decodedMessage</span>
|
||||
}
|
||||
|
||||
<p>
|
||||
<i>@timestamp.ToString("MM/dd/yyyy @ h:mm tt") UTC</i>
|
||||
</p>
|
||||
|
|
|
@ -30,9 +30,8 @@ public class UserPage : BaseLayout
|
|||
this.Photos = await this.Database.Photos.OrderByDescending(p => p.Timestamp).Where(p => p.CreatorId == userId).Take(6).ToListAsync();
|
||||
this.Comments = await this.Database.Comments.Include
|
||||
(p => p.Poster)
|
||||
.Include(p => p.Target)
|
||||
.OrderByDescending(p => p.Timestamp)
|
||||
.Where(p => p.TargetUserId == userId)
|
||||
.Where(p => p.TargetId == userId && p.Type == CommentType.Profile)
|
||||
.Take(50)
|
||||
.ToListAsync();
|
||||
|
||||
|
|
7
ProjectLighthouse/Types/CommentType.cs
Normal file
7
ProjectLighthouse/Types/CommentType.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace LBPUnion.ProjectLighthouse.Types;
|
||||
|
||||
public enum CommentType
|
||||
{
|
||||
Profile = 0,
|
||||
Level = 1,
|
||||
}
|
|
@ -8,6 +8,7 @@ using LBPUnion.ProjectLighthouse.Helpers;
|
|||
using LBPUnion.ProjectLighthouse.Serialization;
|
||||
using LBPUnion.ProjectLighthouse.Types.Profiles;
|
||||
using LBPUnion.ProjectLighthouse.Types.Reviews;
|
||||
using LBPUnion.ProjectLighthouse.Types.Settings;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Types.Levels;
|
||||
|
||||
|
@ -121,6 +122,19 @@ public class Slot
|
|||
}
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
[NotMapped]
|
||||
[JsonIgnore]
|
||||
public int Comments
|
||||
{
|
||||
get
|
||||
{
|
||||
using Database database = new();
|
||||
|
||||
return database.Comments.Count(c => c.Type == CommentType.Level && c.TargetId == this.SlotId);
|
||||
}
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
[NotMapped]
|
||||
public int Plays => this.PlaysLBP1 + this.PlaysLBP2 + this.PlaysLBP3 + this.PlaysLBPVita;
|
||||
|
@ -251,6 +265,7 @@ public class Slot
|
|||
LbpSerializer.StringElement("icon", this.IconHash) +
|
||||
LbpSerializer.StringElement("rootLevel", this.RootLevel) +
|
||||
LbpSerializer.StringElement("authorLabels", this.AuthorLabels) +
|
||||
LbpSerializer.StringElement("labels", this.AuthorLabels) +
|
||||
this.SerializeResources() +
|
||||
LbpSerializer.StringElement("location", this.Location?.Serialize()) +
|
||||
LbpSerializer.StringElement("initiallyLocked", this.InitiallyLocked) +
|
||||
|
@ -266,6 +281,7 @@ public class Slot
|
|||
LbpSerializer.StringElement("mmpick", this.TeamPick) +
|
||||
LbpSerializer.StringElement("heartCount", this.Hearts) +
|
||||
LbpSerializer.StringElement("playCount", this.Plays) +
|
||||
LbpSerializer.StringElement("commentCount", this.Comments) +
|
||||
LbpSerializer.StringElement("uniquePlayCount", this.PlaysLBP2Unique) + // ??? good naming scheme lol
|
||||
LbpSerializer.StringElement("completionCount", this.PlaysComplete) +
|
||||
LbpSerializer.StringElement("lbp1PlayCount", this.PlaysLBP1) +
|
||||
|
@ -277,7 +293,7 @@ public class Slot
|
|||
LbpSerializer.StringElement("lbp3PlayCount", this.PlaysLBP3) +
|
||||
LbpSerializer.StringElement("lbp3CompletionCount", this.PlaysLBP3Complete) +
|
||||
LbpSerializer.StringElement("lbp3UniquePlayCount", this.PlaysLBP3Unique) +
|
||||
LbpSerializer.StringElement("vitaCrossControlRequired", CrossControllerRequired) +
|
||||
LbpSerializer.StringElement("vitaCrossControlRequired", this.CrossControllerRequired) +
|
||||
LbpSerializer.StringElement("thumbsup", this.Thumbsup) +
|
||||
LbpSerializer.StringElement("thumbsdown", this.Thumbsdown) +
|
||||
LbpSerializer.StringElement("averageRating", this.RatingLBP1) +
|
||||
|
@ -290,8 +306,8 @@ public class Slot
|
|||
LbpSerializer.StringElement
|
||||
("yourLBPVitaPlayCount", yourVisitedStats?.PlaysLBPVita) + // i doubt this is the right name but we'll go with it
|
||||
yourReview?.Serialize("yourReview") +
|
||||
LbpSerializer.StringElement("reviewsEnabled", true) +
|
||||
LbpSerializer.StringElement("commentsEnabled", false) +
|
||||
LbpSerializer.StringElement("reviewsEnabled", ServerSettings.Instance.LevelReviewsEnabled) +
|
||||
LbpSerializer.StringElement("commentsEnabled", ServerSettings.Instance.LevelCommentsEnabled) +
|
||||
LbpSerializer.StringElement("reviewCount", this.ReviewCount);
|
||||
|
||||
return LbpSerializer.TaggedStringElement("slot", slotData, "type", "user");
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using LBPUnion.ProjectLighthouse.Serialization;
|
||||
|
||||
|
@ -15,27 +16,60 @@ public class Comment
|
|||
|
||||
public int PosterUserId { get; set; }
|
||||
|
||||
public int TargetUserId { get; set; }
|
||||
public int TargetId { get; set; }
|
||||
|
||||
[ForeignKey(nameof(PosterUserId))]
|
||||
public User Poster { get; set; }
|
||||
|
||||
[ForeignKey(nameof(TargetUserId))]
|
||||
public User Target { get; set; }
|
||||
public bool Deleted { get; set; }
|
||||
|
||||
public string DeletedType { get; set; }
|
||||
|
||||
public string DeletedBy { get; set; }
|
||||
|
||||
public long Timestamp { get; set; }
|
||||
|
||||
[XmlElement("message")]
|
||||
public string Message { get; set; }
|
||||
|
||||
public CommentType Type { get; set; }
|
||||
|
||||
public int ThumbsUp { get; set; }
|
||||
public int ThumbsDown { get; set; }
|
||||
|
||||
public string getComment()
|
||||
{
|
||||
if (!this.Deleted)
|
||||
{
|
||||
return this.Message;
|
||||
}
|
||||
|
||||
if (this.DeletedBy == this.Poster.Username)
|
||||
{
|
||||
return "This comment has been deleted by the author.";
|
||||
}
|
||||
else
|
||||
{
|
||||
using Database database = new();
|
||||
User deletedBy = database.Users.FirstOrDefault(u => u.Username == this.DeletedBy);
|
||||
|
||||
if (deletedBy != null && deletedBy.UserId == this.TargetId)
|
||||
{
|
||||
return "This comment has been deleted by the player.";
|
||||
}
|
||||
}
|
||||
|
||||
return "This comment has been deleted.";
|
||||
}
|
||||
|
||||
private string serialize()
|
||||
=> LbpSerializer.StringElement("id", this.CommentId) +
|
||||
LbpSerializer.StringElement("npHandle", this.Poster.Username) +
|
||||
LbpSerializer.StringElement("timestamp", this.Timestamp) +
|
||||
LbpSerializer.StringElement("message", this.Message) +
|
||||
(this.Deleted ? LbpSerializer.StringElement("deleted", true) +
|
||||
LbpSerializer.StringElement("deletedBy", this.DeletedBy) +
|
||||
LbpSerializer.StringElement("deletedType", this.DeletedBy) : "") +
|
||||
LbpSerializer.StringElement("thumbsup", this.ThumbsUp) +
|
||||
LbpSerializer.StringElement("thumbsdown", this.ThumbsDown);
|
||||
|
||||
|
|
16
ProjectLighthouse/Types/Reaction.cs
Normal file
16
ProjectLighthouse/Types/Reaction.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Types;
|
||||
|
||||
public class Reaction
|
||||
{
|
||||
[Key]
|
||||
public int RatingId { get; set; }
|
||||
|
||||
public int UserId { get; set; }
|
||||
|
||||
public int TargetId { get; set; }
|
||||
|
||||
public int Rating { get; set; }
|
||||
|
||||
}
|
|
@ -13,7 +13,7 @@ namespace LBPUnion.ProjectLighthouse.Types.Settings;
|
|||
[Serializable]
|
||||
public class ServerSettings
|
||||
{
|
||||
public const int CurrentConfigVersion = 18; // MUST BE INCREMENTED FOR EVERY CONFIG CHANGE!
|
||||
public const int CurrentConfigVersion = 19; // MUST BE INCREMENTED FOR EVERY CONFIG CHANGE!
|
||||
private static FileSystemWatcher fileWatcher;
|
||||
static ServerSettings()
|
||||
{
|
||||
|
@ -132,6 +132,12 @@ public class ServerSettings
|
|||
|
||||
public int PhotosQuota { get; set; } = 500;
|
||||
|
||||
public bool ProfileCommentsEnabled { get; set; } = true;
|
||||
|
||||
public bool LevelCommentsEnabled { get; set; } = true;
|
||||
|
||||
public bool LevelReviewsEnabled { get; set; } = true;
|
||||
|
||||
public bool GoogleAnalyticsEnabled { get; set; }
|
||||
|
||||
public string GoogleAnalyticsId { get; set; } = "";
|
||||
|
|
|
@ -61,7 +61,7 @@ public class User
|
|||
public int Comments {
|
||||
get {
|
||||
using Database database = new();
|
||||
return database.Comments.Count(c => c.TargetUserId == this.UserId);
|
||||
return database.Comments.Count(c => c.Type == CommentType.Profile && c.TargetId == this.UserId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ public class User
|
|||
LbpSerializer.StringElement("commentCount", this.Comments) +
|
||||
LbpSerializer.StringElement("photosByMeCount", this.PhotosByMe) +
|
||||
LbpSerializer.StringElement("photosWithMeCount", this.PhotosWithMe) +
|
||||
LbpSerializer.StringElement("commentsEnabled", "true") +
|
||||
LbpSerializer.StringElement("commentsEnabled", ServerSettings.Instance.ProfileCommentsEnabled) +
|
||||
LbpSerializer.StringElement("location", this.Location.Serialize()) +
|
||||
LbpSerializer.StringElement("favouriteSlotCount", this.HeartedLevels) +
|
||||
LbpSerializer.StringElement("favouriteUserCount", this.HeartedUsers) +
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue