mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-13 02:42:30 +00:00
112 lines
4.4 KiB
Markdown
112 lines
4.4 KiB
Markdown
# plspace
|
|
|
|
*It's always Pleroma.*
|
|
|
|
A static, client-side frontend for Pleroma that looks and behaves like MySpace
|
|
circa 2005.
|
|
|
|
Point it at your server. It talks to that server's REST API directly from the
|
|
browser — there is no plspace backend, and `dist/` is a folder of static files
|
|
you can host anywhere.
|
|
|
|
## What it looks like
|
|
|
|
| MySpace | plspace |
|
|
| --- | --- |
|
|
| Profile page: photo, headline, vitals, Contacting box, Interests table | `#/@user@server` |
|
|
| Latest Blog Entries with "(view more)" | Account statuses, headline list |
|
|
| Blurbs: "About me", "Who I'd like to meet" | The bio, split on a heading if you wrote one |
|
|
| Friend Space grid | Followers |
|
|
| Mail Center, Friend Request Manager | Notifications, follow requests |
|
|
| Bulletin Space | The local timeline |
|
|
| Kudos | Favourites |
|
|
| Custom profile layouts | CSS in a profile field named `css` |
|
|
|
|
## Running it
|
|
|
|
```bash
|
|
npm install && npm run dev
|
|
```
|
|
|
|
```bash
|
|
npm run build
|
|
```
|
|
|
|
`npm run build` type-checks and then bundles to `dist/`. Because routing is
|
|
hash-based, the output works from any path — a subdirectory, an S3 bucket,
|
|
GitHub Pages — with no server rewrite rules.
|
|
|
|
## Signing in
|
|
|
|
plspace registers itself as an OAuth app on your server the first time you sign
|
|
in there, then redirects you to that server's own consent screen. Your password
|
|
is never entered into plspace; it only ever receives an access token, which is
|
|
stored in `localStorage` and used directly from your browser.
|
|
|
|
PKCE is used where the server supports it, with an automatic fallback for
|
|
servers that don't.
|
|
|
|
You can also browse without signing in — click **Just look around**. Note that
|
|
many servers set `restrict_unauthenticated` and refuse timeline reads from
|
|
anonymous callers; the suggested servers on the sign-in page are ones verified
|
|
to allow it.
|
|
|
|
## Making it yours
|
|
|
|
Settings has a CSS editor, five starter layouts, and a full class reference.
|
|
Everything about the appearance is overridable — see
|
|
[`src/styles/README.md`](src/styles/README.md) for the contract. In short:
|
|
no CSS framework, no Svelte scoped styles, no hashed class names, every colour
|
|
and metric is a custom property, and user CSS is always last in the cascade so
|
|
plain single-class selectors win without `!important`.
|
|
|
|
There is no built-in dark mode. A dark theme is just token overrides, so it ships
|
|
as a preset (**Midnight**, **Terminal**) you can apply, edit or replace, rather
|
|
than as a toggle you can't.
|
|
|
|
To publish a layout other people see on your profile, put CSS in a profile field
|
|
named `css` on your server. It is scoped to your profile's subtree and filtered
|
|
before it is applied.
|
|
|
|
Your profile fields also drive the profile page: name one `Music`, `Movies`,
|
|
`Television`, `Books` or `Heroes` and it fills the Interests table; name one
|
|
`Mood`, `Location`, `Gender` or `Headline` and it fills the block beside your
|
|
photo.
|
|
|
|
## Layout
|
|
|
|
```
|
|
src/
|
|
lib/
|
|
api/ client (fetch, Link-header pagination), OAuth, endpoints, entity types
|
|
stores/ session, Feed (cursor pagination), theme (user + profile CSS)
|
|
util/ HTML sanitizing, 2005-flavoured date formats, account -> profile mapping
|
|
router.svelte.ts
|
|
themes.ts starter layouts, written only in terms of tokens
|
|
components/
|
|
chrome/ header, nav, footer
|
|
common/ Module, RichText, Avatar, Pager, TabBar
|
|
profile/ identity, contacting box, interests, details, friend space
|
|
blog/ entry, attachments, poll, preview card, composer
|
|
people/ person row and list
|
|
routes/ Home, Profile, Timeline, StatusPage, Mail, Browse, Search, Compose, Login, Settings
|
|
styles/ tokens, base, layout, chrome, module, profile, blog, forms
|
|
```
|
|
|
|
## Safety notes
|
|
|
|
All HTML from the API — post content, bios, profile field values — is sanitized
|
|
with DOMPurify before it reaches `{@html}`, in exactly one component
|
|
(`RichText.svelte`) plus the profile-field helper. Mention and hashtag links are
|
|
rewritten to in-app routes; every other link gets `target="_blank"` with
|
|
`rel="noopener noreferrer"`.
|
|
|
|
## Compatibility
|
|
|
|
Written against the standard `/api/v1` REST API and tested against live servers.
|
|
Anything implementations differ on degrades rather than fails: `/api/v2/instance`
|
|
falls back to v1, `/api/v1/accounts/lookup` falls back to search, pagination
|
|
falls back to the last item's id when a server drops the `Link` header, and
|
|
per-account privacy flags are read in both their spellings. Other software
|
|
speaking the same API therefore works, but Pleroma is what this targets.
|