diff --git a/.env.example b/.env.example index 0ab941c..f618555 100644 --- a/.env.example +++ b/.env.example @@ -1,10 +1,10 @@ -PUBLIC_RELAY_URL=ws://localhost:3334 -PUBLIC_GROUP_ID=mygrouprandomid -PUBLIC_TITLE= # top-bar title (full mode); empty falls back to group name -PUBLIC_MODE=simple # simple | full -PUBLIC_JOINCODE=no # yes | no — show invite-code field on join failure -PUBLIC_LABELS= # comma-separated labels (e.g., bug,feature,question) -PUBLIC_BLOSSOM_URL= # Blossom server URL (e.g., https://blossom.primal.net) +PUBLIC_RELAY_URL=ws://localhost:3334 # required — NIP-29 relay hosting the group(s) +PUBLIC_MODE=simple # simple | full (single forum vs. many rooms) +PUBLIC_GROUP_ID=mygrouprandomid # required in simple mode; the single forum's group id (ignored in full mode) +PUBLIC_TITLE= # top-bar title; empty falls back to the group name +PUBLIC_JOINCODE=no # yes | no — show an invite-code field when a join is rejected +PUBLIC_LABELS= # comma-separated discussion labels (e.g., bug,feature,question) +PUBLIC_BLOSSOM_URL= # Blossom server URL for uploads (e.g., https://blossom.primal.net) # Theme color overrides — quote the value, a leading # is read as a comment otherwise -PUBLIC_ACCENT_COLOR= # override the accent color (default #e32a6d), e.g. "#00ff00"; hover shade derived -PUBLIC_SECONDARY_COLOR= # override the secondary color (default #ffaf25), e.g. "#0000ff"; hover shade derived +PUBLIC_ACCENT_COLOR= # override the accent color (default #e32a6d), e.g. "#00ff00"; hover shade derived +PUBLIC_SECONDARY_COLOR= # override the secondary color (default #ffaf25), e.g. "#0000ff"; hover shade derived diff --git a/README.md b/README.md index 41310b3..8d76132 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # Squalk -**Warning: work in progress, early alpha state!** - Squalk is a forum built on Nostr that permits to manage simple or large communities; in fact you can choose to setup it in "simple" or "full" mode. Simple mode expose a single forum, while in Full mode you can have as many forum as you like. Each forum includes a chat feature in the right-hand sidebar, which is useful for quickly interacting with members. @@ -9,11 +7,74 @@ Each forum includes a chat feature in the right-hand sidebar, which is useful fo ![](assets/screenshot02.png) +![](assets/screenshot03.png) + +![](assets/screenshot04.png) + ## Tech stack Squalk is built on Nostr and implement [NIP-29](https://github.com/nostr-protocol/nips/blob/master/29.md) and [NIP-7D](https://github.com/nostr-protocol/nips/blob/master/7D.md). It needs a personal relay that supports NIP-29 to host the group(s) and a Blossom server for the uploads; [Pyramid](https://github.com/fiatjaf/pyramid) includes both and is the suggested solution. +## Configuration + +Squalk is configured entirely through environment variables (all prefixed `PUBLIC_`, since they are read in the browser). Copy `.env.example` to `.env` and fill in the values; SvelteKit also reads `.env.development` (used by `npm run dev`) and `.env.production` (used by `npm run build`). + +| Variable | Required | Default | Description | +| --- | --- | --- | --- | +| `PUBLIC_RELAY_URL` | yes | — | WebSocket URL of the NIP-29 relay hosting the group(s), e.g. `wss://relay.example.com`. | +| `PUBLIC_MODE` | no | `simple` | `simple` (a single forum) or `full` (multiple rooms). The admin can later upgrade simple → full at runtime. | +| `PUBLIC_GROUP_ID` | in simple mode | — | The single forum's group id. Required when `PUBLIC_MODE=simple`; ignored in full mode, where rooms are selected at runtime. | +| `PUBLIC_TITLE` | no | group name | Title shown in the top bar. When empty it falls back to the group's name. | +| `PUBLIC_JOINCODE` | no | `no` | `yes` to show an invite-code field when a join request is rejected (for code-gated relays). | +| `PUBLIC_LABELS` | no | — | Comma-separated discussion labels offered when composing, e.g. `bug,feature,question`. | +| `PUBLIC_BLOSSOM_URL` | no | — | Blossom server URL used for media uploads, e.g. `https://blossom.primal.net`. Uploads are disabled when unset. | +| `PUBLIC_ACCENT_COLOR` | no | `#e32a6d` | Override the accent (primary) color. Quote the value (`"#00ff00"`) — an unquoted leading `#` is read as a comment. The hover shade is derived automatically. | +| `PUBLIC_SECONDARY_COLOR` | no | `#ffaf25` | Override the secondary color. Same quoting rule and derived hover shade as above. | + +## Customizing content + +Squalk fills its sidebar links and personalizes the homepage and contacts page from NIP-23 long-form events (kind `30023`) published to the same relay that hosts the group(s). Only events authored by a forum admin (a pubkey listed in a group's NIP-29 `39001` admin event) are surfaced — the relay query is open, so the admin set is the trust gate. + +Content is plain markdown. The sample `.md` files in the repo root (`about.md`, `guidelines.md`, `homepage.md`, `contacts.md`) are starting points you can adapt and publish. + +### Resources (sidebar links) + +Resources appear in the left sidebar and are served at `/resource/`. Publish a kind `30023` event with: + +| Tag | Required | Purpose | +| --- | --- | --- | +| `["t", "squalk-resource"]` | yes | marks the event as a resource | +| `["d", ""]` | yes | the `d`/identifier tag — also the URL slug (`/resource/`) | +| `["title", ""]` | recommended | label shown in the sidebar (falls back to the slug) | +| `["position", "<n>"]` | optional | ordering hint, ascending | + +The `content` field is the markdown body. Ordering: resources with a `position` come first, sorted ascending; ties and unpositioned resources fall back to alphabetical order by title. Because events are addressable, re-publishing with the same `d` slug updates the resource (newest wins). + +Example (the `about` resource linked from the homepage): + +``` +kind: 30023 +tags: + ["t", "squalk-resource"] + ["d", "about"] + ["title", "About"] + ["position", "1"] +content: "# About this forum\n\n..." +``` + +### Partials (homepage & contacts) + +Partials inject custom markdown into fixed slots. There are exactly two slots: `home` (rendered at the top of the homepage) and `contacts` (the contacts page). Publish a kind `30023` event with: + +| Tag | Required | Purpose | +| --- | --- | --- | +| `["t", "squalk-partial"]` | yes | marks the event as a partial | +| `["d", "home"]` or `["d", "contacts"]` | yes | the slot to fill (any other value is ignored) | +| `["title", "<title>"]` | optional | not displayed in the slot, but useful for clients | + +The newest admin-authored event for a slot wins. The `home` partial renders above the room list / discussions feed; a leading image URL on its own line (see `homepage.md`) is rendered as a banner image. + ## Developing Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: diff --git a/assets/screenshot01.png b/assets/screenshot01.png index 4822914..6a97e0c 100644 Binary files a/assets/screenshot01.png and b/assets/screenshot01.png differ diff --git a/assets/screenshot02.png b/assets/screenshot02.png index 3d8aa4d..8c8ba6d 100644 Binary files a/assets/screenshot02.png and b/assets/screenshot02.png differ diff --git a/assets/screenshot03.png b/assets/screenshot03.png new file mode 100644 index 0000000..49fc5fd Binary files /dev/null and b/assets/screenshot03.png differ diff --git a/assets/screenshot04.png b/assets/screenshot04.png new file mode 100644 index 0000000..6510ee8 Binary files /dev/null and b/assets/screenshot04.png differ