pleroma: notifications
This commit is contained in:
parent
02ddd4c918
commit
5b8b31932d
2 changed files with 298 additions and 1 deletions
212
Pleroma/Models/Notification.cs
Normal file
212
Pleroma/Models/Notification.cs
Normal file
|
@ -0,0 +1,212 @@
|
|||
namespace Uwaa.Pleroma;
|
||||
|
||||
public class Notification : ASObject
|
||||
{
|
||||
/// <summary>
|
||||
/// The account that performed the action that generated the notification.
|
||||
/// </summary>
|
||||
[JsonPropertyName("account")]
|
||||
public Account Account { get; set; } = null!;
|
||||
|
||||
[JsonPropertyName("created_at")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Group key shared by similar notifications
|
||||
/// </summary>
|
||||
[JsonPropertyName("group_key")]
|
||||
public string GroupKey { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Status that was the object of the notification, e.g. in mentions, reblogs, favourites, or polls.
|
||||
/// </summary>
|
||||
[JsonPropertyName("status")]
|
||||
public Status? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of event that resulted in the notification.
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public NotificationType Type { get; set; }
|
||||
|
||||
[JsonConstructor()]
|
||||
internal Notification()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(NotificationIDConverter))]
|
||||
public readonly struct NotificationID(string id) : IEquatable<NotificationID>
|
||||
{
|
||||
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<NotificationID>
|
||||
{
|
||||
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,
|
||||
|
||||
/// <summary>
|
||||
/// Someone followed you
|
||||
/// </summary>
|
||||
Follow,
|
||||
|
||||
/// <summary>
|
||||
/// Someone mentioned you in their status
|
||||
/// </summary>
|
||||
Mention,
|
||||
|
||||
/// <summary>
|
||||
/// Someone boosted one of your statuses
|
||||
/// </summary>
|
||||
Reblog,
|
||||
|
||||
/// <summary>
|
||||
/// Someone favourited one of your statuses
|
||||
/// </summary>
|
||||
Favourite,
|
||||
|
||||
/// <summary>
|
||||
/// A poll you have voted in or created has ended
|
||||
/// </summary>
|
||||
Poll,
|
||||
|
||||
/// <summary>
|
||||
/// Someone moved their account
|
||||
/// </summary>
|
||||
Move,
|
||||
|
||||
/// <summary>
|
||||
/// Someone reacted with emoji to your status
|
||||
/// </summary>
|
||||
EmojiReaction,
|
||||
|
||||
/// <summary>
|
||||
/// Someone mentioned you in a chat message
|
||||
/// </summary>
|
||||
ChatMention,
|
||||
|
||||
/// <summary>
|
||||
/// Someone was reported
|
||||
/// </summary>
|
||||
Report,
|
||||
|
||||
/// <summary>
|
||||
/// Someone you are subscribed to created a status
|
||||
/// </summary>
|
||||
Status,
|
||||
|
||||
/// <summary>
|
||||
/// A status you boosted has been edited
|
||||
/// </summary>
|
||||
Update,
|
||||
|
||||
/// <summary>
|
||||
/// Someone signed up (optionally sent to admins)
|
||||
/// </summary>
|
||||
Admin_SignUp,
|
||||
|
||||
/// <summary>
|
||||
/// A new report has been filed
|
||||
/// </summary>
|
||||
Admin_Report,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper functions for <see cref="NotificationTypes"/>.
|
||||
/// </summary>
|
||||
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"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts to and from enum values in lowercase.
|
||||
/// </summary>
|
||||
class NotificationTypeConverter : JsonConverter<NotificationType>
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
|
@ -51,6 +51,11 @@ public class Pleroma
|
|||
HttpClient.DefaultRequestHeaders.Authorization = AuthenticationHeaderValue.Parse(authorization);
|
||||
}
|
||||
|
||||
Task Retry(Func<HttpRequestMessage> reqFactory)
|
||||
{
|
||||
return Retry<object?>(reqFactory);
|
||||
}
|
||||
|
||||
async Task<T?> Retry<T>(Func<HttpRequestMessage> reqFactory)
|
||||
{
|
||||
while (true)
|
||||
|
@ -61,7 +66,12 @@ public class Pleroma
|
|||
return default;
|
||||
|
||||
if (res.Content == null)
|
||||
throw new HttpRequestException("Server responded with no content");
|
||||
{
|
||||
if (typeof(T) == typeof(object))
|
||||
return default;
|
||||
else
|
||||
throw new HttpRequestException("Server responded with no content");
|
||||
}
|
||||
|
||||
string text = await res.Content.ReadAsStringAsync();
|
||||
|
||||
|
@ -604,4 +614,79 @@ public class Pleroma
|
|||
if (limit != 20) addPair("limit", limit.ToString());
|
||||
})))!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifications concerning the user. This API returns Link headers containing links to the next/previous page. However, the links can also be constructed dynamically using query params and <c>id</c> values.
|
||||
/// </summary>
|
||||
/// <param name="max_id">Return items older than this ID</param>
|
||||
/// <param name="min_id">Return the oldest items newer than this ID</param>
|
||||
/// <param name="since_id">Return the newest items newer than this ID</param>
|
||||
/// <param name="offset">Return items past this number of items</param>
|
||||
/// <param name="limit">Maximum number of items to return. Will be ignored if it's more than 40</param>
|
||||
public Task<Notification[]> GetNotifications(NotificationType[]? exclude_types = null,
|
||||
string? account_id = null,
|
||||
StatusVisibility[]? exclude_visibilities = null,
|
||||
NotificationType[]? types = null,
|
||||
bool with_muted = false,
|
||||
string? max_id = null,
|
||||
string? min_id = null,
|
||||
string? since_id = null,
|
||||
int offset = 0,
|
||||
int limit = 20)
|
||||
{
|
||||
return Retry<Notification[]>(() => new HttpRequestMessage(HttpMethod.Get, "/api/v1/notifications" + CreateQuery(addPair =>
|
||||
{
|
||||
if (exclude_types != null)
|
||||
foreach (NotificationType type in exclude_types)
|
||||
addPair("exclude_types[]", NotificationTypes.ToString(type));
|
||||
|
||||
if (account_id != null) addPair("account_id", account_id);
|
||||
|
||||
if (exclude_visibilities != null)
|
||||
foreach (StatusVisibility visibility in exclude_visibilities)
|
||||
addPair("exclude_visibilities[]", visibility.ToString().ToLowerInvariant());
|
||||
|
||||
if (types != null)
|
||||
foreach (NotificationType type in types)
|
||||
addPair("types[]", NotificationTypes.ToString(type));
|
||||
|
||||
if (with_muted) addPair("with_muted", "true");
|
||||
if (max_id != null) addPair("max_id", max_id);
|
||||
if (min_id != null) addPair("min_id", min_id);
|
||||
if (since_id != null) addPair("since_id", since_id);
|
||||
if (offset > 0) addPair("offset", offset.ToString());
|
||||
if (limit != 20) addPair("limit", limit.ToString());
|
||||
})))!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// View information about a notification with a given ID.
|
||||
/// </summary>
|
||||
/// <param name="id">Notification ID</param>
|
||||
public Task<Notification?> GetNotification(NotificationID id)
|
||||
{
|
||||
return Retry<Notification?>(() => new HttpRequestMessage(HttpMethod.Get, $"/api/v1/notifications/{id}"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear a single notification from the server.
|
||||
/// </summary>
|
||||
/// <param name="notification">Notification ID</param>
|
||||
public Task Dismiss(NotificationID notification)
|
||||
{
|
||||
return Retry(() => new HttpRequestMessage(HttpMethod.Post, $"/api/v1/notifications/{notification}/dismiss"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears multiple notifications from the server.
|
||||
/// </summary>
|
||||
/// <param name="notifications">Array of notification IDs to dismiss</param>
|
||||
public Task Dismiss(NotificationID[] notifications)
|
||||
{
|
||||
return Retry(() => new HttpRequestMessage(HttpMethod.Delete, $"/api/v1/notifications/destroy_multiple" + CreateQuery(addPair =>
|
||||
{
|
||||
foreach (NotificationID id in notifications)
|
||||
addPair("ids[]", id.ID);
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue