Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
187 commits
Select commit Hold shift + click to select a range
b67e015
refactor data manager to be domain oriented
samthomson Sep 8, 2025
baaa50d
update components using data manager to use new structure
samthomson Sep 8, 2025
39bff4b
wip community/channel fetching from the data manager
samthomson Sep 8, 2025
aafe5eb
debug display for community/channels data
samthomson Sep 8, 2025
b095160
query things in bulk
samthomson Sep 8, 2025
65f3e2f
granular timing
samthomson Sep 8, 2025
2d1b67f
get blocked status for communities too, and query for more community …
samthomson Sep 9, 2025
cca1955
purer membership def
samthomson Sep 9, 2025
a93bb90
purer
samthomson Sep 9, 2025
a2a7ef2
++
samthomson Sep 9, 2025
316c1c2
lift off community info
samthomson Sep 9, 2025
d26a902
use structured data
samthomson Sep 9, 2025
2eeeb69
use structure data from data manager, and add getting channel structu…
samthomson Sep 9, 2025
564ff38
update channel parsing to get meta
samthomson Sep 9, 2025
c9d7b34
get communtiies without channels, then fill in as data comes in. para…
samthomson Sep 9, 2025
942dfe4
get channels specifically and kepe backwards compatability with old w…
samthomson Sep 10, 2025
c66ab70
dont limit channel discovery by author, multiple community members ca…
samthomson Sep 10, 2025
26ac696
drop in what nips/kinds we're actually using to the readme
samthomson Sep 10, 2025
8b8bde8
strip out lots of ai generated docs
samthomson Sep 10, 2025
2e688ff
chop dead functions
samthomson Sep 10, 2025
30e352c
track and display granular timing of parallelised operations
samthomson Sep 10, 2025
4a9745e
get replies too
samthomson Sep 10, 2025
b19b4ae
refactor dm routes / page component structure
samthomson Sep 10, 2025
fcaa52f
big refactor of pages/components and routing
samthomson Sep 10, 2025
56b7939
use same layout for community management page
samthomson Sep 10, 2025
0c55862
lint
samthomson Sep 11, 2025
09d284b
refactor: reorganize layout architecture for better separation of con…
samthomson Sep 11, 2025
4c798a1
refined base page layout interface
samthomson Sep 11, 2025
586d562
more refactoring of component structures
samthomson Sep 11, 2025
d51569e
fail fast
samthomson Sep 11, 2025
0f5e031
lint
samthomson Sep 11, 2025
4dcc2e6
remove pointless prop
samthomson Sep 11, 2025
95134bf
rename community related components to reflect their purpose while ma…
samthomson Sep 11, 2025
4f2c009
refactor community page components a little
samthomson Sep 11, 2025
27fe3c1
remove irrelevant code
samthomson Sep 11, 2025
d2fda15
rename feature to section
samthomson Sep 11, 2025
060b3b8
rename community feature to community section throughout app
samthomson Sep 11, 2025
bbfdecc
also get communtiies for which the user is the creator or moderator
samthomson Sep 11, 2025
ff732c1
refine handling creator/moderators
samthomson Sep 11, 2025
801b96b
normalise on 'banned'
samthomson Sep 11, 2025
5c10212
use the datamanager communities instead of old hook
samthomson Sep 11, 2025
25ab568
adapt sidebar to use new communities list
samthomson Sep 11, 2025
d739f33
lint
samthomson Sep 11, 2025
517b949
use full addressable id key for communities
samthomson Sep 11, 2025
50e856d
expose full membeship statuses (inc owner and moderator) from dataman…
samthomson Sep 11, 2025
8d29bf1
use data manager community data in community panel
samthomson Sep 11, 2025
10260fa
fix - correct prop use
samthomson Sep 11, 2025
1e94af7
remove obsolete import
samthomson Sep 11, 2025
30dc4fa
skeleton sturcture for community persisteance
samthomson Sep 12, 2025
e353bc4
cache communities data
samthomson Sep 12, 2025
65fac68
wip: adapt channel list to use data manager provider
samthomson Sep 12, 2025
d38092f
use data manager for channel list and permissions completely
samthomson Sep 13, 2025
3c002ea
route to community by naddr
samthomson Sep 14, 2025
f5dbb18
parse community naddr
samthomson Sep 14, 2025
6f493b7
fix channel routing
samthomson Sep 14, 2025
09c5bd2
fix highlighting selected community
samthomson Sep 14, 2025
2d92ce6
channel not found copy
samthomson Sep 14, 2025
ae15b2d
adapt to use community messages from the data manager
samthomson Sep 14, 2025
e8956ff
stop reloading channels on a loop
samthomson Sep 14, 2025
4d8bf9c
fix, sort channel messages
samthomson Sep 14, 2025
06f4fcf
add general channel fetching if general channel wasn't there
samthomson Sep 14, 2025
237247a
only save the 50 most recent messages
samthomson Sep 14, 2025
77ce51a
save sorting, since it ought to already be sorted
samthomson Sep 14, 2025
bd06eb3
put cache limiting things in consts
samthomson Sep 14, 2025
d32e88c
store communities with pubkey
samthomson Sep 14, 2025
d5b7786
always [osition the user menu at the bottom
samthomson Sep 14, 2025
efd3233
loading state for channels/communties
samthomson Sep 14, 2025
6b197cd
lean on datamanger for community members and permissions
samthomson Sep 14, 2025
1f42fba
channel message subscriptions and optimistic updates
samthomson Sep 14, 2025
a42b2ae
start subs from last sync
samthomson Sep 14, 2025
8e75c5d
default to stating subs now, not 5 mins ago. that made no sense
samthomson Sep 14, 2025
f00dc7a
wip: fix community settings page
samthomson Sep 14, 2025
2e202c7
subscribe to new channels
samthomson Sep 14, 2025
2db5c17
get folders from data manager
samthomson Sep 14, 2025
01848f2
routing consistent for all community pages
samthomson Sep 15, 2025
d100b02
handle edge case where a message in a new channel may arrive before t…
samthomson Sep 15, 2025
c10b1bb
commentary
samthomson Sep 15, 2025
729106a
wip subscribe to deletions and community events
samthomson Sep 15, 2025
6b6e0ab
handle community management events
samthomson Sep 15, 2025
00b81b8
handle banned members via sub
samthomson Sep 15, 2025
48e728f
ensure we have banned members exposed where expected
samthomson Sep 15, 2025
6ddce46
lint
samthomson Sep 15, 2025
47dc7b4
lint fixes
samthomson Sep 15, 2025
de84756
optimistic channels and new channel subs working again
samthomson Sep 15, 2025
b13c5b3
pointer cursor
samthomson Sep 15, 2025
1584a52
udpate channel settings modal to use data manager hooks
samthomson Sep 15, 2025
565d5c0
fix channel settings modal height
samthomson Sep 15, 2025
94180eb
update channel settings modal to use correct hooks
samthomson Sep 15, 2025
e181fdc
temporarily disable editing name/position of channel
samthomson Sep 15, 2025
a141a33
speecifically handle delete events for channels
samthomson Sep 15, 2025
aebf507
fix channel deletion event broadcast
samthomson Sep 15, 2025
bc9bc17
lint
samthomson Sep 15, 2025
7ce8c8c
temp disable position setting when creating new channel
samthomson Sep 15, 2025
3ad7cb5
wip load older messages for a channel
samthomson Sep 16, 2025
9a00bfe
return to legacy message relations
samthomson Sep 16, 2025
248ae03
udpate channel creation to use legacy ids
samthomson Sep 16, 2025
c8e685e
debug option to wipe communities cache
samthomson Sep 20, 2025
4134c4b
only legacy format for channel querying
samthomson Sep 20, 2025
4c18797
reactions via data manager
samthomson Sep 20, 2025
b6ba45a
query for pinned messages in data manager
samthomson Sep 20, 2025
df5b902
when deleting a channel remove it from the cache too
samthomson Sep 20, 2025
656d209
pending members
samthomson Sep 22, 2025
9efa932
debug pending
samthomson Sep 22, 2025
f5e5f7d
view members and manage join requests
samthomson Sep 22, 2025
f11dba3
update components from legacy hooks to data manager
samthomson Sep 22, 2025
018e083
get all community settings pages showing
samthomson Sep 22, 2025
cf64fc0
fix new channel subs
samthomson Sep 30, 2025
acd29ba
nav to new channel after creating it
samthomson Sep 30, 2025
a4fa7e5
combine community event filters
samthomson Sep 30, 2025
11fb865
fix tests
samthomson Sep 30, 2025
db2332e
lint
samthomson Oct 5, 2025
14da73d
udpate tests with provider
samthomson Oct 5, 2025
d7f771e
update tests
samthomson Oct 5, 2025
29e7012
udpate test
samthomson Oct 5, 2025
304ee20
udpate mocks in test
samthomson Oct 5, 2025
318360f
adapt tests
samthomson Oct 5, 2025
05e8a18
update mocks
samthomson Oct 5, 2025
c49aa85
Merge branch 'main' into refactor/data-manager-communities-channels
samthomson Oct 5, 2025
215655f
speed up community nav & drop now redundant preloading
samthomson Oct 5, 2025
062aa51
fix channel querying and creation to use the current - flawed - addre…
samthomson Oct 6, 2025
e5fcbd0
update proposed changes
samthomson Oct 6, 2025
ba6f3d4
fix fetching messages with legacy query format
samthomson Oct 6, 2025
97e9ebf
fix message publishing
samthomson Oct 6, 2025
bc64df7
wip reactions to channel messages
samthomson Oct 6, 2025
ed13fe7
refactor handling messages from subscriptions
samthomson Oct 6, 2025
9d40fb8
fix pagination state when mixing cached messages with new on channels…
samthomson Oct 7, 2025
90c13bf
fix - not finding general messages
samthomson Oct 7, 2025
d9e61c0
refine channel filtering
samthomson Oct 7, 2025
42e161f
++
samthomson Oct 7, 2025
9c4746b
fix pagination for general channel (needs channel specific solution)
samthomson Oct 7, 2025
66b9c09
fix pinned messages
samthomson Oct 7, 2025
9702857
load data progressively
samthomson Oct 7, 2025
dc1a08c
fire out loaded data asap
samthomson Oct 7, 2025
597d415
use community load state
samthomson Oct 7, 2025
71b5581
use more granular load state
samthomson Oct 7, 2025
19d0463
show communities as soon as we have tehm in the sidebar
samthomson Oct 7, 2025
0d9a375
update test mocks
samthomson Oct 12, 2025
dd0cfde
more test mocks, + a fix to a test which uses a diff prop now
samthomson Oct 12, 2025
8570c1a
reset communities data on relay change, and move all relay changing c…
samthomson Oct 12, 2025
c47f785
use ref to minimise compute
samthomson Oct 13, 2025
906acee
refresh both caches in the ui
samthomson Oct 13, 2025
0c0035c
fix community adding, instantly view it and create subs for it
samthomson Oct 13, 2025
9e63cfa
lint fix
samthomson Oct 13, 2025
f2b1602
condifure tests to work around window object
samthomson Oct 13, 2025
072ec20
mock community reloading in tests
samthomson Oct 13, 2025
5c1e542
fix and consolodate all community links
samthomson Oct 13, 2025
a3e3c47
nav to a community and optionally open the share modal upon creation
samthomson Oct 13, 2025
2a01432
ux fix: on the join page, give the user a way to login
samthomson Oct 13, 2025
b1c2064
request to join a community if not in it
samthomson Oct 13, 2025
0a07f0c
handle join request event in sub
samthomson Oct 13, 2025
657d7c4
join page, join request ui
samthomson Oct 13, 2025
ae740dd
show pending joined communities in left side bar
samthomson Oct 13, 2025
748aaa7
fix: load interim community data between lsat cache and now
samthomson Oct 13, 2025
6e66111
inline seed community list fetching to teh func getting all communtie…
samthomson Oct 13, 2025
796880e
fix race condition with community data used for subs after initial load
samthomson Oct 14, 2025
61f70f6
fix, once approved update a users membership immediately
samthomson Oct 14, 2025
90a3f47
make optimistic communities instantly operable and subscribed
samthomson Oct 14, 2025
212a975
remove duplicate merge. just merge one and set to the other
samthomson Oct 14, 2025
e1893bc
handle empty start - no infinite loading when the users in no communi…
samthomson Oct 14, 2025
6c213c1
auth buttons on login block screen for dms
samthomson Oct 14, 2025
384317f
smooth join UX with pending status
samthomson Oct 14, 2025
9813f37
fix hooks ordering issue on the join comunity via link page
samthomson Oct 14, 2025
885d6bc
fix, synthetic general channel on just joined community
samthomson Oct 14, 2025
111cdcc
support reseting the cache before we've even written anything - edgecase
samthomson Oct 14, 2025
9106d38
wip: convey subscrption status of the app, in the ui - and offer an e…
samthomson Oct 14, 2025
ba84654
interim status for subs before we start htem
samthomson Oct 14, 2025
6fe79d9
more subdued green
samthomson Oct 14, 2025
1c70189
keep relay connection status open as it changes
samthomson Oct 14, 2025
44d3b2b
cache/db race conditions and normalised loading statuses for early re…
samthomson Oct 15, 2025
cdbc74f
bug fix: only fetch community if we know we don't have it already (ie…
samthomson Oct 15, 2025
04691cc
memoize
samthomson Oct 15, 2025
7b7363d
darker / more visible sidebar buttons
samthomson Oct 15, 2025
473ca70
wip quadrants display for relay subscriptions
samthomson Oct 15, 2025
a011ddd
better positioing of the connectivity quadrants
samthomson Oct 15, 2025
5422460
adjust quadrant sizing/thickness
samthomson Oct 15, 2025
91bb9c9
nostr colours
samthomson Oct 15, 2025
f866296
better green
samthomson Oct 15, 2025
b55d9a3
++
samthomson Oct 15, 2025
edafda1
fix custom permissions per channel maintaining backwards compatabilit…
samthomson Oct 16, 2025
27bc377
dedupe channel permission data crunching in hook, lean on existing da…
samthomson Oct 16, 2025
cc2a94b
remove debug logs
samthomson Oct 16, 2025
bdac236
update mocks
samthomson Oct 16, 2025
a457cdd
update more mocks
samthomson Oct 16, 2025
da1f789
minor memoization
samthomson Oct 16, 2025
a586517
ux++ show auth buttons
samthomson Oct 16, 2025
4dd378e
++
samthomson Oct 16, 2025
ce9e41c
clear users state on logout
samthomson Oct 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
356 changes: 39 additions & 317 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,248 +1,24 @@
# Universes

> Explore infinite universes of communities, conversations, and connections on the decentralized web

Universes is a modern Nostr client that brings Discord-like community features to the decentralized Nostr protocol. Built with React, TypeScript, and cutting-edge web technologies, it offers a rich social experience with chat, marketplace, resources, and more.

## ✨ Features

### 🌐 **Decentralized Communities**
- Create and join communities with organized channels
- Discord-like interface with familiar UX patterns
- Real-time messaging and conversations
- Thread support for organized discussions

### 💬 **Advanced Chat System**
- Real-time messaging with typing indicators
- Message reactions and emoji support
- File uploads via Blossom servers
- Message threading and replies
- Pinned messages
- Context menus for message actions

### 🛒 **Marketplace**
- Buy and sell items with Bitcoin/Lightning
- Community-specific marketplaces
- Secure peer-to-peer transactions
- Rich product listings with media

### 📚 **Resource Sharing**
- Organize and share valuable content
- Folder-based resource management
- Community resource libraries
- Link sharing and previews

### 👥 **Social Features**
- User profiles with rich metadata
- Friend systems and social connections
- Direct messaging with NIP-44 encryption
- User status indicators
- Notification center

### 🛡️ **Moderation & Safety**
- Comprehensive moderation tools
- Admin panels and permissions
- Content reporting system
- Bulk moderation actions
- Auto-moderation settings
- Moderation logs and analytics

### 🔐 **Privacy & Security**
- NIP-44 encrypted direct messages
- Multiple account support
- Secure key management
- Privacy-focused design

### 🎨 **Modern UI/UX**
- Beautiful dark/light theme system
- Responsive design for all devices
- Smooth animations and transitions
- Accessible components with Radix UI
- Professional Discord-inspired interface
A modern Nostr client for decentralized communities with Discord-like chat. Built with React, TypeScript, and the latest Nostr protocols.

## 🚀 Quick Start

### Prerequisites

- Node.js 18+
- npm or yarn
- A Nostr identity (created automatically if needed)

### Installation

1. **Clone the repository**
```bash
git clone <repository-url>
cd universes
```

2. **Install dependencies**
```bash
npm install
```

3. **Start development server**
```bash
npm run dev
```

4. **Open your browser**
Navigate to `http://localhost:5173`

### Building for Production

```bash
npm run build
```

### Running Tests

```bash
npm test
```

## 🏗️ Technology Stack

### Core Technologies
- **React 18** - Modern React with hooks and concurrent features
- **TypeScript** - Type-safe JavaScript development
- **Vite** - Fast build tool and development server
- **TailwindCSS 3** - Utility-first CSS framework

### UI Components
- **shadcn/ui** - Beautiful, accessible components built on Radix UI
- **Radix UI** - Low-level UI primitives for accessibility
- **Lucide React** - Beautiful icon library

### Nostr Integration
- **Nostrify** - Modern Nostr framework for web applications
- **nostr-tools** - Core Nostr protocol utilities
- **NIP-44** - Encrypted direct messaging
- **NIP-19** - Bech32-encoded identifiers

### State Management
- **TanStack Query** - Powerful data fetching and caching
- **React Context** - Global app state management
- **Local Storage** - Persistent user preferences

### Development Tools
- **ESLint** - Code linting and quality
- **Vitest** - Fast unit testing
- **Testing Library** - Component testing utilities

## 📁 Project Structure

```
src/
├── components/ # Reusable UI components
│ ├── auth/ # Authentication components
│ ├── chat/ # Chat and messaging
│ ├── comments/ # Comment system
│ ├── community/ # Community management
│ ├── dm/ # Direct messaging
│ ├── layout/ # Layout components
│ ├── moderation/ # Moderation tools
│ ├── spaces/ # Marketplace & resources
│ └── ui/ # shadcn/ui components
├── hooks/ # Custom React hooks
├── pages/ # Page components
├── lib/ # Utility functions
├── contexts/ # React contexts
└── test/ # Testing utilities
```

## 🔧 Configuration

### Relay Configuration

The app connects to Nostr relays for data. Default relay is `wss://relay.nostr.band`, but users can switch between preset relays:

- **Nostr.Band** - General purpose relay
- **Damus** - Popular iOS client relay
- **Primal** - Caching relay with web client
- **Ditto** - Community-focused relay

### Theme System

Built-in light/dark theme support with system preference detection:

```typescript
import { useTheme } from '@/hooks/useTheme';

const { theme, setTheme } = useTheme();
setTheme('dark' | 'light' | 'system');
```

### Environment Variables

No environment variables required for basic functionality. The app works out-of-the-box with default Nostr relays.

## 🎯 Usage Examples

### Creating a Community

```typescript
import { useNostrPublish } from '@/hooks/useNostrPublish';

const { mutate: createEvent } = useNostrPublish();

// Create a community (NIP-72)
createEvent({
kind: 34550,
content: JSON.stringify({
name: "My Community",
about: "A place for awesome discussions",
picture: "https://example.com/image.jpg"
}),
tags: [
['d', 'my-community-id'],
['name', 'My Community'],
['about', 'A place for awesome discussions']
]
});
```

### Sending a Message

```typescript
import { useNostrPublish } from '@/hooks/useNostrPublish';

const { mutate: createEvent } = useNostrPublish();

// Send a chat message (NIP-28)
createEvent({
kind: 42,
content: "Hello, community!",
tags: [
['e', 'community-event-id', '', 'root'],
['p', 'recipient-pubkey']
]
});
git clone <repository-url>
cd universes
npm install
npm run dev
```

### Querying Events
Open `http://localhost:5173` in your browser.

```typescript
import { useNostr } from '@nostrify/react';
import { useQuery } from '@tanstack/react-query';
## 🏗️ Tech Stack

function useMessages(communityId: string) {
const { nostr } = useNostr();

return useQuery({
queryKey: ['messages', communityId],
queryFn: async ({ signal }) => {
const events = await nostr.query([{
kinds: [42],
'#e': [communityId],
limit: 50
}], { signal });

return events;
}
});
}
```
- **React 18** + **TypeScript** + **Vite**
- **TailwindCSS** + **shadcn/ui** components
- **Nostrify** + **nostr-tools** for Nostr protocol
- **TanStack Query** for data fetching

## 🔌 Nostr Protocol Features

Expand All @@ -266,94 +42,40 @@ function useMessages(communityId: string) {

The app may use custom event kinds for specific features. See `NIP.md` (if present) for documentation of any custom protocol extensions.

## 🧪 Testing
### Core Feature Implementation

| **System** | **Component** | **Event Kind(s)** | **NIP** | **Replaceable** | **Purpose** | **Key Tags** |
|------------|---------------|-------------------|---------|-------------|-------------|--------------|
| **Communities** | Community Definition | `34550` | NIP-72 | ✓ | Community metadata and moderator lists | `d` (ID), `name`, `description`, `p` (moderators) |
| | Member Management | `34551/34552/34553` | NIP-72 Ext | ✓ | Approved/declined/banned member lists | `d` (community ref), `p` (member pubkeys) |
| | | | | | *Note: Membership can be explicit (via 34551-34553 events) or implicit (community creator/moderators)* | |
| | Content Reporting | `1984` | NIP-56 | | Report content/users for moderation | `e` (target event), `p` (target user), report type |
| **Channels** | Channel Definition | `32807` | | ✓ | Channel metadata within communities | `d` (ID), `name`, `a` (`"34550:pubkey:universes"`) |
| | Channel Permissions | `30143` | | ✓ | Access control for channels | `d` (community:channel), JSON content, `p` (user permissions) |
| | Channel Messages | `9411` | NIP-28 | | Real-time chat in channels | `a` (community), `t` (channel), `e` (thread) |
| | Message Replies | `1111` | NIP-22 | | Replies to any message (9411, 1, etc.) | `e` (root message), `p` (root author) |
| | Community Posts | `1111` | NIP-22 | | Threaded discussions | `A` (root community), `e` (parent), `k` (parent kind) |
| **Direct Messages** | Legacy DMs | `4` | NIP-04 | | Simple encrypted messages | `#p` (recipient), `authors` (sender) |
| | Modern DMs | `1059` | NIP-17 | | Gift-wrapped encrypted messages | `#p` (recipient) |

#### Event Format Notes

**Current Implementation:**
- Channel community references use: `a` tag = `"34550:pubkey:communitySlug"`
- Where `communitySlug` is the human-readable name from the community's `d` tag (e.g., "universes", "bitcoin-builders")

**Proposed Future Change:**
- Use immutable unique IDs instead of slugs: `a` tag = `"34550:pubkey:uniqueId"`
- **Problem with current approach:** If a community changes its name/slug, all channel references break
- **Proposed solution:** Generate a unique, immutable ID (UUID/hash) for each community that never changes
- This would make communities renameable without breaking existing channel references

The project includes comprehensive testing setup:
## 🧪 Testing

```bash
# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage
```

### Testing Components

```typescript
import { render, screen } from '@testing-library/react';
import { TestApp } from '@/test/TestApp';
import { MyComponent } from './MyComponent';

test('renders correctly', () => {
render(
<TestApp>
<MyComponent />
</TestApp>
);

expect(screen.getByText('Expected text')).toBeInTheDocument();
});
```

## 🚀 Deployment

### GitHub Pages

```bash
npm run build
# Deploy dist/ folder to your hosting provider
```

### Nostr Deploy

```bash
npm run deploy
```

Uses `nostr-deploy-cli` to deploy directly to Nostr relays.

## 🤝 Contributing

1. Fork the repository
2. Create a feature branch: `git checkout -b feature/amazing-feature`
3. Commit changes: `git commit -m 'Add amazing feature'`
4. Push to branch: `git push origin feature/amazing-feature`
5. Open a Pull Request

### Development Guidelines

- Follow TypeScript best practices
- Use existing hooks and components when possible
- Write tests for new features
- Follow the established code style
- Update documentation for new features

## 📝 License

This project is open source. See the LICENSE file for details.

## 🙏 Acknowledgments

- **Nostr Protocol** - Decentralized social networking protocol
- **shadcn/ui** - Beautiful component library
- **Nostrify** - Modern Nostr framework
- **MKStack** - Development framework

---

**Vibed with [MKStack](https://soapbox.pub/mkstack)** ⚡

## 📞 Support

- **Documentation**: Check the `/src` folder for detailed component documentation
- **Issues**: Report bugs and feature requests via GitHub Issues
- **Community**: Join Nostr communities to connect with other users
- **Protocol**: Learn more about Nostr at [nostr.com](https://nostr.com)

---

*Explore infinite universes of communities, conversations, and connections on the decentralized web.* 🌌
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { useUnreadNotificationCount } from '@/hooks/useNotifications';
import { SettingsProvider } from '@/contexts/settings.tsx';
import { SettingsDialog } from '@/components/user/SettingsDialog';
import { DataManagerProvider } from '@/components/DataManagerProvider';
import { RelayChangeHandler } from '@/components/RelayChangeHandler';

import AppRouter from './AppRouter';

Expand Down Expand Up @@ -79,6 +80,7 @@ function AppContent() {
<SettingsProvider>
<MessageSystemProvider>
<TooltipProvider>
<RelayChangeHandler />
<QueryOptimizer />
<Toaster />
<Suspense>
Expand Down
Loading