From b975e55794aec301dd0d39f381b9fd8dcb4ef9d4 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 23 May 2026 12:31:45 -0500 Subject: [PATCH] chore: delete unreachable page files Removes 34 page components no longer routed from AppRouter: content-type feeds (Photos, Videos, Music, Vines, Podcasts, Books, Treasures, Webxdc, World, Badges, Verified, Archive, Bluesky, Wikipedia), social/utility pages (Messages, Trends, UserLists, Bookmarks, AIChat, Follow, Receive), content creation (CreateEvent, ArticleEditor, LetterCompose), settings (ContentSettings, LetterPreferences), letter system pages, relay/domain feeds, and the now-orphaned KindFeedPage base. --- src/pages/AIChatPage.tsx | 534 ------------ src/pages/ArchivePage.tsx | 741 ----------------- src/pages/ArticleEditorPage.tsx | 136 --- src/pages/BadgesPage.tsx | 1198 --------------------------- src/pages/BlueskyPage.tsx | 629 -------------- src/pages/BookmarksPage.tsx | 101 --- src/pages/BooksPage.tsx | 348 -------- src/pages/ContentSettingsPage.tsx | 34 - src/pages/CreateEventPage.tsx | 490 ----------- src/pages/DomainFeedPage.tsx | 158 ---- src/pages/EventsFeedPage.tsx | 207 ----- src/pages/FollowPage.tsx | 563 ------------- src/pages/KindFeedPage.tsx | 75 -- src/pages/LetterComposePage.tsx | 23 - src/pages/LetterPreferencesPage.tsx | 15 - src/pages/LettersPage.tsx | 200 ----- src/pages/Messages.tsx | 42 - src/pages/MusicFeedPage.tsx | 18 - src/pages/MusicPage.tsx | 77 -- src/pages/PhotosFeedPage.tsx | 179 ---- src/pages/PlaceholderPage.tsx | 27 - src/pages/PodcastsFeedPage.tsx | 18 - src/pages/ReceivePage.tsx | 180 ---- src/pages/RelayPage.tsx | 291 ------- src/pages/StreamsFeedPage.tsx | 230 ----- src/pages/TreasuresPage.tsx | 26 - src/pages/TrendsPage.tsx | 236 ------ src/pages/UserListsPage.tsx | 332 -------- src/pages/VerifiedPage.tsx | 62 -- src/pages/VideosFeedPage.tsx | 1012 ---------------------- src/pages/VinesFeedPage.tsx | 1123 ------------------------- src/pages/WebxdcFeedPage.tsx | 28 - src/pages/WikipediaPage.tsx | 786 ------------------ src/pages/WorldPage.tsx | 99 --- 34 files changed, 10218 deletions(-) delete mode 100644 src/pages/AIChatPage.tsx delete mode 100644 src/pages/ArchivePage.tsx delete mode 100644 src/pages/ArticleEditorPage.tsx delete mode 100644 src/pages/BadgesPage.tsx delete mode 100644 src/pages/BlueskyPage.tsx delete mode 100644 src/pages/BookmarksPage.tsx delete mode 100644 src/pages/BooksPage.tsx delete mode 100644 src/pages/ContentSettingsPage.tsx delete mode 100644 src/pages/CreateEventPage.tsx delete mode 100644 src/pages/DomainFeedPage.tsx delete mode 100644 src/pages/EventsFeedPage.tsx delete mode 100644 src/pages/FollowPage.tsx delete mode 100644 src/pages/KindFeedPage.tsx delete mode 100644 src/pages/LetterComposePage.tsx delete mode 100644 src/pages/LetterPreferencesPage.tsx delete mode 100644 src/pages/LettersPage.tsx delete mode 100644 src/pages/Messages.tsx delete mode 100644 src/pages/MusicFeedPage.tsx delete mode 100644 src/pages/MusicPage.tsx delete mode 100644 src/pages/PhotosFeedPage.tsx delete mode 100644 src/pages/PlaceholderPage.tsx delete mode 100644 src/pages/PodcastsFeedPage.tsx delete mode 100644 src/pages/ReceivePage.tsx delete mode 100644 src/pages/RelayPage.tsx delete mode 100644 src/pages/StreamsFeedPage.tsx delete mode 100644 src/pages/TreasuresPage.tsx delete mode 100644 src/pages/TrendsPage.tsx delete mode 100644 src/pages/UserListsPage.tsx delete mode 100644 src/pages/VerifiedPage.tsx delete mode 100644 src/pages/VideosFeedPage.tsx delete mode 100644 src/pages/VinesFeedPage.tsx delete mode 100644 src/pages/WebxdcFeedPage.tsx delete mode 100644 src/pages/WikipediaPage.tsx delete mode 100644 src/pages/WorldPage.tsx diff --git a/src/pages/AIChatPage.tsx b/src/pages/AIChatPage.tsx deleted file mode 100644 index 4ef656f1..00000000 --- a/src/pages/AIChatPage.tsx +++ /dev/null @@ -1,534 +0,0 @@ -import { useMemo, useRef, useState, useEffect, useCallback } from 'react'; -import { useSeoMeta } from '@unhead/react'; -import Markdown from 'react-markdown'; -import rehypeSanitize from 'rehype-sanitize'; -import { Bot, Loader2, Send, Square, Trash2 } from 'lucide-react'; - -import { PageHeader } from '@/components/PageHeader'; -import { useCurrentUser } from '@/hooks/useCurrentUser'; -import { useAppContext } from '@/hooks/useAppContext'; -import { useAIChatSession } from '@/hooks/useAIChatSession'; -import { LoginArea } from '@/components/auth/LoginArea'; -import { Button } from '@/components/ui/button'; -import { Textarea } from '@/components/ui/textarea'; -import { ScrollArea } from '@/components/ui/scroll-area'; -import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; -import { cn } from '@/lib/utils'; -import { useLayoutOptions } from '@/contexts/LayoutContext'; - -import type { DisplayMessage, ToolCall } from '@/lib/aiChatTools'; - -// ─── Slash Commands ─── - -const SLASH_COMMANDS = [ - { command: '/clear', description: 'Clear conversation history' }, - { command: '/new', description: 'Start a new conversation' }, - { command: '/tools', description: 'List available tools' }, -]; - -// ─── Page Component ─── - -export function AIChatPage() { - const { config } = useAppContext(); - const { user } = useCurrentUser(); - - useSeoMeta({ - title: `Agent | ${config.appName}`, - description: 'Chat with your AI agent', - }); - - useLayoutOptions({ noOverscroll: true }); - - if (!user) { - return ( -
-
- -
-

