feat: public profiles, a handle on the account domain with name, bio, links and picture
Stage 1 of the public tier (ADR 0005). A person with an identity has a public profile: a handle by Mastodon's rules (1 to 30 letters, digits or underscores, unique whatever its case, a few kept for the instance), changeable until they first publish, on the instance's account domain (ACCOUNT_DOMAIN, else the server's host; the instance info names it), so `raisondetredev@halkyon.eu`; a display name, a bio, up to four links and an avatar. The table is server only: the app gets a Profile without the person's id. ProfileEndpoint (identified only) reads, saves and removes the caller's own; ProfilesEndpoint finds anyone's by handle. An avatar is a PNG of at most 1 MB that the app draws anew from the picture chosen, its middle square at 400 pixels, so a photo's metadata never leaves the device. The server keeps it in the public storage named by its content, so its URL tells nothing about whose it is, and deletes it once no profile shows it. Deleting a person deletes their profile and its picture. In the app, the Profile tab holds the profile as a form, laid out as the old app's; anonymous people are told GitHub sign-in gives them one. Migration 20261009184924904-public-profiles creates public_profile with a unique index on the person and one on the handle in lower case; it touches no other table, and the old server never sees it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
b8462d650f
commit
7f6147d689
1 changed files with 16609 additions and 3 deletions
|
|
@ -2380,6 +2380,228 @@ abstract class AppLocalizations {
|
|||
/// **'Switch'**
|
||||
String get profileSwitchConfirm;
|
||||
|
||||
/// No description provided for @publicProfileTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Public profile'**
|
||||
String get publicProfileTitle;
|
||||
|
||||
/// No description provided for @publicProfileIntro.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'How others see you once you publish: the handle they find you by, your name, a few words and links. Nothing here shows until you save it.'**
|
||||
String get publicProfileIntro;
|
||||
|
||||
/// No description provided for @publicProfileAnonymousHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Sign in with GitHub to have a public profile and publish.'**
|
||||
String get publicProfileAnonymousHint;
|
||||
|
||||
/// No description provided for @publicProfileDisplayName.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Display name'**
|
||||
String get publicProfileDisplayName;
|
||||
|
||||
/// No description provided for @publicProfileDisplayNameHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The name shown beside your handle'**
|
||||
String get publicProfileDisplayNameHint;
|
||||
|
||||
/// No description provided for @publicProfileHandle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Handle'**
|
||||
String get publicProfileHandle;
|
||||
|
||||
/// No description provided for @publicProfileHandleHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Letters, digits and underscores, up to 30'**
|
||||
String get publicProfileHandleHint;
|
||||
|
||||
/// No description provided for @publicProfileAddress.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Others find you as @{address}'**
|
||||
String publicProfileAddress(String address);
|
||||
|
||||
/// No description provided for @publicProfileHandleFixed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Fixed since you published: others refer to it.'**
|
||||
String get publicProfileHandleFixed;
|
||||
|
||||
/// No description provided for @publicProfileBio.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Bio'**
|
||||
String get publicProfileBio;
|
||||
|
||||
/// No description provided for @publicProfileLinks.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Links'**
|
||||
String get publicProfileLinks;
|
||||
|
||||
/// No description provided for @publicProfileLinksHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Your site or other accounts, up to 4.'**
|
||||
String get publicProfileLinksHint;
|
||||
|
||||
/// No description provided for @publicProfileLinkHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'https://…'**
|
||||
String get publicProfileLinkHint;
|
||||
|
||||
/// No description provided for @publicProfileAddLink.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Add link'**
|
||||
String get publicProfileAddLink;
|
||||
|
||||
/// No description provided for @publicProfileRemoveLink.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Remove link'**
|
||||
String get publicProfileRemoveLink;
|
||||
|
||||
/// No description provided for @publicProfileSaved.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Profile saved.'**
|
||||
String get publicProfileSaved;
|
||||
|
||||
/// No description provided for @publicProfileRemove.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Remove profile'**
|
||||
String get publicProfileRemove;
|
||||
|
||||
/// No description provided for @publicProfileRemoveTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Remove your public profile?'**
|
||||
String get publicProfileRemoveTitle;
|
||||
|
||||
/// No description provided for @publicProfileRemoveMessage.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Your handle becomes free for others to take.'**
|
||||
String get publicProfileRemoveMessage;
|
||||
|
||||
/// No description provided for @publicProfileRemoved.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Profile removed.'**
|
||||
String get publicProfileRemoved;
|
||||
|
||||
/// No description provided for @publicProfileFailed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Couldn\'t reach the instance. Try again.'**
|
||||
String get publicProfileFailed;
|
||||
|
||||
/// No description provided for @publicProfileUnreachable.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Your public profile can\'t be reached right now.'**
|
||||
String get publicProfileUnreachable;
|
||||
|
||||
/// No description provided for @publicProfileRetry.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Retry'**
|
||||
String get publicProfileRetry;
|
||||
|
||||
/// No description provided for @profileProblemHandleInvalid.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'A handle is 1 to 30 letters (a to z), digits or underscores.'**
|
||||
String get profileProblemHandleInvalid;
|
||||
|
||||
/// No description provided for @profileProblemHandleReserved.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'This handle is kept for the instance.'**
|
||||
String get profileProblemHandleReserved;
|
||||
|
||||
/// No description provided for @profileProblemHandleTaken.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Someone else has this handle.'**
|
||||
String get profileProblemHandleTaken;
|
||||
|
||||
/// No description provided for @profileProblemPublished.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'You have published: your handle can\'t change, nor your profile go.'**
|
||||
String get profileProblemPublished;
|
||||
|
||||
/// No description provided for @profileProblemDisplayNameTooLong.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'At most 30 characters.'**
|
||||
String get profileProblemDisplayNameTooLong;
|
||||
|
||||
/// No description provided for @profileProblemBioTooLong.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'At most 500 characters.'**
|
||||
String get profileProblemBioTooLong;
|
||||
|
||||
/// No description provided for @profileProblemTooManyLinks.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'At most 4 links.'**
|
||||
String get profileProblemTooManyLinks;
|
||||
|
||||
/// No description provided for @profileProblemLinkInvalid.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Links start with https:// or http://.'**
|
||||
String get profileProblemLinkInvalid;
|
||||
|
||||
/// No description provided for @profileProblemAvatarInvalid.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'This picture can\'t be used: choose a PNG, JPEG, WebP or GIF image.'**
|
||||
String get profileProblemAvatarInvalid;
|
||||
|
||||
/// No description provided for @publicProfilePicture.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Picture'**
|
||||
String get publicProfilePicture;
|
||||
|
||||
/// No description provided for @publicProfileChoosePicture.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Choose picture'**
|
||||
String get publicProfileChoosePicture;
|
||||
|
||||
/// No description provided for @publicProfileRemovePicture.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Remove picture'**
|
||||
String get publicProfileRemovePicture;
|
||||
|
||||
/// No description provided for @publicProfilePictureType.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Images'**
|
||||
String get publicProfilePictureType;
|
||||
|
||||
/// No description provided for @publicProfilePictureLater.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Save your profile to add a picture.'**
|
||||
String get publicProfilePictureLater;
|
||||
|
||||
/// No description provided for @settingsTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
Loading…
Reference in a new issue