mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-13 02:42:30 +00:00
initial commit
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user