R5 the server's own settings in decePub: instance, rules, announcements, relays, media limits, the staff's log, About
Build / Build (push) Successful in 1m5s
Build / Build (push) Successful in 1m5s
Administration's Pleroma placeholders give way to real sections: Instance (title, descriptions, contact, thumbnail, privacy policy, terms, the weekly activity), Rules, Announcements, Relays, Media limits and the Moderation log, next to Reports, blocked servers (now published or obfuscated), statistics and backups; moderators see Reports and the log. Every save sends the whole settings form built from the latest read, since PrivaPub replaces what it carries. /about shows the server's documents to anyone. The report dialog picks the rules a violation breaks, and reports show them. Announcements show above the feed tabs, dismissed and reacted to, live from the user stream. Login names the server. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WpVCoDeM1qUTRp4fXQdfof
This commit is contained in:
1 parent
b8d7858acb
commit
4c88980374
33 files changed
+3743
-239
No files matched your search
@@ -160,7 +160,8 @@ Below `md` the app is laid out for a phone, and a touch screen gets thumb-sized
|
||||
- No history entries are pushed.
|
||||
- **What can't be undone asks first** through `Services/ConfirmService.cs` (`Ask`, shown by `ConfirmHost` in
|
||||
`MainLayout`): deleting a post, taking it off a wall, muting, blocking, removing a follower, revoking a quote, leaving a
|
||||
group, dropping a scheduled post and signing out.
|
||||
group, dropping a scheduled post, signing out, and for an administrator deleting an announcement and removing the
|
||||
server's thumbnail.
|
||||
- **On a touch screen:**
|
||||
- a tap on a post opens its thread (`main.js`, `data-thread` on the card, its `data-thread-link`), and cards are
|
||||
pinned to the globe with a mouse only;
|
||||
@@ -297,8 +298,11 @@ Never redeclare the base's members in a component.
|
||||
persona's lists and their members; members are only accounts it follows, found with `accounts/search?following=true`),
|
||||
`FilterService` (the persona's v2 filters, their keywords and filtered posts), `DiscoveryService` (hashtags and
|
||||
following them, trends, the directory), `PortabilityService` (Mastodon's CSV exports and imports), `AdminService`
|
||||
(`/clientapi/moderator` and `/clientapi/admin`), `MediaService` (uploads, and deleting those no post holds),
|
||||
`GroupService`, `InstanceService` and
|
||||
(`/clientapi/moderator`, the staff's log among it, and `/clientapi/admin`'s blocks, statistics and backups),
|
||||
`InstanceAdminService` (the server's own settings, thumbnail, announcements and relays: PrivaPub's
|
||||
`InstanceAdminController`), `AboutService` (what the server says of itself to anyone: the instance API, its documents
|
||||
and published domain blocks, never with credentials), `AnnouncementService` (`/api/v1/announcements`: dismissing and
|
||||
reacting), `MediaService` (uploads, and deleting those no post holds), `GroupService`, `InstanceService` and
|
||||
`ProvenanceService`.
|
||||
- **Reactions and votes are public** (owner decision, PrivaPub's ROADMAP): before a persona's first reaction, poll vote
|
||||
or downvote, `PublicNoticeService` asks it once (`PublicNoticeHost` in `MainLayout`) and remembers the persona in
|
||||
@@ -317,6 +321,14 @@ Never redeclare the base's members in a component.
|
||||
sensitive-media button), a picture's focal point (`object-position`), and an event's online link, participants and
|
||||
status. A picture, video or sound that fails to load says "Media unavailable" with "Open original"
|
||||
(`data-media-unavailable`), and a gifv plays only on a tap under `prefers-reduced-motion`.
|
||||
- **About** (`Pages/About.razor` at `/about`, no sign-in, `data-about`; linked from NavMenu as `data-nav-about` and from
|
||||
Login as `data-about-offer`): the server's name (`data-about-title`), short description and thumbnail, its long
|
||||
description (`data-about-description`, `/api/v1/instance/extended_description`), contact (`data-about-contact`), rules
|
||||
(`data-about-rules`, `data-about-rule`), privacy policy (`data-about-privacy`), terms of service (`data-about-terms`,
|
||||
none while PrivaPub answers 404) and the domain blocks the administrator published (`data-about-blocks`,
|
||||
`data-about-block`, an obfuscated one partly starred as PrivaPub gives it). The documents are PrivaPub's sanitized
|
||||
HTML in `post-content doc-content` (`Styles/feed.css` spaces their headings). Login's heading names the server
|
||||
(`data-login-title`, `/api/v2/instance` read without credentials and kept for the session).
|
||||
- **Profiles and search** (`Pages/Profile.razor` at `/account/{id}`, `Pages/Search.razor` at `/search?q=`): a card's
|
||||
author and a notification's account open the profile in the app; "Open original" is the only way to the remote site.
|
||||
A profile shows the posts the account pins above its posts (`pinned=true`: what an account elsewhere features); the
|
||||
@@ -324,7 +336,9 @@ Never redeclare the base's members in a component.
|
||||
An account that moved says where to (`Account.Moved`, which PrivaPub fills once the new account names the old one),
|
||||
linking the new account's profile.
|
||||
Another's profile and posts can be reported (`Components/ReportDialog.razor`, `/api/v1/reports`): a category, words,
|
||||
and for a remote account a copy to its server, which PrivaPub sends from its own actor, never naming the persona.
|
||||
and for a remote account a copy to its server, which PrivaPub sends from its own actor, never naming the persona. A
|
||||
violation (`ReportCategory.Violation`, offered while the server has rules) ticks the server's rules it breaks
|
||||
(`/api/v1/instance/rules`, sent as `rule_ids`; `data-report-rules`, a checkbox `data-report-rule="{id}"` each).
|
||||
Who liked or boosted a post opens from its card's menu (`Components/InteractedByDialog.razor`).
|
||||
On the persona's own profile its counts are buttons (`data-profile-following`, `data-profile-followers`) opening the
|
||||
accounts it follows and its followers (`Components/AccountListDialog.razor`, 40 a page by the Link header): PrivaPub
|
||||
@@ -412,9 +426,56 @@ Never redeclare the base's members in a component.
|
||||
PrivaPub in Mastodon's layout and downloaded through a link; and an archive (its own, or Mastodon's) uploaded in pieces
|
||||
by `js/transfer.js` and imported into it, the parts chosen (likes, located and scheduled posts off unless ticked),
|
||||
with progress, a report and Stop. Imported posts are delivered to no one.
|
||||
- **Administration** (`Pages/Administration.razor`, `Components/Admin/`, for moderators): reports, then for
|
||||
administrators the servers blocked for everyone, the federation statistics and the backups. PrivaPub has no admin list
|
||||
of users, and adding an admin endpoint waits for the owner, so the Users section stays empty.
|
||||
- **Administration** (`Pages/Administration.razor`, `Components/Admin/`): each section is a `DCollapse` marked
|
||||
`data-admin-section`, and its panel loads when the page opens. Moderators see Reports (`reports`) and the Moderation
|
||||
log (`log`); administrators also see Instance (`instance`), Rules (`rules`), Announcements (`announcements`),
|
||||
Blocked servers (`blocks`), Relays (`relays`), Media limits (`media`), Statistics (`statistics`) and Backups
|
||||
(`backups`). PrivaPub checks the role on every call (moderators: `/clientapi/moderator`, administrators:
|
||||
`/clientapi/admin`, checked against its database too). Users & personas come with R6, custom emoji with R7: until
|
||||
then they have no section.
|
||||
- **The settings save whole.** `POST /clientapi/admin/settings` replaces everything `ServerSettingsForm` carries (a rule
|
||||
left out is removed), so Instance, Rules and Media limits each save through `InstanceAdminService.SaveSettings`: it
|
||||
reads the settings PrivaPub has now, builds the form from them (`FormOf`: the rules not deleted, in order, the media
|
||||
overrides, every text), lets the panel set the fields the administrator changed there (the others keep what PrivaPub
|
||||
has, whoever saved it meanwhile), posts the whole form, and the panel shows what PrivaPub answers. A save also makes
|
||||
`AboutService` read the instance again.
|
||||
- **Instance** (`InstancePanel`, `data-instance`): the server's name (`data-instance-title`), short description
|
||||
(`data-instance-short-description`), Markdown description (`data-instance-description`), contact address
|
||||
(`data-instance-email`) and contact persona (`data-instance-contact`, removed with `data-instance-contact-remove`;
|
||||
picked from `data-instance-contact-option` buttons: the administrator's own personas, or this server's accounts as
|
||||
`data-instance-contact-search` finds them through `/api/v2/search`, a local account's `acct` having no host), privacy
|
||||
policy (`data-instance-privacy`), terms (`data-instance-terms`, their date `data-instance-terms-date`), and whether the
|
||||
weekly activity is published (`data-instance-publish-activity`, off by default, with why). Registrations are the
|
||||
configuration's and only shown (`data-instance-registrations`). `data-instance-save`, `data-instance-reset`. The
|
||||
thumbnail (`data-instance-thumbnail`, a file input; `data-instance-thumbnail-image`, `data-instance-thumbnail-remove`,
|
||||
asked first) is saved as soon as it is picked, streamed from the file as multipart `file`.
|
||||
- **Rules** (`RulesPanel`, `data-rules`): one row a rule (`data-rule="{position}"`, `data-rule-id`, its
|
||||
`data-rule-text` and `data-rule-hint`, `data-rule-up`, `data-rule-down`, `data-rule-delete`), `data-rule-add`,
|
||||
`data-rule-save`, `data-rule-reset`. A removed rule is kept (old reports name it) and listed greyed
|
||||
(`data-rule-deleted="{id}"`); `data-rule-restore` lists it again with its id.
|
||||
- **Announcements** (`AnnouncementsPanel`, `data-announcements`): each (`data-announcement="{id}"`,
|
||||
`data-announcement-state` shown, ended or draft) with its HTML, times, `data-announcement-reads` and reactions;
|
||||
`data-announcement-new` and `data-announcement-edit` open `data-announcement-dialog` (`data-announcement-text`,
|
||||
`-starts`, `-ends` as datetime-local in the reader's time, `-all-day`, `-published`, `-save`, `-cancel`);
|
||||
`data-announcement-delete` asks first.
|
||||
- **Blocked servers** (`ServerBlocksPanel`, `data-server-blocks`): a block is published on About and
|
||||
`/api/v1/instance/domain_blocks` only when asked (`data-server-block-published`; `data-server-block-obfuscate` stars
|
||||
part of its name), since that tells the blocked server and everyone; `data-server-block-edit` fills the form with a
|
||||
block, since blocking a server again changes its block. `data-server-block-save`.
|
||||
- **Relays** (`RelaysPanel`, `data-relays`): each (`data-relay="{address}"`, `data-relay-state`, `data-relay-source`
|
||||
configuration or settings; `data-relay-remove` for the settings' ones: a configured one is removed only from
|
||||
`Federation:Relays`, and PrivaPub answers 409), added by `data-relay-address` and `data-relay-add`. PrivaPub answers
|
||||
202 and subscribes in the background, so the panel reads the list again after 4 and 15 seconds.
|
||||
- **Media limits** (`MediaLimitsPanel`, `data-media-limits`): `data-media-limit="quota|image|video|seconds"` rows,
|
||||
inputs `data-media-quota`, `-image`, `-video` (megabytes) and `-seconds`, empty for the configured value, beside the
|
||||
configured and the effective values (`data-media-effective`) and the hard caps as maxima; `data-media-save`,
|
||||
`data-media-reset`, `data-media-use-configured`. What was set stays to the byte while its megabytes are not changed.
|
||||
- **Moderation log** (`ModerationLogPanel`, `data-log`, `/clientapi/moderator/log`): newest first, 50 at a time
|
||||
(`data-log-more` asks for those before `Next`), each entry (`data-log-entry="{id}"`, `data-log-action`) with who
|
||||
(`data-log-by`: you, a login name to administrators, `cli`, or none), what, to what (`data-log-target`) and its note
|
||||
(`data-log-note`). `data-log-reload`.
|
||||
- **Reports** (`ReportsPanel`): a violation's rules (`data-report-rules`, `data-report-rule-id`) as PrivaPub keeps their
|
||||
texts, a removed rule's too.
|
||||
- **Statistics** (`Components/Admin/StatisticsPanel.razor`, `/clientapi/admin/statistics`, typed in ClientModels'
|
||||
`Admin/ViewStatistics.cs`): the period's overview, the servers (by traffic, failures, latency or name), the crawler, the
|
||||
ledger's events and the server's own days. Counted per server, never per account.
|
||||
@@ -461,6 +522,16 @@ Never redeclare the base's members in a component.
|
||||
streaming API (`Services/StreamingService.cs`: one WebSocket, the persona's token as its protocol, never in a URL)
|
||||
for home, lists, local, federated, hashtags and notifications, and wait behind a "new" button; a deletion or an edit
|
||||
it tells applies at once. Other feeds, and any feed while the stream is down, are polled every 45 s while visible.
|
||||
- **Announcements** (`Components/AnnouncementsBanner.razor`, above the tabs, `data-announcement-banner`): the ones
|
||||
shown now that the persona has not dismissed, one at a time (`data-announcement-previous`, `-next`,
|
||||
`-position`), dismissed (`data-announcement-dismiss`, `POST /api/v1/announcements/:id/dismiss`) and reacted to
|
||||
(`data-announcement-reaction="{emoji}"` toggles the persona's own, `data-announcement-react` offers more,
|
||||
`data-announcement-react-emoji`; `PUT`/`DELETE /api/v1/announcements/:id/reactions/:name`, then read again). They
|
||||
come live on the user stream (`announcement`, `announcement.reaction`, `announcement.delete`):
|
||||
`StreamingService.HearAnnouncements` keeps it subscribed whatever feed is followed (and opens the socket for it
|
||||
alone on a polled feed), and raises what it tells as `Announced`; the user stream's posts and notifications are
|
||||
the feed's only while the feed followed is the user stream itself. The banner renders itself and never touches the
|
||||
feed's cards.
|
||||
- **At volume:** the list is a `<Virtualize>` (only the cards near the view are rendered), and a card re-renders only
|
||||
when its own events run or its render key changes (`Content.RenderKey`: the post, its status, notification,
|
||||
conversation, place, grouping, where it is shown, the persona and the connection). Anything that changes what a
|
||||
|
||||
Reference in new issue
Block a user