From 602ac092934b36592c87cfa70d84afe4df76b66b Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Sat, 26 Sep 2026 00:00:18 -0700 Subject: [PATCH] Name the group-space, platform-flag and active-space rules once, and keep makeEventPath to in-app paths --- .agents/skills/flotilla-architecture/SKILL.md | 2 +- .agents/skills/flotilla-model/SKILL.md | 11 ++-- .agents/skills/flotilla-views/SKILL.md | 4 +- src/app/components/MenuSettings.svelte | 19 ++++--- src/app/components/Share.svelte | 15 ++++-- src/app/components/SpaceMenuNavItems.svelte | 15 +++--- src/app/components/SpaceMenuRooms.svelte | 12 ++--- src/app/editor/index.ts | 13 ++--- src/app/env.ts | 2 +- src/app/notifications.ts | 19 ++++--- src/app/push/adapters/common.ts | 3 +- src/app/relays.ts | 8 ++- src/app/rooms.ts | 51 +++++++++--------- src/app/routes.ts | 28 +++++----- src/app/share.ts | 5 +- src/app/sync.ts | 53 +++++++------------ src/routes/settings/+layout.svelte | 4 +- src/routes/settings/about/+page.svelte | 5 +- 18 files changed, 134 insertions(+), 135 deletions(-) diff --git a/.agents/skills/flotilla-architecture/SKILL.md b/.agents/skills/flotilla-architecture/SKILL.md index 5286f63e..b4c0679c 100644 --- a/.agents/skills/flotilla-architecture/SKILL.md +++ b/.agents/skills/flotilla-architecture/SKILL.md @@ -185,7 +185,7 @@ One web build runs in several shells: Platform checks call Capacitor directly. There is no wrapper module: ```ts -export const ENABLE_ZAPS = Capacitor.getPlatform() != "ios" // src/app/env.ts +export const ENABLE_ZAPS = Capacitor.getPlatform() !== "ios" // src/app/env.ts export const HOSTING_ENABLED = Capacitor.getPlatform() !== "ios" // src/app/hosting.ts if (!Capacitor.isPluginAvailable("Keyboard")) return noop // src/app/keyboard.ts diff --git a/.agents/skills/flotilla-model/SKILL.md b/.agents/skills/flotilla-model/SKILL.md index 9c980041..2adb3301 100644 --- a/.agents/skills/flotilla-model/SKILL.md +++ b/.agents/skills/flotilla-model/SKILL.md @@ -31,7 +31,8 @@ carries `["h", h]`; content with no `h` belongs to the whole space. `/spaces/[re `deriveUserRooms(url)` in `src/app/rooms.ts` read it. "Joined" in the UI means "in this list", which is separate from NIP-43 membership on the relay: `src/routes/spaces/[relay]/+layout.svelte` prompts `SpaceJoin` for any URL not in `userSpaceUrls`. A deployment with `VITE_PLATFORM_RELAYS` -uses `PLATFORM_RELAYS` in place of the list for sync and navigation. +uses `PLATFORM_RELAYS` in place of the list for sync and navigation: `activeSpaceUrls` in +`src/app/rooms.ts` is that choice, read by background sync, notifications and editor suggestions. ### NIP-11 relay info @@ -40,7 +41,7 @@ domain `Relay`. These fields drive protocol decisions: | Read | Decides | |---|---| -| `hasNip(29)` | whether the space has rooms. Without it everything lives in the space chat: `makeSpaceEntryPath` (`src/app/routes.ts`), `shareEvent` (`src/app/share.ts`), room search, notification grouping, `SpaceMenuRooms` | +| `hasNip(29)` | whether the space has rooms, read through `isGroupSpace(url)` / `deriveIsGroupSpace(url)` in `src/app/relays.ts`. Without it everything lives in the space chat (`makeSpaceChatPath`): `shareEvent` (`src/app/share.ts`), room search, notification grouping, `SpaceMenuNavItems`, `SpaceMenuRooms` | | `hasNip(70)` | whether space content is marked protected (below) | | `self` | the relay's own pubkey, the trust anchor for relay-signed state | | `pubkey` | the space's owner, who writes space-wide content that has no other author (`deriveUserIsSpaceOwner`) | @@ -104,9 +105,9 @@ user holds a method for — reports under `banevent`, join requests under `allow - `deriveUserRoomMembershipStatus`: an admin is always `Granted`. - `addRoomMembers`: allows each non-member at the relay (NIP-86 `allowPubkey`) before publishing 9000, because a room member the relay won't serve can't read the room. -- `deriveUserRooms`, `deriveOtherRooms`, `deriveOtherVoiceRooms`: rooms from the user's 10009 - list and the rest of the space, limited to rooms the relay still advertises. `meta.hasLivekit()` - marks a voice room. +- `deriveUserRooms`, `deriveOtherRooms(url, type)`: rooms from the user's 10009 list and the rest + of the space by `RoomType`, limited to rooms the relay still advertises. `meta.hasLivekit()` + marks a voice room (`getRoomType`). ### Room flows diff --git a/.agents/skills/flotilla-views/SKILL.md b/.agents/skills/flotilla-views/SKILL.md index b0f87aad..9c940bd1 100644 --- a/.agents/skills/flotilla-views/SKILL.md +++ b/.agents/skills/flotilla-views/SKILL.md @@ -99,7 +99,9 @@ mobile. Pages outside a space use `Page`, `PageBar` and `PageContent` themselves `makeCalendarPath`, `makeGoalPath`, `makePollPath`, `makeLibraryPath`, `makeArticleCreatePath`). - `makeContentPath(url, kind, idOrAddress)` maps a kind to its page. `makeEventPath` builds on it for any event, covering DMs, room messages (`?at=`) and comments (through the parent's `K`, - `A` and `E` tags), and falls back to `entityLink` from `src/app/env.ts`, an external link. + `A` and `E` tags), and returns `undefined` for an event with no page in the app. A caller that + wants an external link then calls `entityLink` from `src/app/env.ts` itself, as + `makeEventPermalink` does. - `goToEvent(event)` scrolls to the event if it is already rendered with a `data-event` attribute and navigates otherwise; `makeEventPermalink` is the shareable form. - `goToSpace(url)` goes to `makeSpaceEntryPath(url)`: the last page visited in that space, which diff --git a/src/app/components/MenuSettings.svelte b/src/app/components/MenuSettings.svelte index bc8a60ba..26b0019f 100644 --- a/src/app/components/MenuSettings.svelte +++ b/src/app/components/MenuSettings.svelte @@ -1,5 +1,4 @@