Wire the client to PrivaPub: one sign-in, real feeds, a globe, nerd stats
One sign-in for both of PrivaPub's APIs: the root logs in on /clientapi, picks a persona, and each persona gets its own Mastodon token in exchange for the JWT (PersonaExchange). HttpService picks credentials and JSON by route (JWT and camelCase for /clientapi, the persona token and snake_case for /api, nothing for /oauth), retries a refused persona token once, and records every request for the nerd stats. The feed page is three columns: navigation with a persona switcher, the feed with a tab per kind (home, local, federated, nearby, communities and circles, direct, notifications, favourites, bookmarks, hashtags), and a 3D globe that looks at the spherical mean of the posts in view and draws a pulse and an arc to a hovered one. Posts sit at their own place, their event's venue, the reader (located posts) or their author's server as PrivaPub publishes it. Cards favourite, boost, bookmark, reply, mute, block and delete; the composer posts with a content warning, visibility, media and alt text, or as a located post. Older pages load as the end nears; newer ones are polled while visible. Nerd stats in tooltips: provenance, author and server, place, media, counts, paging, the globe's camera and frame rate. The mock (Faker, MessagesService, the Message models and store) and the OIDC template leftovers are gone. Strings in English and Italian. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
f41ebf2160
commit
827ecb770e
56 files changed
+5367
-832
No files matched your search
+354
-33
@@ -50,9 +50,6 @@
|
||||
<data name="Alternative text" xml:space="preserve">
|
||||
<value>Alternative text</value>
|
||||
</data>
|
||||
<data name="Ascending" xml:space="preserve">
|
||||
<value>Ascending</value>
|
||||
</data>
|
||||
<data name="Audio" xml:space="preserve">
|
||||
<value>Audio</value>
|
||||
</data>
|
||||
@@ -83,15 +80,9 @@
|
||||
<data name="Delete" xml:space="preserve">
|
||||
<value>Delete</value>
|
||||
</data>
|
||||
<data name="Descending" xml:space="preserve">
|
||||
<value>Descending</value>
|
||||
</data>
|
||||
<data name="Direct" xml:space="preserve">
|
||||
<value>Direct</value>
|
||||
</data>
|
||||
<data name="Direct message" xml:space="preserve">
|
||||
<value>Direct message</value>
|
||||
</data>
|
||||
<data name="Documents" xml:space="preserve">
|
||||
<value>Documents</value>
|
||||
</data>
|
||||
@@ -128,15 +119,9 @@
|
||||
<data name="Home" xml:space="preserve">
|
||||
<value>Home</value>
|
||||
</data>
|
||||
<data name="HTML" xml:space="preserve">
|
||||
<value>HTML</value>
|
||||
</data>
|
||||
<data name="Images" xml:space="preserve">
|
||||
<value>Images</value>
|
||||
</data>
|
||||
<data name="Index" xml:space="preserve">
|
||||
<value>Home</value>
|
||||
</data>
|
||||
<data name="Instance" xml:space="preserve">
|
||||
<value>Instance</value>
|
||||
</data>
|
||||
@@ -164,9 +149,6 @@
|
||||
<data name="Logout" xml:space="preserve">
|
||||
<value>Logout</value>
|
||||
</data>
|
||||
<data name="Markdown" xml:space="preserve">
|
||||
<value>Markdown</value>
|
||||
</data>
|
||||
<data name="Message deleted." xml:space="preserve">
|
||||
<value>Message deleted.</value>
|
||||
</data>
|
||||
@@ -188,15 +170,9 @@
|
||||
<data name="Not found" xml:space="preserve">
|
||||
<value>Not found</value>
|
||||
</data>
|
||||
<data name="oh shit... here we go again" xml:space="preserve">
|
||||
<value>oh shit... here we go again</value>
|
||||
</data>
|
||||
<data name="Other" xml:space="preserve">
|
||||
<value>Other</value>
|
||||
</data>
|
||||
<data name="PlainText" xml:space="preserve">
|
||||
<value>Plain text</value>
|
||||
</data>
|
||||
<data name="Policies" xml:space="preserve">
|
||||
<value>Policies</value>
|
||||
</data>
|
||||
@@ -221,18 +197,12 @@
|
||||
<data name="Settings" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
</data>
|
||||
<data name="Show preview" xml:space="preserve">
|
||||
<value>Show preview</value>
|
||||
</data>
|
||||
<data name="Sorry, there's nothing at this address." xml:space="preserve">
|
||||
<value>Sorry, there's nothing at this address.</value>
|
||||
</data>
|
||||
<data name="Supplied file "{0}" with size {1} exceeds the maximum of {2}." xml:space="preserve">
|
||||
<value>Supplied file "{0}" with size {1} exceeds the maximum of {2}.</value>
|
||||
</data>
|
||||
<data name="The action could not be completed." xml:space="preserve">
|
||||
<value>The action could not be completed.</value>
|
||||
</data>
|
||||
<data name="The file "{0}" could not be read." xml:space="preserve">
|
||||
<value>The file "{0}" could not be read.</value>
|
||||
</data>
|
||||
@@ -263,9 +233,6 @@
|
||||
<data name="This message doesn't exist." xml:space="preserve">
|
||||
<value>This message doesn't exist.</value>
|
||||
</data>
|
||||
<data name="Title (optional)" xml:space="preserve">
|
||||
<value>Title (optional)</value>
|
||||
</data>
|
||||
<data name="Unlisted" xml:space="preserve">
|
||||
<value>Unlisted</value>
|
||||
</data>
|
||||
@@ -320,4 +287,358 @@
|
||||
<data name="{0}MB" xml:space="preserve">
|
||||
<value>{0}MB</value>
|
||||
</data>
|
||||
<data name="A located post needs this device's position." xml:space="preserve">
|
||||
<value>A located post needs this device's position.</value>
|
||||
</data>
|
||||
<data name="A poll you took part in has ended" xml:space="preserve">
|
||||
<value>A poll you took part in has ended</value>
|
||||
</data>
|
||||
<data name="Asking this device for its position…" xml:space="preserve">
|
||||
<value>Asking this device for its position…</value>
|
||||
</data>
|
||||
<data name="Attach" xml:space="preserve">
|
||||
<value>Attach</value>
|
||||
</data>
|
||||
<data name="Author" xml:space="preserve">
|
||||
<value>Author</value>
|
||||
</data>
|
||||
<data name="Back" xml:space="preserve">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="Bookmark" xml:space="preserve">
|
||||
<value>Bookmark</value>
|
||||
</data>
|
||||
<data name="Bookmarks" xml:space="preserve">
|
||||
<value>Bookmarks</value>
|
||||
</data>
|
||||
<data name="Choose a persona first." xml:space="preserve">
|
||||
<value>Choose a persona first.</value>
|
||||
</data>
|
||||
<data name="Content warning" xml:space="preserve">
|
||||
<value>Content warning</value>
|
||||
</data>
|
||||
<data name="Counts" xml:space="preserve">
|
||||
<value>Counts</value>
|
||||
</data>
|
||||
<data name="Each persona has its own token; PrivaPub never tells anyone they share a login." xml:space="preserve">
|
||||
<value>Each persona has its own token; PrivaPub never tells anyone they share a login.</value>
|
||||
</data>
|
||||
<data name="Event" xml:space="preserve">
|
||||
<value>Event</value>
|
||||
</data>
|
||||
<data name="Favourites" xml:space="preserve">
|
||||
<value>Favourites</value>
|
||||
</data>
|
||||
<data name="Federated" xml:space="preserve">
|
||||
<value>Federated</value>
|
||||
</data>
|
||||
<data name="Feed" xml:space="preserve">
|
||||
<value>Feed</value>
|
||||
</data>
|
||||
<data name="Globe" xml:space="preserve">
|
||||
<value>Globe</value>
|
||||
</data>
|
||||
<data name="Globe of the posts in view" xml:space="preserve">
|
||||
<value>Globe of the posts in view</value>
|
||||
</data>
|
||||
<data name="Groups" xml:space="preserve">
|
||||
<value>Groups</value>
|
||||
</data>
|
||||
<data name="Located" xml:space="preserve">
|
||||
<value>Located</value>
|
||||
</data>
|
||||
<data name="Located post" xml:space="preserve">
|
||||
<value>Located post</value>
|
||||
</data>
|
||||
<data name="Located post published." xml:space="preserve">
|
||||
<value>Located post published.</value>
|
||||
</data>
|
||||
<data name="Media" xml:space="preserve">
|
||||
<value>Media</value>
|
||||
</data>
|
||||
<data name="Near you" xml:space="preserve">
|
||||
<value>Near you</value>
|
||||
</data>
|
||||
<data name="Nearby" xml:space="preserve">
|
||||
<value>Nearby</value>
|
||||
</data>
|
||||
<data name="Nearby shows located posts written within their range of you. It needs this device's position, which goes to PrivaPub only." xml:space="preserve">
|
||||
<value>Nearby shows located posts written within their range of you. It needs this device's position, which goes to PrivaPub only.</value>
|
||||
</data>
|
||||
<data name="No persona" xml:space="preserve">
|
||||
<value>No persona</value>
|
||||
</data>
|
||||
<data name="No persona yet" xml:space="preserve">
|
||||
<value>No persona yet</value>
|
||||
</data>
|
||||
<data name="Notifications" xml:space="preserve">
|
||||
<value>Notifications</value>
|
||||
</data>
|
||||
<data name="One login for all of your personas: each one is signed in separately and never linked to the others." xml:space="preserve">
|
||||
<value>One login for all of your personas: each one is signed in separately and never linked to the others.</value>
|
||||
</data>
|
||||
<data name="Open original" xml:space="preserve">
|
||||
<value>Open original</value>
|
||||
</data>
|
||||
<data name="Password" xml:space="preserve">
|
||||
<value>Password</value>
|
||||
</data>
|
||||
<data name="Place" xml:space="preserve">
|
||||
<value>Place</value>
|
||||
</data>
|
||||
<data name="Published." xml:space="preserve">
|
||||
<value>Published.</value>
|
||||
</data>
|
||||
<data name="Reply to {0}" xml:space="preserve">
|
||||
<value>Reply to {0}</value>
|
||||
</data>
|
||||
<data name="Retry" xml:space="preserve">
|
||||
<value>Retry</value>
|
||||
</data>
|
||||
<data name="Sensitive media, show" xml:space="preserve">
|
||||
<value>Sensitive media, show</value>
|
||||
</data>
|
||||
<data name="Shown only to people within {0} km of here, never sent to other servers." xml:space="preserve">
|
||||
<value>Shown only to people within {0} km of here, never sent to other servers.</value>
|
||||
</data>
|
||||
<data name="Sign in to PrivaPub" xml:space="preserve">
|
||||
<value>Sign in to PrivaPub</value>
|
||||
</data>
|
||||
<data name="Switch persona" xml:space="preserve">
|
||||
<value>Switch persona</value>
|
||||
</data>
|
||||
<data name="Tag" xml:space="preserve">
|
||||
<value>Tag</value>
|
||||
</data>
|
||||
<data name="That's all." xml:space="preserve">
|
||||
<value>That's all.</value>
|
||||
</data>
|
||||
<data name="The feed could not be read." xml:space="preserve">
|
||||
<value>The feed could not be read.</value>
|
||||
</data>
|
||||
<data name="The globe could not start." xml:space="preserve">
|
||||
<value>The globe could not start.</value>
|
||||
</data>
|
||||
<data name="The server is behind {0}, so its place is unknown." xml:space="preserve">
|
||||
<value>The server is behind {0}, so its place is unknown.</value>
|
||||
</data>
|
||||
<data name="This device did not give its position: {0}" xml:space="preserve">
|
||||
<value>This device did not give its position: {0}</value>
|
||||
</data>
|
||||
<data name="This login has no persona to act as. Create one on PrivaPub first." xml:space="preserve">
|
||||
<value>This login has no persona to act as. Create one on PrivaPub first.</value>
|
||||
</data>
|
||||
<data name="This persona is in no community or circle yet." xml:space="preserve">
|
||||
<value>This persona is in no community or circle yet.</value>
|
||||
</data>
|
||||
<data name="Thread" xml:space="preserve">
|
||||
<value>Thread</value>
|
||||
</data>
|
||||
<data name="Use my position" xml:space="preserve">
|
||||
<value>Use my position</value>
|
||||
</data>
|
||||
<data name="Username" xml:space="preserve">
|
||||
<value>Username</value>
|
||||
</data>
|
||||
<data name="What's happening?" xml:space="preserve">
|
||||
<value>What's happening?</value>
|
||||
</data>
|
||||
<data name="Who are you today?" xml:space="preserve">
|
||||
<value>Who are you today?</value>
|
||||
</data>
|
||||
<data name="active this month" xml:space="preserve">
|
||||
<value>active this month</value>
|
||||
</data>
|
||||
<data name="ago" xml:space="preserve">
|
||||
<value>ago</value>
|
||||
</data>
|
||||
<data name="answer" xml:space="preserve">
|
||||
<value>answer</value>
|
||||
</data>
|
||||
<data name="auto-rotate" xml:space="preserve">
|
||||
<value>auto-rotate</value>
|
||||
</data>
|
||||
<data name="boosts" xml:space="preserve">
|
||||
<value>boosts</value>
|
||||
</data>
|
||||
<data name="boosts per favourite" xml:space="preserve">
|
||||
<value>boosts per favourite</value>
|
||||
</data>
|
||||
<data name="camera" xml:space="preserve">
|
||||
<value>camera</value>
|
||||
</data>
|
||||
<data name="centre of view" xml:space="preserve">
|
||||
<value>centre of view</value>
|
||||
</data>
|
||||
<data name="closed" xml:space="preserve">
|
||||
<value>closed</value>
|
||||
</data>
|
||||
<data name="delivery latency" xml:space="preserve">
|
||||
<value>delivery latency</value>
|
||||
</data>
|
||||
<data name="described" xml:space="preserve">
|
||||
<value>described</value>
|
||||
</data>
|
||||
<data name="end" xml:space="preserve">
|
||||
<value>end</value>
|
||||
</data>
|
||||
<data name="error" xml:space="preserve">
|
||||
<value>error</value>
|
||||
</data>
|
||||
<data name="failures in a row" xml:space="preserve">
|
||||
<value>failures in a row</value>
|
||||
</data>
|
||||
<data name="first page" xml:space="preserve">
|
||||
<value>first page</value>
|
||||
</data>
|
||||
<data name="followers" xml:space="preserve">
|
||||
<value>followers</value>
|
||||
</data>
|
||||
<data name="following" xml:space="preserve">
|
||||
<value>following</value>
|
||||
</data>
|
||||
<data name="from PrivaPub" xml:space="preserve">
|
||||
<value>from PrivaPub</value>
|
||||
</data>
|
||||
<data name="in view" xml:space="preserve">
|
||||
<value>in view</value>
|
||||
</data>
|
||||
<data name="items" xml:space="preserve">
|
||||
<value>items</value>
|
||||
</data>
|
||||
<data name="last delivery" xml:space="preserve">
|
||||
<value>last delivery</value>
|
||||
</data>
|
||||
<data name="last request" xml:space="preserve">
|
||||
<value>last request</value>
|
||||
</data>
|
||||
<data name="local posts" xml:space="preserve">
|
||||
<value>local posts</value>
|
||||
</data>
|
||||
<data name="located at" xml:space="preserve">
|
||||
<value>located at</value>
|
||||
</data>
|
||||
<data name="located by" xml:space="preserve">
|
||||
<value>located by</value>
|
||||
</data>
|
||||
<data name="network" xml:space="preserve">
|
||||
<value>network</value>
|
||||
</data>
|
||||
<data name="open" xml:space="preserve">
|
||||
<value>open</value>
|
||||
</data>
|
||||
<data name="paused" xml:space="preserve">
|
||||
<value>paused</value>
|
||||
</data>
|
||||
<data name="points" xml:space="preserve">
|
||||
<value>points</value>
|
||||
</data>
|
||||
<data name="poll every" xml:space="preserve">
|
||||
<value>poll every</value>
|
||||
</data>
|
||||
<data name="polled" xml:space="preserve">
|
||||
<value>polled</value>
|
||||
</data>
|
||||
<data name="posts" xml:space="preserve">
|
||||
<value>posts</value>
|
||||
</data>
|
||||
<data name="precision" xml:space="preserve">
|
||||
<value>precision</value>
|
||||
</data>
|
||||
<data name="quotes" xml:space="preserve">
|
||||
<value>quotes</value>
|
||||
</data>
|
||||
<data name="registrations" xml:space="preserve">
|
||||
<value>registrations</value>
|
||||
</data>
|
||||
<data name="replies" xml:space="preserve">
|
||||
<value>replies</value>
|
||||
</data>
|
||||
<data name="server" xml:space="preserve">
|
||||
<value>server</value>
|
||||
</data>
|
||||
<data name="servers" xml:space="preserve">
|
||||
<value>servers</value>
|
||||
</data>
|
||||
<data name="software" xml:space="preserve">
|
||||
<value>software</value>
|
||||
</data>
|
||||
<data name="source" xml:space="preserve">
|
||||
<value>source</value>
|
||||
</data>
|
||||
<data name="spread" xml:space="preserve">
|
||||
<value>spread</value>
|
||||
</data>
|
||||
<data name="texture" xml:space="preserve">
|
||||
<value>texture</value>
|
||||
</data>
|
||||
<data name="the author's server" xml:space="preserve">
|
||||
<value>the author's server</value>
|
||||
</data>
|
||||
<data name="the author's server's country" xml:space="preserve">
|
||||
<value>the author's server's country</value>
|
||||
</data>
|
||||
<data name="the event's venue" xml:space="preserve">
|
||||
<value>the event's venue</value>
|
||||
</data>
|
||||
<data name="the post's own place" xml:space="preserve">
|
||||
<value>the post's own place</value>
|
||||
</data>
|
||||
<data name="votes" xml:space="preserve">
|
||||
<value>votes</value>
|
||||
</data>
|
||||
<data name="waiting" xml:space="preserve">
|
||||
<value>waiting</value>
|
||||
</data>
|
||||
<data name="{0} asked to follow you" xml:space="preserve">
|
||||
<value>{0} asked to follow you</value>
|
||||
</data>
|
||||
<data name="{0} boosted your post" xml:space="preserve">
|
||||
<value>{0} boosted your post</value>
|
||||
</data>
|
||||
<data name="{0} edited a post" xml:space="preserve">
|
||||
<value>{0} edited a post</value>
|
||||
</data>
|
||||
<data name="{0} favourited your post" xml:space="preserve">
|
||||
<value>{0} favourited your post</value>
|
||||
</data>
|
||||
<data name="{0} followed you" xml:space="preserve">
|
||||
<value>{0} followed you</value>
|
||||
</data>
|
||||
<data name="{0} km from you, shown within {1} km" xml:space="preserve">
|
||||
<value>{0} km from you, shown within {1} km</value>
|
||||
</data>
|
||||
<data name="{0} mentioned you" xml:space="preserve">
|
||||
<value>{0} mentioned you</value>
|
||||
</data>
|
||||
<data name="{0} new" xml:space="preserve">
|
||||
<value>{0} new</value>
|
||||
</data>
|
||||
<data name="{0} posted" xml:space="preserve">
|
||||
<value>{0} posted</value>
|
||||
</data>
|
||||
<data name="{0} quoted your post" xml:space="preserve">
|
||||
<value>{0} quoted your post</value>
|
||||
</data>
|
||||
<data name="{0} reacted {1}" xml:space="preserve">
|
||||
<value>{0} reacted {1}</value>
|
||||
</data>
|
||||
<data name="{0} votes" xml:space="preserve">
|
||||
<value>{0} votes</value>
|
||||
</data>
|
||||
<data name="{0}: {1}" xml:space="preserve">
|
||||
<value>{0}: {1}</value>
|
||||
</data>
|
||||
<data name="hovered" xml:space="preserve">
|
||||
<value>hovered</value>
|
||||
</data>
|
||||
<data name="arcs" xml:space="preserve">
|
||||
<value>arcs</value>
|
||||
</data>
|
||||
<data name="rings" xml:space="preserve">
|
||||
<value>rings</value>
|
||||
</data>
|
||||
<data name="placed" xml:space="preserve">
|
||||
<value>placed</value>
|
||||
</data>
|
||||
</root>
|
||||
Reference in new issue
Block a user