namespace Uwaa.Pleroma; public class Notification : ASObject { /// /// The account that performed the action that generated the notification. /// [JsonPropertyName("account")] public Account Account { get; set; } = null!; [JsonPropertyName("created_at")] public DateTimeOffset CreatedAt { get; set; } /// /// Group key shared by similar notifications /// [JsonPropertyName("group_key")] public string GroupKey { get; set; } = null!; /// /// Status that was the object of the notification, e.g. in mentions, reblogs, favourites, or polls. /// [JsonPropertyName("status")] public Status? Status { get; set; } /// /// The type of event that resulted in the notification. /// [JsonPropertyName("type")] public NotificationType Type { get; set; } [JsonConstructor()] internal Notification() { } } [JsonConverter(typeof(NotificationIDConverter))] public readonly struct NotificationID(string id) : IEquatable { public static implicit operator NotificationID(string id) => new NotificationID(id); public static implicit operator NotificationID(Notification notification) => new NotificationID(notification.ID); public readonly string ID = id; public override string ToString() => ID; public static bool operator ==(NotificationID left, NotificationID right) => left.Equals(right); public static bool operator !=(NotificationID left, NotificationID right) => !(left == right); public override bool Equals(object? obj) => (obj is NotificationID id && Equals(id)) || (obj is Notification notification && Equals(notification)); public bool Equals(NotificationID other) => ID == other.ID; public override int GetHashCode() => ID.GetHashCode(); } class NotificationIDConverter : JsonConverter { public override bool CanConvert(Type type) => type.IsAssignableTo(typeof(NotificationID)); public override NotificationID Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return new NotificationID(reader.GetString() ?? throw new NullReferenceException("Expected a string, got null")); } public override void Write(Utf8JsonWriter writer, NotificationID value, JsonSerializerOptions options) { writer.WriteStringValue(value.ID); } } [JsonConverter(typeof(NotificationTypeConverter))] public enum NotificationType { Unknown, /// /// Someone followed you /// Follow, /// /// Someone mentioned you in their status /// Mention, /// /// Someone boosted one of your statuses /// Reblog, /// /// Someone favourited one of your statuses /// Favourite, /// /// A poll you have voted in or created has ended /// Poll, /// /// Someone moved their account /// Move, /// /// Someone reacted with emoji to your status /// EmojiReaction, /// /// Someone mentioned you in a chat message /// ChatMention, /// /// Someone was reported /// Report, /// /// Someone you are subscribed to created a status /// Status, /// /// A status you boosted has been edited /// Update, /// /// Someone signed up (optionally sent to admins) /// Admin_SignUp, /// /// A new report has been filed /// Admin_Report, } /// /// Helper functions for . /// public static class NotificationTypes { public static NotificationType Parse(string typeStr) { return typeStr switch { "follow" => NotificationType.Follow, "mention" => NotificationType.Mention, "reblog" => NotificationType.Reblog, "favourite" => NotificationType.Favourite, "poll" => NotificationType.Poll, "move" => NotificationType.Move, "pleroma:emoji_reaction" => NotificationType.EmojiReaction, "pleroma:chat_mention" => NotificationType.ChatMention, "pleroma:report" => NotificationType.Report, "status" => NotificationType.Status, "update" => NotificationType.Update, "admin.sign_up" => NotificationType.Admin_SignUp, "admin.report" => NotificationType.Admin_Report, _ => NotificationType.Unknown, }; } public static string ToString(this NotificationType type) { return type switch { NotificationType.Unknown => throw new NotImplementedException("Invalid notification type"), NotificationType.Follow => "follow", NotificationType.Mention => "mention", NotificationType.Reblog => "reblog", NotificationType.Favourite => "favourite", NotificationType.Poll => "poll", NotificationType.Move => "move", NotificationType.EmojiReaction => "pleroma:emoji_reaction", NotificationType.ChatMention => "pleroma:chat_mention", NotificationType.Report => "pleroma:report", NotificationType.Status => "status", NotificationType.Update => "update", NotificationType.Admin_SignUp => "admin.sign_up", NotificationType.Admin_Report => "admin.report", _ => throw new NotImplementedException("Unknown notification type"), }; } } /// /// Converts to and from enum values in lowercase. /// class NotificationTypeConverter : JsonConverter { public override bool CanConvert(Type typeToConvert) => typeToConvert.IsEnum; public override NotificationType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return NotificationTypes.Parse(reader.GetString() ?? throw new NullReferenceException("Expected a string, got null")); } public override void Write(Utf8JsonWriter writer, NotificationType value, JsonSerializerOptions options) { writer.WriteStringValue(NotificationTypes.ToString(value)); } }