refactor: improve nostr connection and message handling
- Add WebSocket manager class for better connection handling - Split message handling into separate store - Add encryption service class - Create chat composable for reusable chat logic - Add error handling service - Add connection status indicators throughout app - Add message persistence service - Improve subscription reliability with EOSE handling - Add connection state management - Hide status text on mobile for better space usage These changes improve code organization, reliability, and user experience by: - Better separation of concerns - More robust error handling - Clearer connection status feedback - Improved message persistence - More maintainable WebSocket management - Better mobile responsiveness Breaking changes: - Message handling moved to separate store - WebSocket connections now managed through NostrWebSocketManager - Encryption now handled through NostrEncryption service
This commit is contained in:
parent
be93965e13
commit
5eb46e96c3
11 changed files with 169 additions and 26 deletions
9
src/lib/encryption.ts
Normal file
9
src/lib/encryption.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export class NostrEncryption {
|
||||
static async encrypt(privkey: string, pubkey: string, content: string) {
|
||||
return await window.NostrTools.nip04.encrypt(privkey, pubkey, content)
|
||||
}
|
||||
|
||||
static async decrypt(privkey: string, pubkey: string, content: string) {
|
||||
return await window.NostrTools.nip04.decrypt(privkey, pubkey, content)
|
||||
}
|
||||
}
|
||||
14
src/lib/error.ts
Normal file
14
src/lib/error.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
export class ErrorHandler {
|
||||
static handle(error: unknown, context: string) {
|
||||
console.error(`Error in ${context}:`, error)
|
||||
|
||||
if (error instanceof Error) {
|
||||
// Handle specific error types
|
||||
if (error.name === 'TimeoutError') {
|
||||
return 'Connection timed out. Please try again.'
|
||||
}
|
||||
}
|
||||
|
||||
return 'An unexpected error occurred'
|
||||
}
|
||||
}
|
||||
22
src/lib/storage.ts
Normal file
22
src/lib/storage.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
export class MessageStorage {
|
||||
static saveMessages(pubkey: string, messages: DirectMessage[]) {
|
||||
try {
|
||||
localStorage.setItem(
|
||||
`messages_${pubkey}`,
|
||||
JSON.stringify(messages)
|
||||
)
|
||||
} catch (err) {
|
||||
console.error('Failed to save messages:', err)
|
||||
}
|
||||
}
|
||||
|
||||
static loadMessages(pubkey: string): DirectMessage[] {
|
||||
try {
|
||||
const stored = localStorage.getItem(`messages_${pubkey}`)
|
||||
return stored ? JSON.parse(stored) : []
|
||||
} catch (err) {
|
||||
console.error('Failed to load messages:', err)
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src/lib/websocket.ts
Normal file
35
src/lib/websocket.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Create a new WebSocket manager class
|
||||
export class NostrWebSocketManager {
|
||||
private connections: Map<string, any> = new Map()
|
||||
private subscriptions: Map<string, any[]> = new Map()
|
||||
|
||||
async connect(url: string) {
|
||||
if (this.connections.has(url)) return this.connections.get(url)
|
||||
|
||||
const relay = window.NostrTools.relayInit(url)
|
||||
try {
|
||||
await relay.connect()
|
||||
this.connections.set(url, relay)
|
||||
this.subscriptions.set(url, [])
|
||||
return relay
|
||||
} catch (err) {
|
||||
console.error(`Failed to connect to ${url}:`, err)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
addSubscription(url: string, sub: any) {
|
||||
const subs = this.subscriptions.get(url) || []
|
||||
subs.push(sub)
|
||||
this.subscriptions.set(url, subs)
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
for (const [url, subs] of this.subscriptions.entries()) {
|
||||
subs.forEach(sub => sub.unsub?.())
|
||||
this.connections.get(url)?.close()
|
||||
}
|
||||
this.connections.clear()
|
||||
this.subscriptions.clear()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue