204 lines
No EOL
5.7 KiB
C#
204 lines
No EOL
5.7 KiB
C#
namespace Uwaa.Pleroma;
|
|
|
|
public class Status
|
|
{
|
|
/// <summary>
|
|
/// Pleroma uses 128-bit ids as opposed to Mastodon's 64 bits. However just like Mastodon's ids they are lexically sortable strings
|
|
/// </summary>
|
|
[JsonPropertyName("id")]
|
|
public string ID { get; set; } = null!;
|
|
|
|
/// <summary>
|
|
/// HTML-encoded status content
|
|
/// </summary>
|
|
[JsonPropertyName("content")]
|
|
public string HtmlContent { get; set; } = null!;
|
|
|
|
/// <summary>
|
|
/// The account that authored this status
|
|
/// </summary>
|
|
[JsonPropertyName("account")]
|
|
public Account Account { get; set; } = null!;
|
|
|
|
/// <summary>
|
|
/// The date when this status was created
|
|
/// </summary>
|
|
[JsonPropertyName("created_at")]
|
|
public DateTime CreatedAt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Have you favourited this status?
|
|
/// </summary>
|
|
[JsonPropertyName("favourited")]
|
|
public bool Favourited { get; set; }
|
|
|
|
/// <summary>
|
|
/// How many favourites this status has received
|
|
/// </summary>
|
|
[JsonPropertyName("favourites_count")]
|
|
public int FavouriteCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// ID of the account being replied to
|
|
/// </summary>
|
|
[JsonPropertyName("in_reply_to_account_id")]
|
|
public string? ReplyToAccount { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// ID of the status being replied
|
|
/// </summary>
|
|
[JsonPropertyName("in_reply_to_id")]
|
|
public string? ReplyTo { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// Primary language of this status
|
|
/// </summary>
|
|
[JsonPropertyName("language")]
|
|
public string? Language { get; set; }
|
|
|
|
/// <summary>
|
|
/// Media that is attached to this status
|
|
/// </summary>
|
|
[JsonPropertyName("media_attachments")]
|
|
public Attachment[] Attachments { get; set; } = Array.Empty<Attachment>();
|
|
|
|
/// <summary>
|
|
/// Mentions of users within the status content
|
|
/// </summary>
|
|
[JsonPropertyName("mentions")]
|
|
public Mention[] Mentions { get; set; } = Array.Empty<Mention>();
|
|
|
|
/// <summary>
|
|
/// Have you pinned this status? Only appears if the status is pinnable.
|
|
/// </summary>
|
|
[JsonPropertyName("pinned")]
|
|
public bool Pinned { get; set; }
|
|
|
|
/// <summary>
|
|
/// Additional pleroma-specific data.
|
|
/// </summary>
|
|
[JsonPropertyName("pleroma")]
|
|
public PleromaStatusData Pleroma { get; set; } = null!;
|
|
|
|
/// <summary>
|
|
/// The status being reblogged
|
|
/// </summary>
|
|
[JsonPropertyName("reblog")]
|
|
public Status? Reblog { get; set; }
|
|
|
|
/// <summary>
|
|
/// Have you boosted this status?
|
|
/// </summary>
|
|
[JsonPropertyName("reblogged")]
|
|
public bool Reblogged { get; set; }
|
|
|
|
/// <summary>
|
|
/// How many boosts this status has received
|
|
/// </summary>
|
|
[JsonPropertyName("reblogs_count")]
|
|
public int ReblogCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// How many replies this status has received
|
|
/// </summary>
|
|
[JsonPropertyName("replies_count")]
|
|
public int ReplyCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Is this status marked as sensitive content?
|
|
/// </summary>
|
|
[JsonPropertyName("sensitive")]
|
|
public bool Sensitive { get; set; }
|
|
|
|
/// <summary>
|
|
/// Subject or summary line, below which status content is collapsed until expanded
|
|
/// </summary>
|
|
[JsonPropertyName("spoiler_text")]
|
|
public string SpoilerText { get; set; } = null!;
|
|
|
|
/// <summary>
|
|
/// Hashtags included in the status.
|
|
/// </summary>
|
|
[JsonPropertyName("tags")]
|
|
public Hashtag[] Tags { get; set; } = Array.Empty<Hashtag>();
|
|
|
|
/// <summary>
|
|
/// URI of the status used for federation
|
|
/// </summary>
|
|
[JsonPropertyName("uri")]
|
|
public string URI { get; set; } = null!;
|
|
|
|
/// <summary>
|
|
/// A link to the status's HTML representation
|
|
/// </summary>
|
|
[JsonPropertyName("url")]
|
|
public string? URL { get; set; }
|
|
|
|
/// <summary>
|
|
/// Visibility of this status
|
|
/// </summary>
|
|
[JsonPropertyName("visibility")]
|
|
public StatusVisibility Visibility { get; set; }
|
|
|
|
/// <summary>
|
|
/// Plain text content of that status.
|
|
/// </summary>
|
|
[JsonIgnore]
|
|
public string Content => Pleroma?.Content?.Plain ?? HtmlContent;
|
|
|
|
/// <summary>
|
|
/// Returns true if a status mentions or replies to a user.
|
|
/// </summary>
|
|
/// <param name="id">The ID of the user.</param>
|
|
public bool IsInteracting(string id)
|
|
{
|
|
return ReplyToAccount == id || Mentions.Any(m => m.ID == id);
|
|
}
|
|
|
|
public override string ToString() => $"{Account?.Username ?? "unknown"}: \"{Content}\"";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Additional pleroma-specific data for a <see cref="Status"/>.
|
|
/// </summary>
|
|
public class PleromaStatusData
|
|
{
|
|
[JsonPropertyName("content")]
|
|
public Content Content { get; set; } = null!;
|
|
|
|
[JsonPropertyName("local")]
|
|
public bool Local { get; set; }
|
|
}
|
|
|
|
public class Content
|
|
{
|
|
[JsonPropertyName("text/plain")]
|
|
public string Plain { get; set; } = null!;
|
|
}
|
|
|
|
[JsonConverter(typeof(StatusIDConverter))]
|
|
public readonly struct StatusID(string id)
|
|
{
|
|
public static implicit operator StatusID(string id) => new StatusID(id);
|
|
|
|
public static implicit operator StatusID(Status status) => new StatusID(status.ID);
|
|
|
|
public readonly string ID = id;
|
|
|
|
public override string ToString() => ID;
|
|
}
|
|
|
|
class StatusIDConverter : JsonConverter<StatusID>
|
|
{
|
|
public override bool CanConvert(Type type) => type.IsAssignableTo(typeof(StatusID));
|
|
|
|
public override StatusID Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
{
|
|
return new StatusID(reader.GetString() ?? throw new NullReferenceException("Expected a string, got null"));
|
|
}
|
|
|
|
public override void Write(Utf8JsonWriter writer, StatusID value, JsonSerializerOptions options)
|
|
{
|
|
writer.WriteStringValue(value.ID);
|
|
}
|
|
} |