Files
decePubClient/Models/ProfileForm.cs
T

101 lines
3.9 KiB
C#
Raw Normal View History

using decePubClient.Models.Mastodon;
using decePubClient.Models.Types;
namespace decePubClient.Models
{
/// <summary>
/// The persona's profile as Settings edits it, which is what update_credentials takes: the words as written (its
/// account's Source), the flags, the posting defaults, and a new avatar or header when one was picked. Fields always
/// holds FieldCount rows; a row without a name is dropped.
/// </summary>
public class ProfileForm
{
public const int FieldCount = 4;
public const int DisplayNameLength = 30;
public const int NoteLength = 500;
public const int FieldLength = 255;
public string DisplayName { get; set; }
public string Note { get; set; }
public bool Locked { get; set; }
public bool Bot { get; set; }
public bool Discoverable { get; set; }
public bool Indexable { get; set; }
public MessageType Privacy { get; set; } = MessageType.Public;
public bool Sensitive { get; set; }
public string Language { get; set; }
public QuotePolicy QuotePolicy { get; set; } = QuotePolicy.Public;
public List<AccountField> Fields { get; set; } = [];
public UploadMedia Avatar { get; set; }
public UploadMedia Header { get; set; }
public static ProfileForm Of(Account account)
{
var source = account.Source ?? new();
var fields = source.Fields.Count > 0 ? source.Fields : account.Fields;
return new()
{
DisplayName = account.DisplayName,
Note = source.Note,
Locked = account.Locked,
Bot = account.Bot,
Discoverable = account.Discoverable == true,
Indexable = account.Indexable == true,
Privacy = source.Privacy switch
{
"private" => MessageType.FollowersOnly,
"unlisted" => MessageType.Unlisted,
_ => MessageType.Public
},
Sensitive = source.Sensitive,
Language = source.Language,
QuotePolicy = source.QuotePolicy switch
{
"followers" => QuotePolicy.Followers,
"nobody" => QuotePolicy.Nobody,
_ => QuotePolicy.Public
},
Fields = [.. fields.Take(FieldCount).Select(f => new AccountField { Name = f.Name, Value = f.Value }),
.. Enumerable.Range(0, Math.Max(0, FieldCount - fields.Count)).Select(_ => new AccountField())]
};
}
/// <summary>The form as update_credentials reads it, with the pictures as files.</summary>
public MultipartFormDataContent Content()
{
var content = new MultipartFormDataContent
{
{ new StringContent(DisplayName?.Trim() ?? ""), "display_name" },
{ new StringContent(Note ?? ""), "note" },
{ new StringContent(Flag(Locked)), "locked" },
{ new StringContent(Flag(Bot)), "bot" },
{ new StringContent(Flag(Discoverable)), "discoverable" },
{ new StringContent(Flag(Indexable)), "indexable" },
{ new StringContent(Privacy switch { MessageType.FollowersOnly => "private", MessageType.Unlisted => "unlisted", _ => "public" }), "source[privacy]" },
{ new StringContent(Flag(Sensitive)), "source[sensitive]" },
{ new StringContent(Language ?? ""), "source[language]" },
{ new StringContent(QuotePolicy switch { QuotePolicy.Followers => "followers", QuotePolicy.Nobody => "nobody", _ => "public" }), "source[quote_policy]" }
};
// every row is sent, so a row emptied here is removed there
for (var i = 0; i < Fields.Count; i++)
{
content.Add(new StringContent(Fields[i].Name?.Trim() ?? ""), $"fields_attributes[{i}][name]");
content.Add(new StringContent(Fields[i].Value?.Trim() ?? ""), $"fields_attributes[{i}][value]");
}
if (Avatar is not null)
content.Add(Picture(Avatar), "avatar", Avatar.FileName);
if (Header is not null)
content.Add(Picture(Header), "header", Header.FileName);
return content;
}
static string Flag(bool value) => value ? "true" : "false";
static ByteArrayContent Picture(UploadMedia media)
{
var picture = new ByteArrayContent(media.Blob);
picture.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(media.ContentType);
return picture;
}
}
}