index.tsx raw
1 import {
2 Accordion,
3 AccordionContent,
4 AccordionItem,
5 AccordionTrigger
6 } from '@/components/ui/accordion'
7 import { Keyboard, Layout, MessageSquare, Settings, User, Zap } from 'lucide-react'
8 import { useTranslation } from 'react-i18next'
9
10 export default function Help() {
11 const { t } = useTranslation()
12
13 return (
14 <div className="px-4 py-4">
15 <Accordion type="single" collapsible className="space-y-2">
16 <AccordionItem value="keyboard" className="border rounded-lg px-4">
17 <AccordionTrigger className="py-3">
18 <div className="flex items-center gap-3">
19 <Keyboard className="size-5 text-muted-foreground" />
20 <span className="font-medium">{t('Keyboard Navigation')}</span>
21 </div>
22 </AccordionTrigger>
23 <AccordionContent className="pb-4">
24 <div className="space-y-4 text-sm text-muted-foreground">
25 <p>{t('Navigate the app entirely with your keyboard:')}</p>
26 <p className="font-medium">{t('Toggle Keyboard Mode:')}</p>
27 <div className="space-y-2">
28 <KeyBinding keys={['⇧K']} description={t('Toggle keyboard navigation on/off')} />
29 <KeyBinding keys={['Esc', 'Esc', 'Esc']} description={t('Triple-Escape to quickly exit keyboard mode')} />
30 </div>
31 <p className="text-xs opacity-70">{t('You can also click the keyboard button in the sidebar to toggle.')}</p>
32 <p className="font-medium mt-4">{t('Movement:')}</p>
33 <div className="space-y-2">
34 <KeyBinding keys={['↑', '↓']} altKeys={['k', 'j']} description={t('Move between items in a list')} />
35 <KeyBinding keys={['Tab']} description={t('Switch to next column (Shift+Tab for previous)')} />
36 <KeyBinding keys={['Page Up']} description={t('Jump to top and focus first item')} />
37 </div>
38 <p className="font-medium mt-4">{t('Actions:')}</p>
39 <div className="space-y-2">
40 <KeyBinding keys={['→', 'Enter']} altKeys={['l']} description={t('Activate the selected item')} />
41 <KeyBinding keys={['←']} altKeys={['h']} description={t('Go back (close panel or move to sidebar)')} />
42 <KeyBinding keys={['Escape']} description={t('Close current view or cancel')} />
43 </div>
44 <p className="font-medium mt-4">{t('Note Actions (when a note is selected):')}</p>
45 <div className="space-y-2">
46 <KeyBinding keys={['r']} description={t('Reply')} />
47 <KeyBinding keys={['p']} description={t('Repost')} />
48 <KeyBinding keys={['q']} description={t('Quote')} />
49 <KeyBinding keys={['R']} description={t('React with emoji')} />
50 <KeyBinding keys={['z']} description={t('Zap (send sats)')} />
51 </div>
52 <p className="text-xs opacity-70 pt-2">{t('Selected items are centered on screen for easy viewing.')}</p>
53 </div>
54 </AccordionContent>
55 </AccordionItem>
56
57 <AccordionItem value="layout" className="border rounded-lg px-4">
58 <AccordionTrigger className="py-3">
59 <div className="flex items-center gap-3">
60 <Layout className="size-5 text-muted-foreground" />
61 <span className="font-medium">{t('Layout & Navigation')}</span>
62 </div>
63 </AccordionTrigger>
64 <AccordionContent className="pb-4">
65 <div className="space-y-3 text-sm text-muted-foreground">
66 <p>{t('The app uses a multi-column layout:')}</p>
67 <ul className="list-disc list-inside space-y-1.5 ml-2">
68 <li>{t('Sidebar: Quick access to main sections')}</li>
69 <li>{t('Primary column: Feed, notifications, inbox, search')}</li>
70 <li>{t('Secondary column: Note details, user profiles, relay info')}</li>
71 </ul>
72 <p>{t('On mobile or single-column mode, pages stack on top of each other.')}</p>
73 <p>{t('Use the columns button at the bottom of the sidebar to switch between layouts.')}</p>
74 </div>
75 </AccordionContent>
76 </AccordionItem>
77
78 <AccordionItem value="posting" className="border rounded-lg px-4">
79 <AccordionTrigger className="py-3">
80 <div className="flex items-center gap-3">
81 <MessageSquare className="size-5 text-muted-foreground" />
82 <span className="font-medium">{t('Posting & Interactions')}</span>
83 </div>
84 </AccordionTrigger>
85 <AccordionContent className="pb-4">
86 <div className="space-y-3 text-sm text-muted-foreground">
87 <p><strong>{t('Creating Posts:')}</strong></p>
88 <ul className="list-disc list-inside space-y-1.5 ml-2">
89 <li>{t('Click the post button in the sidebar to compose a new note')}</li>
90 <li>{t('Use @ to mention users and # for hashtags')}</li>
91 <li>{t('Drag and drop images or use the attachment button')}</li>
92 </ul>
93 <p className="pt-2"><strong>{t('Interacting with Notes:')}</strong></p>
94 <ul className="list-disc list-inside space-y-1.5 ml-2">
95 <li>{t('Reply: Continue the conversation')}</li>
96 <li>{t('Repost: Share to your followers')}</li>
97 <li>{t('Quote: Repost with your own comment')}</li>
98 <li>{t('React: Like or add emoji reactions')}</li>
99 <li>{t('Zap: Send Bitcoin tips via Lightning')}</li>
100 </ul>
101 </div>
102 </AccordionContent>
103 </AccordionItem>
104
105 <AccordionItem value="zaps" className="border rounded-lg px-4">
106 <AccordionTrigger className="py-3">
107 <div className="flex items-center gap-3">
108 <Zap className="size-5 text-muted-foreground" />
109 <span className="font-medium">{t('Zaps & Lightning')}</span>
110 </div>
111 </AccordionTrigger>
112 <AccordionContent className="pb-4">
113 <div className="space-y-3 text-sm text-muted-foreground">
114 <p>{t('Zaps are Bitcoin tips sent via the Lightning Network:')}</p>
115 <ul className="list-disc list-inside space-y-1.5 ml-2">
116 <li>{t('To receive zaps, add a Lightning address to your profile')}</li>
117 <li>{t('To send zaps, connect a Lightning wallet in Settings')}</li>
118 <li>{t('Click the zap icon on any note to send sats')}</li>
119 <li>{t('Long-press for custom zap amounts')}</li>
120 </ul>
121 <p className="pt-2">{t('Supported wallets include Alby, NWC-compatible wallets, and Cashu mints.')}</p>
122 </div>
123 </AccordionContent>
124 </AccordionItem>
125
126 <AccordionItem value="accounts" className="border rounded-lg px-4">
127 <AccordionTrigger className="py-3">
128 <div className="flex items-center gap-3">
129 <User className="size-5 text-muted-foreground" />
130 <span className="font-medium">{t('Account & Login')}</span>
131 </div>
132 </AccordionTrigger>
133 <AccordionContent className="pb-4">
134 <div className="space-y-3 text-sm text-muted-foreground">
135 <p>{t('Nostr uses public/private key pairs for identity:')}</p>
136 <ul className="list-disc list-inside space-y-1.5 ml-2">
137 <li><strong>npub</strong>: {t('Your public key (share freely)')}</li>
138 <li><strong>nsec</strong>: {t('Your private key (keep secret!)')}</li>
139 </ul>
140 <p className="pt-2"><strong>{t('Login Methods:')}</strong></p>
141 <ul className="list-disc list-inside space-y-1.5 ml-2">
142 <li><strong>{t('Browser Extension (NIP-07)')}</strong>: {t('Recommended. Uses extensions like Alby or nos2x')}</li>
143 <li><strong>{t('Remote Signer (NIP-46)')}</strong>: {t('Connect to bunker signers like Amber or nsecBunker')}</li>
144 <li><strong>{t('Private Key')}</strong>: {t('Enter nsec directly (less secure)')}</li>
145 <li><strong>{t('View Only')}</strong>: {t('Browse with an npub without signing')}</li>
146 </ul>
147 </div>
148 </AccordionContent>
149 </AccordionItem>
150
151 <AccordionItem value="settings" className="border rounded-lg px-4">
152 <AccordionTrigger className="py-3">
153 <div className="flex items-center gap-3">
154 <Settings className="size-5 text-muted-foreground" />
155 <span className="font-medium">{t('Settings Overview')}</span>
156 </div>
157 </AccordionTrigger>
158 <AccordionContent className="pb-4">
159 <div className="space-y-3 text-sm text-muted-foreground">
160 <ul className="list-disc list-inside space-y-1.5 ml-2">
161 <li><strong>{t('General')}</strong>: {t('Language, content preferences, mutes')}</li>
162 <li><strong>{t('Appearance')}</strong>: {t('Theme, layout, visual options')}</li>
163 <li><strong>{t('Relays')}</strong>: {t('Configure which relays to read from and write to')}</li>
164 <li><strong>{t('Posts')}</strong>: {t('Posting preferences and default settings')}</li>
165 <li><strong>{t('Wallet')}</strong>: {t('Lightning wallet connection for zaps')}</li>
166 <li><strong>{t('Emoji Packs')}</strong>: {t('Custom emoji sets')}</li>
167 <li><strong>{t('System')}</strong>: {t('Debug tools and app information')}</li>
168 </ul>
169 </div>
170 </AccordionContent>
171 </AccordionItem>
172 </Accordion>
173 </div>
174 )
175 }
176
177 function KeyBinding({
178 keys,
179 altKeys,
180 description
181 }: {
182 keys: string[]
183 altKeys?: string[]
184 description: string
185 }) {
186 return (
187 <div className="flex items-center gap-3">
188 <div className="flex items-center gap-1">
189 {keys.map((key) => (
190 <kbd key={key} className="px-2 py-1 text-xs font-mono bg-muted border rounded">
191 {key}
192 </kbd>
193 ))}
194 {altKeys && (
195 <>
196 <span className="text-xs text-muted-foreground mx-1">/</span>
197 {altKeys.map((key) => (
198 <kbd key={key} className="px-2 py-1 text-xs font-mono bg-muted border rounded">
199 {key}
200 </kbd>
201 ))}
202 </>
203 )}
204 </div>
205 <span>{description}</span>
206 </div>
207 )
208 }
209