diff --git a/modules/rfeeds/landing.ts b/modules/rfeeds/landing.ts new file mode 100644 index 00000000..11425e49 --- /dev/null +++ b/modules/rfeeds/landing.ts @@ -0,0 +1,143 @@ +/** + * rFeeds — landing page body. + * Returned by landingPage() in the module export; + * the shell wraps it with header, CSS, and analytics. + */ +export function renderLanding(): string { + return ` + +
+ rFeeds +

Your community’s pulse, one feed.

+

RSS Dashboard & Activity Aggregator

+

+ Subscribe to external RSS/Atom feeds, pull activity from your rSpace modules, + curate what matters, and republish as a unified Atom feed — + all from one local-first dashboard. +

+
+ View Demo + Create a Space +
+
+ + +
+
+

What rFeeds Does

+
+
+
📡
+

RSS & Atom Import

+

Subscribe to any RSS or Atom feed. Bulk import via OPML. Background sync keeps items fresh.

+
+
+
🔌
+

rApp Activity

+

Pull activity from Calendar, Tasks, Docs, Wallet, Photos, and more — directly from Automerge docs.

+
+
+
💬
+

Manual Posts

+

Write short posts that appear in the timeline alongside imported items. Quick updates for your community.

+
+
+
🛰
+

Reshare & Republish

+

Curate the best items and reshare them into your space’s public Atom feed for others to subscribe to.

+
+
+
+
+ + +
+
+

How It Works

+
+
+
1
+

Add Sources

+

Paste an RSS URL, import an OPML file, or enable rApp activity adapters to pull from your modules.

+
+
+
2
+

Curate & Reshare

+

Browse the unified timeline. Mark the best items as “Reshared” to include them in your outbound feed.

+
+
+
3
+

Subscribe Anywhere

+

Your space publishes an Atom feed. Other spaces, RSS readers, or newsletters can subscribe to it.

+
+
+
+
+ + +
+
+

Personal Feed Profiles

+

+ Every member can create a personal feed profile that aggregates their activity across modules. +

+
+
+
👤
+

Your Profile

+

Set a display name, bio, and choose which modules appear in your personal feed.

+
+
+
📰
+

Personal Atom Feed

+

Each profile gets a unique Atom URL. Others subscribe via any RSS reader or rFeeds instance.

+
+
+
🌐
+

Cross-Space

+

Subscribe to someone’s personal feed from a different space — it’s just a standard Atom URL.

+
+
+
+
+ + +
+
+

Built on Open Standards

+
+
+
📚
+

Atom 1.0

+

All feeds published as standard Atom XML. Compatible with every RSS reader on the planet.

+
+
+
🧰
+

Automerge CRDT

+

Feed data stored in local-first Automerge documents. Works offline, syncs on reconnect.

+
+
+
🔒
+

EncryptID

+

Passkey-authenticated profiles. No passwords, no seeds — just biometric or hardware key sign-in.

+
+
+
+
+ + +
+
+

Your community’s pulse, one feed.

+

Try the demo or create a space to start curating.

+ +
+
+ +
+ ← Back to rSpace +
`; +} diff --git a/modules/rfeeds/mod.ts b/modules/rfeeds/mod.ts index ffa38f6a..e30639ce 100644 --- a/modules/rfeeds/mod.ts +++ b/modules/rfeeds/mod.ts @@ -20,6 +20,7 @@ import { feedsSchema, feedsDocId, MAX_ITEMS_PER_SOURCE, MAX_ACTIVITY_CACHE, DEFA import type { FeedsDoc, FeedSource, FeedItem, ManualPost, ActivityCacheEntry, ActivityModuleConfig, UserFeedProfile } from "./schemas"; import { parseFeed, parseOPML } from "./lib/feed-parser"; import { adapterRegistry } from "./adapters/index"; +import { renderLanding } from "./landing"; let _syncServer: SyncServer | null = null; @@ -965,6 +966,8 @@ export const feedsModule: RSpaceModule = { routes, scoping: { defaultScope: "space", userConfigurable: false }, docSchemas: [feedsSchema as any], + standaloneDomain: "rfeeds.online", + landingPage: renderLanding, onInit: async ({ syncServer }) => { _syncServer = syncServer;