ProjectLighthouse/ProjectLighthouse.Servers.Website/Pages/NotificationsPage.cshtml.cs
sudokoko aea66b4a74
Implement in-game and website notifications (#932)
* Implement notifications logic, basic calls, and admin command

* Remove unnecessary code

* Add ability to stack notifications and return manually created XML

* Remove test that is no longer needed and is causing failures

* Apply suggestions from code review

* Merge notifications with existing announcements page

* Order notifications by descending ID instead of ascending ID

* Move notification send task to moderation options under user

Also restyles the buttons to line up next to each other like in the slot pages.

* Style/position fixes with granted slots/notification partials

* Fix incorrect form POST route

* Prevent notification text area from breaking out of container

* Actually use builder result for notification text

* Minor restructuring of the notifications page

* Add notifications for team picks, publish issues, and moderation

* Mark notifications as dismissed instead of deleting them

* Add XMLdoc to SendNotification method

* Fix incorrect URL in announcements webhook

* Remove unnecessary inline style from granted slots partial

* Apply suggestions from code review

* Apply first batch of suggestions from code review

* Apply second batch of suggestions from code review

* Change notification icon depending on if user has unread notifications

* Show unread notification icon if there is an announcement posted

* Remove "potential" wording from definitive fixes in error docs

* Remove "Error code:" from publish notifications

* Send notification if user tries to unlock a mod-locked level

* Change notification timestamp format to include date

* Add clarification to level mod-lock notification message

* Change team pick notifications to moderation notifications

Apparently the MMPick type doesn't show a visual notification.

* Apply suggestions from code review

* Add obsolete to notification types that display nothing in-game

* Remove unused imports and remove icon switch case in favor of bell icon

* Last minute fixes

* Send notification upon earth wipe and clarify moderation case notifications

* Add check for empty/too long notification text
2023-10-29 20:27:41 +00:00

112 lines
No EOL
3.8 KiB
C#

using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
using LBPUnion.ProjectLighthouse.Types.Entities.Notifications;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Website;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages;
public class NotificationsPage : BaseLayout
{
public NotificationsPage(DatabaseContext database) : base(database)
{ }
public List<WebsiteAnnouncementEntity> Announcements { get; set; } = new();
public List<NotificationEntity> Notifications { get; set; } = new();
public string Error { get; set; } = "";
public async Task<IActionResult> OnGet()
{
this.Announcements = await this.Database.WebsiteAnnouncements
.Include(a => a.Publisher)
.OrderByDescending(a => a.AnnouncementId)
.ToListAsync();
if (this.User == null) return this.Page();
this.Notifications = await this.Database.Notifications
.Where(n => n.UserId == this.User.UserId)
.Where(n => !n.IsDismissed)
.OrderByDescending(n => n.Id)
.ToListAsync();
return this.Page();
}
public async Task<IActionResult> OnPost([FromForm] string title, [FromForm] string content)
{
UserEntity? user = this.Database.UserFromWebRequest(this.Request);
if (user == null) return this.BadRequest();
if (!user.IsAdmin) return this.BadRequest();
if (string.IsNullOrWhiteSpace(title) || string.IsNullOrWhiteSpace(content))
{
this.Error = "Invalid form data, please ensure all fields are filled out.";
return this.Page();
}
WebsiteAnnouncementEntity announcement = new()
{
Title = title.Trim(),
Content = content.Trim(),
PublisherId = user.UserId,
};
this.Database.WebsiteAnnouncements.Add(announcement);
await this.Database.SaveChangesAsync();
if (!DiscordConfiguration.Instance.DiscordIntegrationEnabled) return this.RedirectToPage();
string truncatedAnnouncement = content.Length > 250
? content[..250] + $"... [read more]({ServerConfiguration.Instance.ExternalUrl}/notifications)"
: content;
await WebhookHelper.SendWebhook($":mega: {title}", truncatedAnnouncement);
return this.RedirectToPage();
}
public async Task<IActionResult> OnPostDelete(string type, int id)
{
UserEntity? user = this.Database.UserFromWebRequest(this.Request);
if (user == null) return this.BadRequest();
switch (type)
{
case "announcement":
{
WebsiteAnnouncementEntity? announcement = await this.Database.WebsiteAnnouncements
.Where(a => a.AnnouncementId == id)
.FirstOrDefaultAsync();
if (announcement == null || !user.IsAdmin) return this.BadRequest();
this.Database.WebsiteAnnouncements.Remove(announcement);
await this.Database.SaveChangesAsync();
break;
}
case "notification":
{
NotificationEntity? notification = await this.Database.Notifications
.Where(n => n.Id == id)
.Where(n => !n.IsDismissed)
.FirstOrDefaultAsync();
if (notification == null || notification.UserId != user.UserId) return this.BadRequest();
notification.IsDismissed = true;
await this.Database.SaveChangesAsync();
break;
}
}
return this.RedirectToPage();
}
}