The composer uploads each file as soon as it is attached (streamed from the browser file, under its own ten-minute
timeout), shows it uploading, processing (a 202 followed until ready), ready or failed with Retry, and cancels one
removed; publishing sends the ids, so a failed publish or a retried upload sends nothing twice. Size limits and types
come from /api/v2/instance, a file without a browser type gets one from its extension, and each refusal names the file
and why. Previews are 320 px thumbnails, not whole files in memory. A picture without a description is asked about once
("Publish anyway"; a setting turns it off), descriptions are sent with PUT, and an edit keeps the post's media, language
and sensitive flag.
Profile pictures are checked against the server's types and can be removed. A card shows "Media unavailable" with the
original's link when a picture fails, the blurhash behind a sensitive placeholder, and plays a GIF only on tap under
reduced motion. A failed export says so instead of downloading part of a file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
49 lines
1.6 KiB
C#
49 lines
1.6 KiB
C#
using System.ComponentModel;
|
|
using System.Text.Json.Serialization;
|
|
|
|
using Microsoft.AspNetCore.Components.Forms;
|
|
|
|
namespace decePubClient.Models;
|
|
|
|
public enum UploadState
|
|
{
|
|
Uploading,
|
|
Processing,
|
|
Ready,
|
|
Failed
|
|
}
|
|
|
|
/// <summary>
|
|
/// A file attached in the composer. It is uploaded as soon as it is picked, streamed from the browser's file (nothing of
|
|
/// it is kept but a small preview), and its id is kept, so a post that fails never sends it again.
|
|
/// </summary>
|
|
public class UploadMedia
|
|
{
|
|
public string ContentType { get; set; }
|
|
public string FileName { get; set; }
|
|
public string AltText { get; set; }
|
|
public long Size { get; set; }
|
|
|
|
[JsonIgnore, Bindable(false)]
|
|
public IBrowserFile File { get; set; }
|
|
/// <summary>A small picture of it (a thumbnail the browser made), or for media already posted its server's preview.</summary>
|
|
[JsonIgnore, Bindable(false)]
|
|
public string Preview { get; set; }
|
|
[JsonIgnore, Bindable(false)]
|
|
public UploadState State { get; set; }
|
|
[JsonIgnore, Bindable(false)]
|
|
public string Id { get; set; }
|
|
[JsonIgnore, Bindable(false)]
|
|
public string Error { get; set; }
|
|
/// <summary>The description the server holds: a different one is sent before the post.</summary>
|
|
[JsonIgnore, Bindable(false)]
|
|
public string SentAltText { get; set; }
|
|
/// <summary>Already on the post being edited: its description changes through the edit.</summary>
|
|
[JsonIgnore, Bindable(false)]
|
|
public bool Posted { get; set; }
|
|
[JsonIgnore, Bindable(false)]
|
|
public CancellationTokenSource Cancel { get; set; }
|
|
[JsonIgnore, Bindable(false)]
|
|
public Task Done { get; set; } = Task.CompletedTask;
|
|
}
|