Build / Build (push) Successful in 56s
Settings gets "Notifications on this device" (PushEditor): personas, alerts in four groups, policy, a test
notification, after a one-time notice of what the push service learns. Each persona ticked gets its own service
worker registration (push-worker.js at push/{slot}/), so its own endpoint and keys, subscribed with its own token
(IHttpService's *As); nothing PrivaPub stores ties two personas together and the worker never reads the payload's
token. PushService follows the tokens (re-subscribing after a renewal), reconciles at every session start, turns
off before sign-out and drops deleted or suspended personas. A click opens that persona's notifications; the app
badge counts the unread ones. Exchanges now ask for the push scope.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WpVCoDeM1qUTRp4fXQdfof
98 lines
3.4 KiB
C#
98 lines
3.4 KiB
C#
namespace decePubClient.Models.Mastodon;
|
|
|
|
/// <summary>/api/v2/instance, the part the client reads: what the server calls itself and says of itself, its contact,
|
|
/// its rules, what an upload may be, and its Web Push key.</summary>
|
|
public class InstanceV2
|
|
{
|
|
public string Domain { get; set; }
|
|
public string Title { get; set; }
|
|
/// <summary>The short description, as plain text.</summary>
|
|
public string Description { get; set; }
|
|
public InstanceThumbnail Thumbnail { get; set; } = new();
|
|
public InstanceContact Contact { get; set; } = new();
|
|
public List<InstanceRule> Rules { get; set; } = [];
|
|
public InstanceConfiguration Configuration { get; set; } = new();
|
|
}
|
|
|
|
public class InstanceThumbnail
|
|
{
|
|
public string Url { get; set; }
|
|
}
|
|
|
|
/// <summary>Who answers for the server: an address, and the persona its administrator named (null when none).</summary>
|
|
public class InstanceContact
|
|
{
|
|
public string Email { get; set; }
|
|
public Account Account { get; set; }
|
|
}
|
|
|
|
/// <summary>One of the server's rules (/api/v1/instance/rules and the instance's own), in their order.</summary>
|
|
public class InstanceRule
|
|
{
|
|
public string Id { get; set; }
|
|
public string Text { get; set; }
|
|
public string Hint { get; set; }
|
|
}
|
|
|
|
public class InstanceConfiguration
|
|
{
|
|
public MediaConfiguration MediaAttachments { get; set; } = new();
|
|
public AccountsConfiguration Accounts { get; set; } = new();
|
|
public VapidConfiguration Vapid { get; set; } = new();
|
|
}
|
|
|
|
/// <summary>The server's VAPID public key (RFC 8292), the applicationServerKey a browser subscribes to Web Push with: the
|
|
/// uncompressed P-256 point, URL-safe base64. Null on a server that pushes nothing.</summary>
|
|
public class VapidConfiguration
|
|
{
|
|
public string PublicKey { get; set; }
|
|
}
|
|
|
|
/// <summary>What an account may hold: how many hashtags it features on its profile (PrivaPub's 10).</summary>
|
|
public class AccountsConfiguration
|
|
{
|
|
public int MaxFeaturedTags { get; set; }
|
|
}
|
|
|
|
/// <summary>The types an upload may have and how big it may be, as the server enforces them.</summary>
|
|
public class MediaConfiguration
|
|
{
|
|
public List<string> SupportedMimeTypes { get; set; } = [];
|
|
public long ImageSizeLimit { get; set; }
|
|
public long VideoSizeLimit { get; set; }
|
|
public long ImageMatrixLimit { get; set; }
|
|
public long VideoMatrixLimit { get; set; }
|
|
public int VideoFrameRateLimit { get; set; }
|
|
}
|
|
|
|
/// <summary>/api/v1/instance/extended_description and /privacy_policy: the server's text as sanitized HTML, and when it
|
|
/// last changed.</summary>
|
|
public class InstanceDocument
|
|
{
|
|
public DateTime? UpdatedAt { get; set; }
|
|
public string Content { get; set; }
|
|
}
|
|
|
|
/// <summary>/api/v1/instance/terms_of_service (Mastodon 4.4): the one version PrivaPub keeps; none while it has none
|
|
/// (404).</summary>
|
|
public class TermsOfService
|
|
{
|
|
/// <summary>yyyy-MM-dd.</summary>
|
|
public string EffectiveDate { get; set; }
|
|
/// <summary>Whether they apply already (false while their date is ahead).</summary>
|
|
public bool Effective { get; set; }
|
|
public string Content { get; set; }
|
|
public string SucceededBy { get; set; }
|
|
}
|
|
|
|
/// <summary>/api/v1/instance/domain_blocks: a block the administrator published; its domain partly starred when it is
|
|
/// obfuscated, its digest the SHA-256 of the whole name.</summary>
|
|
public class PublicDomainBlock
|
|
{
|
|
public string Domain { get; set; }
|
|
public string Digest { get; set; }
|
|
/// <summary>suspend, silence or noop.</summary>
|
|
public string Severity { get; set; }
|
|
public string Comment { get; set; }
|
|
}
|