story-research-zapwall/lib/nostrSubscription.ts
Nicolas Cantu cc49c9d7c1 Add language preference selector in settings
**Motivations:**
- Allow users to set their preferred language (fr/en) in the settings page
- Load language preference from localStorage at startup to configure the application locale

**Root causes:**
- Language preference was only available in the header via LanguageSelector component
- Language preference was stored in IndexedDB instead of localStorage
- No centralized language settings management in the settings page

**Correctifs:**
- Created LanguageSettingsManager component for settings page
- Migrated language storage from IndexedDB to localStorage for consistency
- Updated _app.tsx to load locale from localStorage synchronously at startup
- Updated useI18n hook to use localStorage instead of IndexedDB
- Updated LanguageSelector component to use localStorage instead of IndexedDB

**Evolutions:**
- Added language preference section in settings page (displayed first)
- Language preference is now loaded at application startup from localStorage
- Added translations for language settings (settings.language.*)

**Pages affectées:**
- components/LanguageSettingsManager.tsx (new)
- pages/settings.tsx
- pages/_app.tsx
- hooks/useI18n.ts
- components/LanguageSelector.tsx
- locales/fr.txt
- locales/en.txt
2026-01-06 14:57:38 +01:00

48 lines
1.2 KiB
TypeScript

import type { Event, Filter } from 'nostr-tools'
import { SimplePool } from 'nostr-tools'
import { getPrimaryRelaySync } from './config'
import { createSubscription } from '@/types/nostr-tools-extended'
/**
* Subscribe to events with timeout
* Supports both sync and async parsers
*/
export function subscribeWithTimeout<T>(
pool: SimplePool,
filters: Filter[],
parser: (event: Event) => T | null | Promise<T | null>,
timeout: number = 5000
): Promise<T | null> {
return new Promise((resolve) => {
const resolved = { value: false }
const relayUrl = getPrimaryRelaySync()
const sub = createSubscription(pool, [relayUrl], filters)
let timeoutId: NodeJS.Timeout | null = null
const cleanup = (): void => {
if (timeoutId) {
clearTimeout(timeoutId)
}
sub.unsub()
}
const resolveOnce = (value: T | null): void => {
if (resolved.value) {
return
}
resolved.value = true
cleanup()
resolve(value)
}
sub.on('event', async (event: Event): Promise<void> => {
const result = await parser(event)
resolveOnce(result)
})
sub.on('eose', (): void => {
resolveOnce(null)
})
timeoutId = setTimeout(() => resolveOnce(null), timeout)
})
}