Agent

-

Log in with your Nostr account to start using the Agent.

-
- -
-
- ); - } - - return ; -} - -// ─── Chat View ─── - -function AgentChatView() { - const { - messages, - input, - setInput, - isStreaming, - streamingText, - selectedModel, - apiLoading, - apiError, - messagesEndRef, - capacity, - lastPromptTokens, - contextWindow, - storageBytes, - maxStorageBytes, - handleSend, - handleStop, - handleKeyDown, - handleClear, - } = useAIChatSession(); - - return ( -
- {/* Header */} - - -

Agent

- - }> -
- - -
-
- - {/* Messages Area */} - {messages.length === 0 && !streamingText ? ( -
- -
- ) : ( - -
- {messages.map((msg) => ( - msg.role !== 'tool_result' && - ))} - - {/* Streaming text */} - {streamingText && ( -
-
-
-
- - {streamingText} - -
-
-
-
- )} - - {/* Loading indicator */} - {(isStreaming || apiLoading) && !streamingText && } - - {/* Error display */} - {apiError && ( - apiError.includes('run out of credits') ? ( - - ) : apiError.includes('Rate limited') ? ( - - ) : null - )} - -
-
- - )} - - {/* Input Area */} -
-
- - {isStreaming ? ( - - ) : ( - - )} -
-
-
- ); -} - -// ─── Sub-Components ─── - -function ThinkingIndicator() { - return ( -
-
- - Thinking... -
-
- ); -} - -function ErrorBanner({ heading, body }: { heading: string; body: string }) { - return ( -
-

{heading}

-

{body}

-
- ); -} - -const AGENT_GREETINGS = [ - "How can I help you today?", - "What would you like to know?", - "Ready when you are.", -]; - -const SUGGESTIONS = [ - "What are my friends talking about?", - "What's happening in the world?", -]; - -function EmptyState({ onSuggestion }: { onSuggestion: (text: string) => void }) { - const greeting = useMemo(() => AGENT_GREETINGS[Math.floor(Math.random() * AGENT_GREETINGS.length)], []); - - return ( -
- -
-

Agent

-

{greeting}

-
- -
- {SUGGESTIONS.map((s) => ( - - ))} -
-
- ); -} - -function MessageBubble({ message }: { message: DisplayMessage }) { - const isUser = message.role === 'user'; - - // System notices — info vs error styling - if (message.noticeVariant) { - const isError = message.noticeVariant === 'error'; - return ( -
-
-
-
- - {message.content} - -
-
-
-
- ); - } - - return ( -
-
- {/* Hide the bubble entirely when the assistant message is empty (tool-only turn) */} - {(isUser || message.content.trim()) && ( -
- {isUser ? ( -

{message.content}

- ) : ( -
- - {message.content} - -
- )} -
- )} - - {/* Tool call indicators */} - {message.toolCalls && message.toolCalls.length > 0 && ( -
- {message.toolCalls.map((tc) => ( - - ))} -
- )} - - - {message.timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} - -
-
- ); -} - -/** Text input with a slash-command autocomplete dropdown. */ -function SlashCommandInput({ value, onChange, onKeyDown, onSend, placeholder, disabled }: { - value: string; - onChange: (v: string) => void; - onKeyDown: (e: React.KeyboardEvent) => void; - onSend: (override?: string) => void; - placeholder?: string; - disabled?: boolean; -}) { - const wrapperRef = useRef(null); - const [selectedIndex, setSelectedIndex] = useState(0); - const [menuDismissed, setMenuDismissed] = useState(false); - - // Filter commands based on input - const matches = useMemo(() => { - if (!value.startsWith('/') || menuDismissed) return []; - const typed = value.toLowerCase(); - return SLASH_COMMANDS.filter((c) => c.command.startsWith(typed)); - }, [value, menuDismissed]); - - const showMenu = matches.length > 0 && !disabled; - - // Reset selection when matches change - useEffect(() => { - setSelectedIndex(0); - }, [matches.length]); - - // Un-dismiss when input stops being a slash command or is cleared - useEffect(() => { - if (!value.startsWith('/')) setMenuDismissed(false); - }, [value]); - - // Close menu on outside click - useEffect(() => { - if (!showMenu) return; - const handler = (e: MouseEvent) => { - if (wrapperRef.current && !wrapperRef.current.contains(e.target as Node)) { - setMenuDismissed(true); - } - }; - document.addEventListener('mousedown', handler); - return () => document.removeEventListener('mousedown', handler); - }, [showMenu]); - - const selectCommand = useCallback((cmd: string) => { - onChange(cmd); - setMenuDismissed(true); - // Auto-send slash commands immediately - onSend(cmd); - }, [onChange, onSend]); - - const handleKeyDown = useCallback((e: React.KeyboardEvent) => { - if (showMenu) { - if (e.key === 'ArrowUp') { - e.preventDefault(); - setSelectedIndex((i) => (i - 1 + matches.length) % matches.length); - return; - } - if (e.key === 'ArrowDown') { - e.preventDefault(); - setSelectedIndex((i) => (i + 1) % matches.length); - return; - } - if (e.key === 'Tab' || (e.key === 'Enter' && !e.shiftKey)) { - e.preventDefault(); - selectCommand(matches[selectedIndex].command); - return; - } - if (e.key === 'Escape') { - e.preventDefault(); - setMenuDismissed(true); - return; - } - } - // Fall through to parent handler (Enter → send, etc.) - onKeyDown(e); - }, [showMenu, matches, selectedIndex, selectCommand, onKeyDown]); - - return ( -
- {/* Autocomplete menu */} - {showMenu && ( -
- {matches.map((cmd, i) => ( - - ))} -
- )} -