14 KiB
TODO
Known Issues
RTL Support in Rich Text
Priority: Medium
File: src/components/nostr/RichText/Text.tsx
Current RTL implementation is partial and has limitations:
- RTL text direction works (
dirattribute on spans) - RTL text alignment (right-align) doesn't work properly with inline elements
- Mixed LTR/RTL content with inline elements (hashtags, mentions) creates layout conflicts
The core problem:
- Inline elements (hashtags, mentions) need inline flow to stay on same line
- RTL alignment requires block-level containers
- These two requirements conflict
Potential solutions to explore:
- Line-aware rendering at RichText component level (parse and group by lines)
- CSS-based approach with unicode-bidi and direction properties
- Separate rendering paths for pure RTL content vs mixed content
- Accept partial RTL support and document limitations
Test case: Arabic text with hashtags on same line should display properly with right-alignment.
Live Mode Reliability
Priority: High
File: src/components/ReqViewer.tsx
Issues:
- Live mode sometimes stops updating (gets stuck)
- May be related to reconnection on errors
- Compact live indicator needed for better UX
Investigation needed: Check relay reconnection logic and subscription lifecycle.
Rendering Issues
Priority: Medium
- Window crashes on unsupported kind event - Need graceful error handling for unknown kinds
- Nested lists in Markdown should be padded - Markdown renderer spacing issue
- Text rendering: Avoid inserting
<br>tags, investigate noStrudel's EOL metadata approach - JSON viewer scrolling: Expandable JSON in event details cannot be scrolled when content exceeds available height - needs overflow handling
Command Palette / UX Improvements
Enter Key Behavior
When selecting an action from the dropdown, pressing Enter should insert the command at the beginning of the command line (currently requires manual typing).
Command Options Display
When an action is entered, show the list of available options below and provide auto-completion for flags/arguments.
Feature Requests
Command History
Priority: High
- Remember command history across sessions
- Allow editing a selected command before executing
- Arrow up/down navigation through history
Column Command Editing
Priority: Medium
- Allow users to edit the command that defines a column/window
- Useful for adjusting filters without recreating the window
NIP-05 and Name Autocomplete
Priority: Medium File: Command parser, author flag handler
- Autocomplete NIP-05 identifiers when using
--authorflag - Autocomplete by display name from cached profiles
- Improve discoverability of user identifiers
Generic Feed Command
Priority: Low
Description: Add a feed command to show the full personalized feed for the logged-in user.
Note: May be "too much" for this tool's focused approach - consider carefully whether it fits the Unix philosophy.
Column Sharing
Priority: Medium Description:
- Export a column definition (command + relays + filters) as shareable JSON/URL
- Import column definitions from others
- Enable sharing of useful views and configurations
Per-Column Theming
Priority: Low Description: Allow setting background color or theme for individual columns, helping visually organize workspace.
Planned Improvements
- App-wide error boundary - Splash crash screen for unhandled errors
- Collapsible relay list - Show user relay links without inbox/outbox icons initially
- NIP badges everywhere - Use consistent NIP badge components for linking to NIP documentation
- External spec event kind support - Add references and documentation links for commented-out event kinds from external specs (Blossom, Marmot Protocol, NKBIP, nostrocket, Corny Chat, NUD, etc.) in
src/constants/kinds.ts. Consider adding a separate registry or documentation for non-official-NIP event kinds.
NIP-22 Comment Threading Support
Priority: High
Files: src/components/nostr/kinds/Kind1Renderer.tsx, potentially new Kind1111Renderer.tsx
Current State:
- Kind 1111 (Comment) is registered in constants with MessageCircle icon
- Kind 1111 currently falls back to DefaultKindRenderer (just shows raw content)
- Kind1Renderer only handles NIP-10 threading (kind 1 notes), not NIP-22 comments
NIP-22 Requirements:
- Kind 1111 events are not replies to kind 1 notes - they use a different threading model
- Comments MUST use uppercase tags (K, E, A, I, P) for root scope
- Comments MUST use lowercase tags (k, e, a, i, p) for parent item
- Comments can thread on:
- Nostr events (using E/e, A/a tags with K/k for kinds, P/p for authors)
- External identifiers (using I/i tags with K/k for types - URLs, podcast GUIDs, etc.)
- Comments MUST NOT reply to kind 1 notes (NIP-10 should be used instead)
Implementation Tasks:
-
Create Kind1111Renderer component:
- Parse uppercase tags (K, E, A, I, P) to identify root scope
- Parse lowercase tags (k, e, a, i, p) to identify parent item
- Display comment content with RichText (plaintext only, no HTML/Markdown per spec)
- Show "replying to" context with appropriate UI based on tag types:
- For E/e tags: Fetch and display parent nostr event
- For A/a tags: Fetch and display addressable event
- For I/i tags: Display external identifier (URL, podcast, etc.)
- Handle nested comment threading (when parent is also kind 1111)
- Show root context indicator (what the comment thread is about)
-
Tag Parsing Utilities (potentially in
src/lib/nip22.ts):getRootScope(event)- extracts K, E, A, or I tagsgetParentItem(event)- extracts k, e, a, or i tagsgetRootAuthor(event)- extracts P taggetParentAuthor(event)- extracts p tagisTopLevelComment(event)- checks if root === parent- Helper to determine comment type (event comment vs external identifier comment)
-
UI Components:
- Comment thread visualization (show depth/nesting)
- Root context banner (e.g., "Comment on article", "Comment on podcast episode")
- External identifier display (for I tags - URLs, podcasts, etc.)
- Parent comment preview (for nested threads)
- Kind badge display (show what kind of event is being commented on)
-
Integration Points:
- Update kind registry to use Kind1111Renderer
- Consider how comments relate to other viewers (e.g., showing comments on a 30023 article)
- Timeline/feed integration (how to display comment threads)
- Reply UI for creating new comments
-
Edge Cases to Handle:
- Comments on replaceable/addressable events (both
aandetags present) - Comments on external identifiers without nostr events
- Comments with q tags (quote references)
- Invalid comment structure (missing required K/k tags)
- Mixed case handling and validation
- Comments on replaceable/addressable events (both
-
Testing Scenarios:
- Top-level comment on blog post (kind 30023)
- Top-level comment on file (kind 1063)
- Nested reply to another comment (kind 1111 → 1111)
- Comment on external URL (I tag with "web" type)
- Comment on podcast episode (I tag with podcast GUID)
- Validation: ensure kind 1 notes don't use kind 1111 (should fail/warn)
References:
- NIP-22 Spec
- NIP-73 External Identities (for I/i tag types)
- NIP-10 Threading (for contrast - what NOT to do)
Note: This is a significant feature requiring careful attention to the threading model differences between NIP-10 (kind 1 notes) and NIP-22 (kind 1111 comments).
Event Rendering System Improvements
Reference: See claudedocs/event-rendering-system-analysis.md for comprehensive analysis
Phase 1: Foundation Fixes (1-2 weeks)
Goal: Fix critical architectural issues and quick wins
1.1 Unified Detail Renderer Registry
Priority: High | Effort: Low
Files: src/components/nostr/kinds/index.tsx, src/components/EventDetailViewer.tsx
Problem: EventDetailViewer uses hardcoded switch statement instead of registry pattern
// Current anti-pattern:
event.kind === kinds.Metadata ? <Kind0DetailRenderer />
: event.kind === kinds.Contacts ? <Kind3DetailView />
Solution: Create detailRenderers map parallel to kindRenderers with fallback logic
1.2 Systematic Depth Tracking
Priority: High | Effort: Medium
Files: All *Renderer.tsx files
Problem: Depth tracking inconsistent - can cause infinite loops in Kind6Renderer (reposts), Kind9735Renderer (zaps)
Solution:
- Add
MAX_EMBED_DEPTH = 3constant - Update
BaseEventPropsto require depth - Audit all renderers using
EmbeddedEvent - Implement
CollapsedPreviewcomponent for max depth exceeded
1.3 Error Boundaries
Priority: High | Effort: Low
File: src/components/EventErrorBoundary.tsx
Problem: One broken event crashes entire feed
Solution: Create EventErrorBoundary component wrapping all events with diagnostic error cards
1.4 Renderer Memoization
Priority: Medium | Effort: Low
Files: All *Renderer.tsx files
Problem: Renderers recalculate on every parent render - no performance optimization
Solution:
- Wrap all renderer components with
React.memo - Add
useMemofor expensive computations (parsing, extraction) - Add
useCallbackfor event handlers
Phase 2: Component Library (2-3 weeks)
Goal: Build reusable abstractions for common patterns
2.1 Generic Threading Components
Priority: High | Effort: High
Files: src/lib/threading.ts, src/components/Thread/
Problem: Only NIP-10 threading supported, need NIP-22, NIP-28, NIP-29
Solution: Create abstraction layer
getThreadReferences()helper supporting multiple NIPs<ThreadIndicator>component (universal "replying to")<ThreadContext>for parent preview<ThreadTree>for detail view reply chains
Related: Works with NIP-22 Comment Support (existing TODO)
2.2 Relationship Panels
Priority: Medium | Effort: Medium
Files: src/components/nostr/Relationships/
Problem: Detail views don't show replies, zaps, reactions
Solution: Create reusable relationship components
<RepliesPanel>- Show replies to event<ZapsPanel>- Show zaps with total/list<ReactionsPanel>- Group reactions by emoji<EngagementFooter>- Universal engagement indicators
2.3 Enhanced Media Components
Priority: Medium | Effort: Medium
Files: src/components/nostr/MediaEmbed.tsx
Problem: No multi-stage rendering, no lazy loading, no NSFW handling
Solution: Enhance MediaEmbed with
- Multi-stage rendering (placeholder → thumbnail → full → error)
- Lazy loading with IntersectionObserver
- NSFW blur with content-warning tag support
- Quality selection for videos
- Accessibility improvements (alt text, captions)
2.4 Context-Aware Rendering
Priority: Medium | Effort: Low
Files: src/components/nostr/kinds/index.tsx, all renderers
Problem: Same rendering for feed, detail, and embed contexts
Solution: Add context prop to BaseEventProps, renderers adapt display
Phase 3: Architecture Evolution (3-4 weeks)
Goal: Transform into production-grade framework
3.1 Performance Optimization
Priority: High | Effort: Medium
Files: src/components/ReqViewer.tsx, EventDetailViewer.tsx
Target: Feed with 10,000 events scrolls at 60fps
Tasks:
- Virtual scrolling with react-virtuoso
- Code splitting for detail renderers (lazy load)
- Batch profile fetching (avoid N+1 queries)
- Suspense boundaries for async content
- Performance monitoring
3.2 Helper Library Expansion
Priority: High | Effort: High
Files: src/lib/helpers/ directory
Problem: Many renderers parse tags manually instead of using helpers
Solution: Create helpers for all NIPs
- File metadata (1063): url, hash, size, mime, dimensions
- Media events (20, 21, 22): URLs, thumbnails, dimensions
- Lists (30000+): systematic list item extraction
- Reposts (6, 16, 18): reposted event extraction
- Highlights (9802): context, highlight text
- Calendar (31922-31925): date/time parsing
- Polls (1068): options, votes, tally
Note: Submit generic ones to applesauce-core upstream
3.3 Accessibility Improvements
Priority: Medium | Effort: Medium Files: All renderers, BaseEventContainer
Target: WCAG AA compliance
Tasks:
- Semantic HTML (
<article>,<time>, proper headings) - ARIA labels and roles (
role="feed",aria-labelon actions) - Keyboard navigation system (arrow keys, enter, escape)
- Focus management (modals, detail views)
- Screen reader testing and fixes
- Color contrast audit
3.4 Internationalization
Priority: Medium | Effort: Medium Files: Setup i18n infrastructure, translate all components
Problem: Hardcoded English strings, inconsistent locale usage
Solution:
- i18next integration
- Extract all hardcoded strings
- Locale-aware number/date formatting (zap amounts, timestamps)
- Kind name translations
- RTL support improvements (related to existing RTL TODO)
3.5 Composable Renderer System
Priority: Medium | Effort: High Files: Refactor complex renderers
Problem: Renderers are monolithic, hard to reuse pieces
Solution: Break into smaller components
- Content components (primary payload display)
- Metadata components (structured data display)
- Relationship components (connections/replies)
- Action components (user interactions)
- Enable mix-and-match composition