refactor: remove all console.log debug output

This commit is contained in:
Gigi
2025-10-19 22:35:45 +02:00
parent 1c21615103
commit 4202807777
58 changed files with 11 additions and 411 deletions

View File

@@ -215,7 +215,6 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
const debugEnabled = req.query.debug === '1' || req.headers['x-boris-debug'] === '1' const debugEnabled = req.query.debug === '1' || req.headers['x-boris-debug'] === '1'
if (debugEnabled) { if (debugEnabled) {
console.log('[article-og] request', JSON.stringify({
naddr, naddr,
ua: userAgent || null, ua: userAgent || null,
isCrawlerRequest, isCrawlerRequest,
@@ -257,7 +256,6 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
res.setHeader('Content-Type', 'text/html; charset=utf-8') res.setHeader('Content-Type', 'text/html; charset=utf-8')
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate') res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
if (debugEnabled) { if (debugEnabled) {
console.log('[article-og] response', JSON.stringify({ mode: 'browser', naddr }))
} }
return res.status(200).send(html) return res.status(200).send(html)
} }
@@ -268,7 +266,6 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
if (cached && cached.expires > now) { if (cached && cached.expires > now) {
setCacheHeaders(res) setCacheHeaders(res)
if (debugEnabled) { if (debugEnabled) {
console.log('[article-og] response', JSON.stringify({ mode: 'bot', naddr, cache: true }))
} }
return res.status(200).send(cached.html) return res.status(200).send(cached.html)
} }
@@ -286,7 +283,6 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
// Send response // Send response
setCacheHeaders(res) setCacheHeaders(res)
if (debugEnabled) { if (debugEnabled) {
console.log('[article-og] response', JSON.stringify({ mode: 'bot', naddr, cache: false }))
} }
return res.status(200).send(html) return res.status(200).send(html)
} catch (err) { } catch (err) {
@@ -296,7 +292,6 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
const html = generateHtml(naddr, null) const html = generateHtml(naddr, null)
setCacheHeaders(res, 3600) setCacheHeaders(res, 3600)
if (debugEnabled) { if (debugEnabled) {
console.log('[article-og] response', JSON.stringify({ mode: 'bot-fallback', naddr }))
} }
return res.status(200).send(html) return res.status(200).send(html)
} }

View File

@@ -70,18 +70,14 @@ function AppRoutes({
// Subscribe to contacts controller // Subscribe to contacts controller
useEffect(() => { useEffect(() => {
console.log('[contacts] 🎧 Subscribing to contacts controller')
const unsubContacts = contactsController.onContacts((contacts) => { const unsubContacts = contactsController.onContacts((contacts) => {
console.log('[contacts] 📥 Received contacts:', contacts.size)
setContacts(contacts) setContacts(contacts)
}) })
const unsubLoading = contactsController.onLoading((loading) => { const unsubLoading = contactsController.onLoading((loading) => {
console.log('[contacts] 📥 Loading state:', loading)
setContactsLoading(loading) setContactsLoading(loading)
}) })
return () => { return () => {
console.log('[contacts] 🔇 Unsubscribing from contacts controller')
unsubContacts() unsubContacts()
unsubLoading() unsubLoading()
} }
@@ -100,25 +96,21 @@ function AppRoutes({
// Load contacts // Load contacts
if (pubkey && contacts.size === 0 && !contactsLoading) { if (pubkey && contacts.size === 0 && !contactsLoading) {
console.log('[contacts] 🚀 Auto-loading contacts on mount/login')
contactsController.start({ relayPool, pubkey }) contactsController.start({ relayPool, pubkey })
} }
// Load highlights (controller manages its own state) // Load highlights (controller manages its own state)
if (pubkey && eventStore && !highlightsController.isLoadedFor(pubkey)) { if (pubkey && eventStore && !highlightsController.isLoadedFor(pubkey)) {
console.log('[highlights] 🚀 Auto-loading highlights on mount/login')
highlightsController.start({ relayPool, eventStore, pubkey }) highlightsController.start({ relayPool, eventStore, pubkey })
} }
// Load writings (controller manages its own state) // Load writings (controller manages its own state)
if (pubkey && eventStore && !writingsController.isLoadedFor(pubkey)) { if (pubkey && eventStore && !writingsController.isLoadedFor(pubkey)) {
console.log('[writings] 🚀 Auto-loading writings on mount/login')
writingsController.start({ relayPool, eventStore, pubkey }) writingsController.start({ relayPool, eventStore, pubkey })
} }
// Load reading progress (controller manages its own state) // Load reading progress (controller manages its own state)
if (pubkey && eventStore && !readingProgressController.isLoadedFor(pubkey)) { if (pubkey && eventStore && !readingProgressController.isLoadedFor(pubkey)) {
console.log('[progress] 🚀 Auto-loading reading progress on mount/login')
readingProgressController.start({ relayPool, eventStore, pubkey }) readingProgressController.start({ relayPool, eventStore, pubkey })
} }
@@ -386,40 +378,30 @@ function App() {
// Return an already-resolved promise so upstream await finishes immediately // Return an already-resolved promise so upstream await finishes immediately
return Promise.resolve() return Promise.resolve()
} }
console.log('[bunker] ✅ Wired NostrConnectSigner to RelayPool publish/subscription (before account load)')
// Create a relay group for better event deduplication and management // Create a relay group for better event deduplication and management
pool.group(RELAYS) pool.group(RELAYS)
console.log('[bunker] Created relay group with', RELAYS.length, 'relays (including local)')
// Load persisted accounts from localStorage // Load persisted accounts from localStorage
try { try {
const accountsJson = localStorage.getItem('accounts') const accountsJson = localStorage.getItem('accounts')
console.log('[bunker] Raw accounts from localStorage:', accountsJson)
const json = JSON.parse(accountsJson || '[]') const json = JSON.parse(accountsJson || '[]')
console.log('[bunker] Parsed accounts:', json.length, 'accounts')
await accounts.fromJSON(json) await accounts.fromJSON(json)
console.log('[bunker] Loaded', accounts.accounts.length, 'accounts from storage')
console.log('[bunker] Account types:', accounts.accounts.map(a => ({ id: a.id, type: a.type })))
// Load active account from storage // Load active account from storage
const activeId = localStorage.getItem('active') const activeId = localStorage.getItem('active')
console.log('[bunker] Active ID from localStorage:', activeId)
if (activeId) { if (activeId) {
const account = accounts.getAccount(activeId) const account = accounts.getAccount(activeId)
console.log('[bunker] Found account for ID?', !!account, account?.type)
if (account) { if (account) {
accounts.setActive(activeId) accounts.setActive(activeId)
console.log('[bunker] ✅ Restored active account:', activeId, 'type:', account.type)
} else { } else {
console.warn('[bunker] ⚠️ Active ID found but account not in list') console.warn('[bunker] ⚠️ Active ID found but account not in list')
} }
} else { } else {
console.log('[bunker] No active account ID in localStorage')
} }
} catch (err) { } catch (err) {
console.error('[bunker] ❌ Failed to load accounts from storage:', err) console.error('[bunker] ❌ Failed to load accounts from storage:', err)
@@ -444,11 +426,6 @@ function App() {
const reconnectedAccounts = new Set<string>() const reconnectedAccounts = new Set<string>()
const bunkerReconnectSub = accounts.active$.subscribe(async (account) => { const bunkerReconnectSub = accounts.active$.subscribe(async (account) => {
console.log('[bunker] Active account changed:', {
hasAccount: !!account,
type: account?.type,
id: account?.id
})
if (account && account.type === 'nostr-connect') { if (account && account.type === 'nostr-connect') {
const nostrConnectAccount = account as Accounts.NostrConnectAccount<unknown> const nostrConnectAccount = account as Accounts.NostrConnectAccount<unknown>
@@ -456,23 +433,15 @@ function App() {
try { try {
if (!(nostrConnectAccount as unknown as { disableQueue?: boolean }).disableQueue) { if (!(nostrConnectAccount as unknown as { disableQueue?: boolean }).disableQueue) {
(nostrConnectAccount as unknown as { disableQueue?: boolean }).disableQueue = true (nostrConnectAccount as unknown as { disableQueue?: boolean }).disableQueue = true
console.log('[bunker] ⚙️ Disabled account request queueing for nostr-connect')
} }
} catch (err) { console.warn('[bunker] failed to disable queue', err) } } catch (err) { console.warn('[bunker] failed to disable queue', err) }
// Note: for Amber bunker, the remote signer pubkey is the user's pubkey. This is expected. // Note: for Amber bunker, the remote signer pubkey is the user's pubkey. This is expected.
// Skip if we've already reconnected this account // Skip if we've already reconnected this account
if (reconnectedAccounts.has(account.id)) { if (reconnectedAccounts.has(account.id)) {
console.log('[bunker] ⏭️ Already reconnected this account, skipping')
return return
} }
console.log('[bunker] Account detected. Status:', {
listening: nostrConnectAccount.signer.listening,
isConnected: nostrConnectAccount.signer.isConnected,
hasRemote: !!nostrConnectAccount.signer.remote,
bunkerRelays: nostrConnectAccount.signer.relays
})
try { try {
// For restored signers, ensure they have the pool's subscription methods // For restored signers, ensure they have the pool's subscription methods
@@ -486,10 +455,8 @@ function App() {
const newBunkerRelays = bunkerRelays.filter(url => !existingRelayUrls.has(url)) const newBunkerRelays = bunkerRelays.filter(url => !existingRelayUrls.has(url))
if (newBunkerRelays.length > 0) { if (newBunkerRelays.length > 0) {
console.log('[bunker] Adding bunker relays to pool BEFORE signer recreation:', newBunkerRelays)
pool.group(newBunkerRelays) pool.group(newBunkerRelays)
} else { } else {
console.log('[bunker] Bunker relays already in pool')
} }
const recreatedSigner = new NostrConnectSigner({ const recreatedSigner = new NostrConnectSigner({
@@ -503,13 +470,11 @@ function App() {
try { try {
const mergedRelays = Array.from(new Set([...(signerData.relays || []), ...RELAYS])) const mergedRelays = Array.from(new Set([...(signerData.relays || []), ...RELAYS]))
recreatedSigner.relays = mergedRelays recreatedSigner.relays = mergedRelays
console.log('[bunker] 🔗 Signer relays merged with app RELAYS:', mergedRelays)
} catch (err) { console.warn('[bunker] failed to merge signer relays', err) } } catch (err) { console.warn('[bunker] failed to merge signer relays', err) }
// Replace the signer on the account // Replace the signer on the account
nostrConnectAccount.signer = recreatedSigner nostrConnectAccount.signer = recreatedSigner
console.log('[bunker] ✅ Signer recreated with pool context')
// Debug: log publish/subscription calls made by signer (decrypt/sign requests) // Debug: log publish/subscription calls made by signer (decrypt/sign requests)
// IMPORTANT: bind originals to preserve `this` context used internally by the signer // IMPORTANT: bind originals to preserve `this` context used internally by the signer
const originalPublish = (recreatedSigner as unknown as { publishMethod: (relays: string[], event: unknown) => unknown }).publishMethod.bind(recreatedSigner) const originalPublish = (recreatedSigner as unknown as { publishMethod: (relays: string[], event: unknown) => unknown }).publishMethod.bind(recreatedSigner)
@@ -531,7 +496,6 @@ function App() {
tags: (event as { tags?: unknown })?.tags, tags: (event as { tags?: unknown })?.tags,
contentLength: typeof content === 'string' ? content.length : undefined contentLength: typeof content === 'string' ? content.length : undefined
} }
console.log('[bunker] publish via signer:', summary)
try { DebugBus.info('bunker', 'publish', summary) } catch (err) { console.warn('[bunker] failed to log to DebugBus', err) } try { DebugBus.info('bunker', 'publish', summary) } catch (err) { console.warn('[bunker] failed to log to DebugBus', err) }
} catch (err) { console.warn('[bunker] failed to log publish summary', err) } } catch (err) { console.warn('[bunker] failed to log publish summary', err) }
// Fire-and-forget publish: trigger the publish but do not return the // Fire-and-forget publish: trigger the publish but do not return the
@@ -549,7 +513,6 @@ function App() {
const originalSubscribe = (recreatedSigner as unknown as { subscriptionMethod: (relays: string[], filters: unknown[]) => unknown }).subscriptionMethod.bind(recreatedSigner) const originalSubscribe = (recreatedSigner as unknown as { subscriptionMethod: (relays: string[], filters: unknown[]) => unknown }).subscriptionMethod.bind(recreatedSigner)
;(recreatedSigner as unknown as { subscriptionMethod: (relays: string[], filters: unknown[]) => unknown }).subscriptionMethod = (relays: string[], filters: unknown[]) => { ;(recreatedSigner as unknown as { subscriptionMethod: (relays: string[], filters: unknown[]) => unknown }).subscriptionMethod = (relays: string[], filters: unknown[]) => {
try { try {
console.log('[bunker] subscribe via signer:', { relays, filters })
try { DebugBus.info('bunker', 'subscribe', { relays, filters }) } catch (err) { console.warn('[bunker] failed to log subscribe to DebugBus', err) } try { DebugBus.info('bunker', 'subscribe', { relays, filters }) } catch (err) { console.warn('[bunker] failed to log subscribe to DebugBus', err) }
} catch (err) { console.warn('[bunker] failed to log subscribe summary', err) } } catch (err) { console.warn('[bunker] failed to log subscribe summary', err) }
return originalSubscribe(relays, filters) return originalSubscribe(relays, filters)
@@ -559,20 +522,15 @@ function App() {
// Just ensure the signer is listening for responses - don't call connect() again // Just ensure the signer is listening for responses - don't call connect() again
// The fromBunkerURI already connected with permissions during login // The fromBunkerURI already connected with permissions during login
if (!nostrConnectAccount.signer.listening) { if (!nostrConnectAccount.signer.listening) {
console.log('[bunker] Opening signer subscription...')
await nostrConnectAccount.signer.open() await nostrConnectAccount.signer.open()
console.log('[bunker] ✅ Signer subscription opened')
} else { } else {
console.log('[bunker] ✅ Signer already listening')
} }
// Attempt a guarded reconnect to ensure Amber authorizes decrypt operations // Attempt a guarded reconnect to ensure Amber authorizes decrypt operations
try { try {
if (nostrConnectAccount.signer.remote && !reconnectedAccounts.has(account.id)) { if (nostrConnectAccount.signer.remote && !reconnectedAccounts.has(account.id)) {
const permissions = getDefaultBunkerPermissions() const permissions = getDefaultBunkerPermissions()
console.log('[bunker] Attempting guarded connect() with permissions to ensure decrypt perms', { count: permissions.length })
await nostrConnectAccount.signer.connect(undefined, permissions) await nostrConnectAccount.signer.connect(undefined, permissions)
console.log('[bunker] ✅ Guarded connect() succeeded with permissions')
} }
} catch (e) { } catch (e) {
console.warn('[bunker] ⚠️ Guarded connect() failed:', e) console.warn('[bunker] ⚠️ Guarded connect() failed:', e)
@@ -581,7 +539,6 @@ function App() {
// Give the subscription a moment to fully establish before allowing decrypt operations // Give the subscription a moment to fully establish before allowing decrypt operations
// This ensures the signer is ready to handle and receive responses // This ensures the signer is ready to handle and receive responses
await new Promise(resolve => setTimeout(resolve, 100)) await new Promise(resolve => setTimeout(resolve, 100))
console.log("[bunker] Subscription ready after startup delay")
// Fire-and-forget: probe decrypt path to verify Amber responds to NIP-46 decrypt // Fire-and-forget: probe decrypt path to verify Amber responds to NIP-46 decrypt
try { try {
const withTimeout = async <T,>(p: Promise<T>, ms = 10000): Promise<T> => { const withTimeout = async <T,>(p: Promise<T>, ms = 10000): Promise<T> => {
@@ -594,38 +551,24 @@ function App() {
const self = nostrConnectAccount.pubkey const self = nostrConnectAccount.pubkey
// Try a roundtrip so the bunker can respond successfully // Try a roundtrip so the bunker can respond successfully
try { try {
console.log('[bunker] 🔎 Probe nip44 roundtrip (encrypt→decrypt)…')
const cipher44 = await withTimeout(nostrConnectAccount.signer.nip44!.encrypt(self, 'probe-nip44')) const cipher44 = await withTimeout(nostrConnectAccount.signer.nip44!.encrypt(self, 'probe-nip44'))
const plain44 = await withTimeout(nostrConnectAccount.signer.nip44!.decrypt(self, cipher44)) const plain44 = await withTimeout(nostrConnectAccount.signer.nip44!.decrypt(self, cipher44))
console.log('[bunker] 🔎 Probe nip44 responded:', typeof plain44 === 'string' ? plain44 : typeof plain44)
} catch (err) { } catch (err) {
console.log('[bunker] 🔎 Probe nip44 result:', err instanceof Error ? err.message : err)
} }
try { try {
console.log('[bunker] 🔎 Probe nip04 roundtrip (encrypt→decrypt)…')
const cipher04 = await withTimeout(nostrConnectAccount.signer.nip04!.encrypt(self, 'probe-nip04')) const cipher04 = await withTimeout(nostrConnectAccount.signer.nip04!.encrypt(self, 'probe-nip04'))
const plain04 = await withTimeout(nostrConnectAccount.signer.nip04!.decrypt(self, cipher04)) const plain04 = await withTimeout(nostrConnectAccount.signer.nip04!.decrypt(self, cipher04))
console.log('[bunker] 🔎 Probe nip04 responded:', typeof plain04 === 'string' ? plain04 : typeof plain04)
} catch (err) { } catch (err) {
console.log('[bunker] 🔎 Probe nip04 result:', err instanceof Error ? err.message : err)
} }
}, 0) }, 0)
} catch (err) { } catch (err) {
console.log('[bunker] 🔎 Probe setup failed:', err)
} }
// The bunker remembers the permissions from the initial connection // The bunker remembers the permissions from the initial connection
nostrConnectAccount.signer.isConnected = true nostrConnectAccount.signer.isConnected = true
console.log('[bunker] Final signer status:', {
listening: nostrConnectAccount.signer.listening,
isConnected: nostrConnectAccount.signer.isConnected,
remote: nostrConnectAccount.signer.remote,
relays: nostrConnectAccount.signer.relays
})
// Mark this account as reconnected // Mark this account as reconnected
reconnectedAccounts.add(account.id) reconnectedAccounts.add(account.id)
console.log('[bunker] 🎉 Signer ready for signing')
} catch (error) { } catch (error) {
console.error('[bunker] ❌ Failed to open signer:', error) console.error('[bunker] ❌ Failed to open signer:', error)
} }
@@ -639,7 +582,6 @@ function App() {
next: () => {}, // No-op, we don't care about events next: () => {}, // No-op, we don't care about events
error: (err) => console.warn('Keep-alive subscription error:', err) error: (err) => console.warn('Keep-alive subscription error:', err)
}) })
console.log('🔗 Created keep-alive subscription for', RELAYS.length, 'relay(s)')
// Store subscription for cleanup // Store subscription for cleanup
;(pool as unknown as { _keepAliveSubscription: typeof keepAliveSub })._keepAliveSubscription = keepAliveSub ;(pool as unknown as { _keepAliveSubscription: typeof keepAliveSub })._keepAliveSubscription = keepAliveSub

View File

@@ -36,7 +36,6 @@ const BlogPostCard: React.FC<BlogPostCardProps> = ({ post, href, level, readingP
// Debug log // Debug log
if (readingProgress !== undefined) { if (readingProgress !== undefined) {
console.log('[progress] 🎴 Card render:', post.title.slice(0, 30), '=> progress:', progressPercent + '%', 'color:', progressColor)
} }
return ( return (

View File

@@ -151,33 +151,18 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
// Callback to save reading position // Callback to save reading position
const handleSavePosition = useCallback(async (position: number) => { const handleSavePosition = useCallback(async (position: number) => {
if (!activeAccount || !relayPool || !eventStore || !articleIdentifier) { if (!activeAccount || !relayPool || !eventStore || !articleIdentifier) {
console.log('[progress] ⏭️ ContentPanel: Skipping save - missing requirements:', {
hasAccount: !!activeAccount,
hasRelayPool: !!relayPool,
hasEventStore: !!eventStore,
hasIdentifier: !!articleIdentifier
})
return return
} }
if (!settings?.syncReadingPosition) { if (!settings?.syncReadingPosition) {
console.log('[progress] ⏭️ ContentPanel: Sync disabled in settings')
return return
} }
// Check if content is long enough to track reading progress // Check if content is long enough to track reading progress
if (!shouldTrackReadingProgress(html, markdown)) { if (!shouldTrackReadingProgress(html, markdown)) {
console.log('[progress] ⏭️ ContentPanel: Content too short to track reading progress')
return return
} }
const scrollTop = window.pageYOffset || document.documentElement.scrollTop const scrollTop = window.pageYOffset || document.documentElement.scrollTop
console.log('[progress] 💾 ContentPanel: Saving position:', {
position,
percentage: Math.round(position * 100) + '%',
scrollTop,
articleIdentifier: articleIdentifier.slice(0, 50) + '...',
url: selectedUrl?.slice(0, 50)
})
try { try {
const factory = new EventFactory({ signer: activeAccount }) const factory = new EventFactory({ signer: activeAccount })
@@ -192,7 +177,6 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
scrollTop scrollTop
} }
) )
console.log('[progress] ✅ ContentPanel: Save completed successfully')
} catch (error) { } catch (error) {
console.error('[progress] ❌ ContentPanel: Failed to save reading position:', error) console.error('[progress] ❌ ContentPanel: Failed to save reading position:', error)
} }
@@ -205,7 +189,6 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
onReadingComplete: () => { onReadingComplete: () => {
// Auto-mark as read when reading is complete (if enabled in settings) // Auto-mark as read when reading is complete (if enabled in settings)
if (activeAccount && !isMarkedAsRead && settings?.autoMarkAsReadOnCompletion) { if (activeAccount && !isMarkedAsRead && settings?.autoMarkAsReadOnCompletion) {
console.log('[progress] 📖 Auto-marking as read on completion')
handleMarkAsRead() handleMarkAsRead()
} }
} }
@@ -213,36 +196,17 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
// Log sync status when it changes // Log sync status when it changes
useEffect(() => { useEffect(() => {
console.log('[progress] 📊 ContentPanel reading position sync status:', {
enabled: isTextContent,
syncEnabled: settings?.syncReadingPosition !== false,
hasAccount: !!activeAccount,
hasRelayPool: !!relayPool,
hasEventStore: !!eventStore,
hasArticleIdentifier: !!articleIdentifier,
currentProgress: progressPercentage + '%'
})
}, [isTextContent, settings?.syncReadingPosition, activeAccount, relayPool, eventStore, articleIdentifier, progressPercentage]) }, [isTextContent, settings?.syncReadingPosition, activeAccount, relayPool, eventStore, articleIdentifier, progressPercentage])
// Load saved reading position when article loads // Load saved reading position when article loads
useEffect(() => { useEffect(() => {
if (!isTextContent || !activeAccount || !relayPool || !eventStore || !articleIdentifier) { if (!isTextContent || !activeAccount || !relayPool || !eventStore || !articleIdentifier) {
console.log('⏭️ [ContentPanel] Skipping position restore - missing requirements:', {
isTextContent,
hasAccount: !!activeAccount,
hasRelayPool: !!relayPool,
hasEventStore: !!eventStore,
hasIdentifier: !!articleIdentifier
})
return return
} }
if (settings?.syncReadingPosition === false) { if (settings?.syncReadingPosition === false) {
console.log('⏭️ [ContentPanel] Sync disabled in settings - not restoring position')
return return
} }
console.log('📖 [ContentPanel] Loading position for article:', selectedUrl?.slice(0, 50))
const loadPosition = async () => { const loadPosition = async () => {
try { try {
const savedPosition = await loadReadingPosition( const savedPosition = await loadReadingPosition(
@@ -253,7 +217,6 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
) )
if (savedPosition && savedPosition.position > 0.05 && savedPosition.position < 1) { if (savedPosition && savedPosition.position > 0.05 && savedPosition.position < 1) {
console.log('🎯 [ContentPanel] Restoring position:', Math.round(savedPosition.position * 100) + '%')
// Wait for content to be fully rendered before scrolling // Wait for content to be fully rendered before scrolling
setTimeout(() => { setTimeout(() => {
const documentHeight = document.documentElement.scrollHeight const documentHeight = document.documentElement.scrollHeight
@@ -264,14 +227,10 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
top: scrollTop, top: scrollTop,
behavior: 'smooth' behavior: 'smooth'
}) })
console.log('✅ [ContentPanel] Restored to position:', Math.round(savedPosition.position * 100) + '%', 'scrollTop:', scrollTop)
}, 500) // Give content time to render }, 500) // Give content time to render
} else if (savedPosition) { } else if (savedPosition) {
if (savedPosition.position === 1) { if (savedPosition.position === 1) {
console.log('✅ [ContentPanel] Article completed (100%), starting from top')
} else { } else {
console.log('⏭️ [ContentPanel] Position too early (<5%):', Math.round(savedPosition.position * 100) + '%')
} }
} }
} catch (error) { } catch (error) {
@@ -648,14 +607,12 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
activeAccount, activeAccount,
relayPool relayPool
) )
console.log('✅ Marked nostr article as read')
} else if (selectedUrl) { } else if (selectedUrl) {
await createWebsiteReaction( await createWebsiteReaction(
selectedUrl, selectedUrl,
activeAccount, activeAccount,
relayPool relayPool
) )
console.log('✅ Marked website as read')
} }
} catch (error) { } catch (error) {
console.error('Failed to mark as read:', error) console.error('Failed to mark as read:', error)

View File

@@ -310,7 +310,6 @@ const Debug: React.FC<DebugProps> = ({
// Subscribe to decrypt complete events for Debug UI display // Subscribe to decrypt complete events for Debug UI display
const unsubscribeDecrypt = bookmarkController.onDecryptComplete((eventId, publicCount, privateCount) => { const unsubscribeDecrypt = bookmarkController.onDecryptComplete((eventId, publicCount, privateCount) => {
console.log('[bunker] ✅ Auto-decrypted:', eventId.slice(0, 8), {
public: publicCount, public: publicCount,
private: privateCount private: privateCount
}) })
@@ -742,7 +741,6 @@ const Debug: React.FC<DebugProps> = ({
// Subscribe to controller updates to see streaming // Subscribe to controller updates to see streaming
const unsubscribe = contactsController.onContacts((contacts) => { const unsubscribe = contactsController.onContacts((contacts) => {
console.log('[debug] Received contacts update:', contacts.size)
setFriendsPubkeys(new Set(contacts)) setFriendsPubkeys(new Set(contacts))
}) })

View File

@@ -178,12 +178,10 @@ const Explore: React.FC<ExploreProps> = ({ relayPool, eventStore, settings, acti
useEffect(() => { useEffect(() => {
// Get initial state immediately // Get initial state immediately
const initialMap = readingProgressController.getProgressMap() const initialMap = readingProgressController.getProgressMap()
console.log('[progress] 🎯 Explore: Initial progress map size:', initialMap.size)
setReadingProgressMap(initialMap) setReadingProgressMap(initialMap)
// Subscribe to updates // Subscribe to updates
const unsubProgress = readingProgressController.onProgress((newMap) => { const unsubProgress = readingProgressController.onProgress((newMap) => {
console.log('[progress] 🎯 Explore: Received progress update, size:', newMap.size)
setReadingProgressMap(newMap) setReadingProgressMap(newMap)
}) })
@@ -612,7 +610,6 @@ const Explore: React.FC<ExploreProps> = ({ relayPool, eventStore, settings, acti
const getReadingProgress = useCallback((post: BlogPostPreview): number | undefined => { const getReadingProgress = useCallback((post: BlogPostPreview): number | undefined => {
const dTag = post.event.tags.find(t => t[0] === 'd')?.[1] const dTag = post.event.tags.find(t => t[0] === 'd')?.[1]
if (!dTag) { if (!dTag) {
console.log('[progress] ⚠️ No d-tag for post:', post.title)
return undefined return undefined
} }
@@ -624,16 +621,6 @@ const Explore: React.FC<ExploreProps> = ({ relayPool, eventStore, settings, acti
}) })
const progress = readingProgressMap.get(naddr) const progress = readingProgressMap.get(naddr)
// Only log first lookup to avoid spam, or when found
if (progress || readingProgressMap.size === 0) {
console.log('[progress] 🔍 Looking up:', {
title: post.title.slice(0, 30),
naddr: naddr.slice(0, 80),
mapSize: readingProgressMap.size,
mapKeys: readingProgressMap.size > 0 ? Array.from(readingProgressMap.keys()).slice(0, 3).map(k => k.slice(0, 80)) : [],
progress: progress ? Math.round(progress * 100) + '%' : 'not found'
})
}
return progress return progress
} catch (err) { } catch (err) {
console.error('[progress] ❌ Error encoding naddr:', err) console.error('[progress] ❌ Error encoding naddr:', err)

View File

@@ -27,7 +27,6 @@ export const HighlightCitation: React.FC<HighlightCitationProps> = ({
// Fallback: extract directly from p tag // Fallback: extract directly from p tag
const pTag = highlight.tags.find(t => t[0] === 'p') const pTag = highlight.tags.find(t => t[0] === 'p')
if (pTag && pTag[1]) { if (pTag && pTag[1]) {
console.log('📝 Found author from p tag:', pTag[1])
return pTag[1] return pTag[1]
} }

View File

@@ -348,11 +348,9 @@ export const HighlightItem: React.FC<HighlightItemProps> = ({
// Publish to all configured relays - let the relay pool handle connection state // Publish to all configured relays - let the relay pool handle connection state
const targetRelays = RELAYS const targetRelays = RELAYS
console.log('📡 Rebroadcasting highlight to', targetRelays.length, 'relay(s):', targetRelays)
await relayPool.publish(targetRelays, event) await relayPool.publish(targetRelays, event)
console.log('✅ Rebroadcast successful!')
// Update the highlight with new relay info // Update the highlight with new relay info
const isLocalOnly = areAllRelaysLocal(targetRelays) const isLocalOnly = areAllRelaysLocal(targetRelays)
@@ -449,7 +447,6 @@ export const HighlightItem: React.FC<HighlightItemProps> = ({
relayPool relayPool
) )
console.log('✅ Highlight deletion request published')
// Notify parent to remove this highlight from the list // Notify parent to remove this highlight from the list
if (onHighlightDelete) { if (onHighlightDelete) {

View File

@@ -243,23 +243,15 @@ const Me: React.FC<MeProps> = ({
// Background enrichment: merge reading progress and mark-as-read // Background enrichment: merge reading progress and mark-as-read
// Only update items that are already in our map // Only update items that are already in our map
fetchAllReads(relayPool, viewingPubkey, bookmarks, (item) => { fetchAllReads(relayPool, viewingPubkey, bookmarks, (item) => {
console.log('📈 [Reads] Enrichment item received:', {
id: item.id.slice(0, 20) + '...',
progress: item.readingProgress,
hasProgress: item.readingProgress !== undefined && item.readingProgress > 0
})
setReadsMap(prevMap => { setReadsMap(prevMap => {
// Only update if item exists in our current map // Only update if item exists in our current map
if (!prevMap.has(item.id)) { if (!prevMap.has(item.id)) {
console.log('⚠️ [Reads] Item not in map, skipping:', item.id.slice(0, 20) + '...')
return prevMap return prevMap
} }
const newMap = new Map(prevMap) const newMap = new Map(prevMap)
const merged = mergeReadItem(newMap, item) const merged = mergeReadItem(newMap, item)
if (merged) { if (merged) {
console.log('✅ [Reads] Merged progress:', item.id.slice(0, 20) + '...', item.readingProgress)
// Update reads array after map is updated // Update reads array after map is updated
setReads(Array.from(newMap.values())) setReads(Array.from(newMap.values()))
return newMap return newMap

View File

@@ -68,12 +68,10 @@ const Profile: React.FC<ProfileProps> = ({
useEffect(() => { useEffect(() => {
// Get initial state immediately // Get initial state immediately
const initialMap = readingProgressController.getProgressMap() const initialMap = readingProgressController.getProgressMap()
console.log('[progress] 🎯 Profile: Initial progress map size:', initialMap.size)
setReadingProgressMap(initialMap) setReadingProgressMap(initialMap)
// Subscribe to updates // Subscribe to updates
const unsubProgress = readingProgressController.onProgress((newMap) => { const unsubProgress = readingProgressController.onProgress((newMap) => {
console.log('[progress] 🎯 Profile: Received progress update, size:', newMap.size)
setReadingProgressMap(newMap) setReadingProgressMap(newMap)
}) })
@@ -100,12 +98,10 @@ const Profile: React.FC<ProfileProps> = ({
useEffect(() => { useEffect(() => {
if (!pubkey || !relayPool || !eventStore) return if (!pubkey || !relayPool || !eventStore) return
console.log('🔄 [Profile] Background fetching highlights and writings for', pubkey.slice(0, 8))
// Fetch highlights in background // Fetch highlights in background
fetchHighlights(relayPool, pubkey, undefined, undefined, false, eventStore) fetchHighlights(relayPool, pubkey, undefined, undefined, false, eventStore)
.then(highlights => { .then(highlights => {
console.log('✅ [Profile] Fetched', highlights.length, 'highlights')
}) })
.catch(err => { .catch(err => {
console.warn('⚠️ [Profile] Failed to fetch highlights:', err) console.warn('⚠️ [Profile] Failed to fetch highlights:', err)
@@ -115,7 +111,6 @@ const Profile: React.FC<ProfileProps> = ({
fetchBlogPostsFromAuthors(relayPool, [pubkey], RELAYS, undefined, null) fetchBlogPostsFromAuthors(relayPool, [pubkey], RELAYS, undefined, null)
.then(writings => { .then(writings => {
writings.forEach(w => eventStore.add(w.event)) writings.forEach(w => eventStore.add(w.event))
console.log('✅ [Profile] Fetched', writings.length, 'writings')
}) })
.catch(err => { .catch(err => {
console.warn('⚠️ [Profile] Failed to fetch writings:', err) console.warn('⚠️ [Profile] Failed to fetch writings:', err)
@@ -157,7 +152,6 @@ const Profile: React.FC<ProfileProps> = ({
// Only log when found or map is empty // Only log when found or map is empty
if (progress || readingProgressMap.size === 0) { if (progress || readingProgressMap.size === 0) {
console.log('[progress] 🔍 Profile lookup:', {
title: post.title?.slice(0, 30), title: post.title?.slice(0, 30),
naddr: naddr.slice(0, 80), naddr: naddr.slice(0, 80),
mapSize: readingProgressMap.size, mapSize: readingProgressMap.size,

View File

@@ -50,7 +50,6 @@ export const RelayStatusIndicator: React.FC<RelayStatusIndicatorProps> = ({
// Debug logging // Debug logging
useEffect(() => { useEffect(() => {
console.log('🔌 Relay Status Indicator:', {
mode: isConnecting ? 'CONNECTING' : offlineMode ? 'OFFLINE' : localOnlyMode ? 'LOCAL_ONLY' : 'ONLINE', mode: isConnecting ? 'CONNECTING' : offlineMode ? 'OFFLINE' : localOnlyMode ? 'LOCAL_ONLY' : 'ONLINE',
totalStatuses: relayStatuses.length, totalStatuses: relayStatuses.length,
connectedCount: connectedUrls.length, connectedCount: connectedUrls.length,

View File

@@ -27,7 +27,6 @@ const PWASettings: React.FC<PWASettingsProps> = ({ settings, onUpdate, onClose }
if (isInstalled) return if (isInstalled) return
const success = await installApp() const success = await installApp()
if (success) { if (success) {
console.log('App installed successfully')
} }
} }

View File

@@ -43,7 +43,6 @@ export function useAdaptiveTextColor(imageUrl: string | undefined): AdaptiveText
height: Math.floor(height * 0.25) height: Math.floor(height * 0.25)
}) })
console.log('Adaptive color detected:', {
hex: color.hex, hex: color.hex,
rgb: color.rgb, rgb: color.rgb,
isLight: color.isLight, isLight: color.isLight,
@@ -52,12 +51,10 @@ export function useAdaptiveTextColor(imageUrl: string | undefined): AdaptiveText
// Use library's built-in isLight check for optimal contrast // Use library's built-in isLight check for optimal contrast
if (color.isLight) { if (color.isLight) {
console.log('Light background detected, using black text')
setColors({ setColors({
textColor: '#000000' textColor: '#000000'
}) })
} else { } else {
console.log('Dark background detected, using white text')
setColors({ setColors({
textColor: '#ffffff' textColor: '#ffffff'
}) })

View File

@@ -64,8 +64,6 @@ export function useArticleLoader({
setCurrentArticleEventId(article.event.id) setCurrentArticleEventId(article.event.id)
setCurrentArticle?.(article.event) setCurrentArticle?.(article.event)
console.log('📰 Article loaded:', article.title)
console.log('📍 Coordinate:', articleCoordinate)
// Set reader loading to false immediately after article content is ready // Set reader loading to false immediately after article content is ready
// Don't wait for highlights to finish loading // Don't wait for highlights to finish loading
@@ -92,7 +90,6 @@ export function useArticleLoader({
}, },
settings settings
) )
console.log(`📌 Found ${highlightsMap.size} highlights`)
} catch (err) { } catch (err) {
console.error('Failed to fetch highlights:', err) console.error('Failed to fetch highlights:', err)
} finally { } finally {

View File

@@ -77,7 +77,6 @@ export function useExternalUrlLoader({
const content = await fetchReadableContent(url) const content = await fetchReadableContent(url)
setReaderContent(content) setReaderContent(content)
console.log('🌐 External URL loaded:', content.title)
// Set reader loading to false immediately after content is ready // Set reader loading to false immediately after content is ready
setReaderLoading(false) setReaderLoading(false)

View File

@@ -60,7 +60,6 @@ export const useHighlightCreation = ({
? currentArticle.content ? currentArticle.content
: readerContent?.markdown || readerContent?.html : readerContent?.markdown || readerContent?.html
console.log('🎯 Creating highlight...', { text: text.substring(0, 50) + '...' })
const newHighlight = await createHighlight( const newHighlight = await createHighlight(
text, text,
@@ -73,7 +72,6 @@ export const useHighlightCreation = ({
settings settings
) )
console.log('✅ Highlight created successfully!', {
id: newHighlight.id, id: newHighlight.id,
isLocalOnly: newHighlight.isLocalOnly, isLocalOnly: newHighlight.isLocalOnly,
isOfflineCreated: newHighlight.isOfflineCreated, isOfflineCreated: newHighlight.isOfflineCreated,

View File

@@ -32,14 +32,12 @@ export const useHighlightedContent = ({
}: UseHighlightedContentParams) => { }: UseHighlightedContentParams) => {
// Filter highlights by URL and visibility settings // Filter highlights by URL and visibility settings
const relevantHighlights = useMemo(() => { const relevantHighlights = useMemo(() => {
console.log('🔍 ContentPanel: Processing highlights', {
totalHighlights: highlights.length, totalHighlights: highlights.length,
selectedUrl, selectedUrl,
showHighlights showHighlights
}) })
const urlFiltered = filterHighlightsByUrl(highlights, selectedUrl) const urlFiltered = filterHighlightsByUrl(highlights, selectedUrl)
console.log('📌 URL filtered highlights:', urlFiltered.length)
// Apply visibility filtering // Apply visibility filtering
const classified = classifyHighlights(urlFiltered, currentUserPubkey, followedPubkeys) const classified = classifyHighlights(urlFiltered, currentUserPubkey, followedPubkeys)
@@ -49,7 +47,6 @@ export const useHighlightedContent = ({
return highlightVisibility.nostrverse return highlightVisibility.nostrverse
}) })
console.log('✅ Relevant highlights after filtering:', filtered.length, filtered.map(h => h.content.substring(0, 30)))
return filtered return filtered
}, [selectedUrl, highlights, highlightVisibility, currentUserPubkey, followedPubkeys, showHighlights]) }, [selectedUrl, highlights, highlightVisibility, currentUserPubkey, followedPubkeys, showHighlights])
@@ -57,7 +54,6 @@ export const useHighlightedContent = ({
const finalHtml = useMemo(() => { const finalHtml = useMemo(() => {
const sourceHtml = markdown ? renderedMarkdownHtml : html const sourceHtml = markdown ? renderedMarkdownHtml : html
console.log('🎨 Preparing final HTML:', {
hasMarkdown: !!markdown, hasMarkdown: !!markdown,
hasHtml: !!html, hasHtml: !!html,
renderedHtmlLength: renderedMarkdownHtml.length, renderedHtmlLength: renderedMarkdownHtml.length,
@@ -72,13 +68,10 @@ export const useHighlightedContent = ({
} }
if (showHighlights && relevantHighlights.length > 0) { if (showHighlights && relevantHighlights.length > 0) {
console.log('✨ Applying', relevantHighlights.length, 'highlights to HTML')
const highlightedHtml = applyHighlightsToHTML(sourceHtml, relevantHighlights, highlightStyle) const highlightedHtml = applyHighlightsToHTML(sourceHtml, relevantHighlights, highlightStyle)
console.log('✅ Highlights applied, result length:', highlightedHtml.length)
return highlightedHtml return highlightedHtml
} }
console.log('📄 Returning source HTML without highlights')
return sourceHtml return sourceHtml
}, [html, renderedMarkdownHtml, markdown, relevantHighlights, showHighlights, highlightStyle]) }, [html, renderedMarkdownHtml, markdown, relevantHighlights, showHighlights, highlightStyle])

View File

@@ -43,7 +43,6 @@ export const useMarkdownToHTML = (
// Replace nostr URIs with resolved titles // Replace nostr URIs with resolved titles
processed = replaceNostrUrisInMarkdownWithTitles(markdown, articleTitles) processed = replaceNostrUrisInMarkdownWithTitles(markdown, articleTitles)
console.log(`📚 Resolved ${articleTitles.size} article titles`)
} catch (error) { } catch (error) {
console.warn('Failed to fetch article titles:', error) console.warn('Failed to fetch article titles:', error)
// Fall back to basic replacement // Fall back to basic replacement
@@ -58,12 +57,10 @@ export const useMarkdownToHTML = (
setProcessedMarkdown(processed) setProcessedMarkdown(processed)
console.log('📝 Converting markdown to HTML...')
const rafId = requestAnimationFrame(() => { const rafId = requestAnimationFrame(() => {
if (previewRef.current && !isCancelled) { if (previewRef.current && !isCancelled) {
const html = previewRef.current.innerHTML const html = previewRef.current.innerHTML
console.log('✅ Markdown converted to HTML:', html.length, 'chars')
setRenderedHtml(html) setRenderedHtml(html)
} else if (!isCancelled) { } else if (!isCancelled) {
console.warn('⚠️ markdownPreviewRef.current is null') console.warn('⚠️ markdownPreviewRef.current is null')

View File

@@ -50,8 +50,6 @@ export function useOfflineSync({
const isNowOnline = hasRemoteRelays const isNowOnline = hasRemoteRelays
if (wasLocalOnly && isNowOnline) { if (wasLocalOnly && isNowOnline) {
console.log('✈️ Detected transition: Flight Mode → Online')
console.log('📊 Relay state:', {
connectedRelays: connectedRelays.length, connectedRelays: connectedRelays.length,
remoteRelays: connectedRelays.filter(r => !isLocalRelay(r.url)).length, remoteRelays: connectedRelays.filter(r => !isLocalRelay(r.url)).length,
localRelays: connectedRelays.filter(r => isLocalRelay(r.url)).length localRelays: connectedRelays.filter(r => isLocalRelay(r.url)).length
@@ -59,7 +57,6 @@ export function useOfflineSync({
// Wait a moment for relays to fully establish connections // Wait a moment for relays to fully establish connections
setTimeout(() => { setTimeout(() => {
console.log('🚀 Starting sync after delay...')
syncLocalEventsToRemote(relayPool, eventStore) syncLocalEventsToRemote(relayPool, eventStore)
}, 2000) }, 2000)
} }

View File

@@ -5,12 +5,10 @@ export function useOnlineStatus() {
useEffect(() => { useEffect(() => {
const handleOnline = () => { const handleOnline = () => {
console.log('🌐 Back online')
setIsOnline(true) setIsOnline(true)
} }
const handleOffline = () => { const handleOffline = () => {
console.log('📴 Gone offline')
setIsOnline(false) setIsOnline(false)
} }

View File

@@ -51,12 +51,10 @@ export function usePWAInstall() {
const choiceResult = await deferredPrompt.userChoice const choiceResult = await deferredPrompt.userChoice
if (choiceResult.outcome === 'accepted') { if (choiceResult.outcome === 'accepted') {
console.log('✅ PWA installed')
setIsInstallable(false) setIsInstallable(false)
setDeferredPrompt(null) setDeferredPrompt(null)
return true return true
} else { } else {
console.log('❌ PWA installation dismissed')
return false return false
} }
} catch (error) { } catch (error) {

View File

@@ -32,7 +32,6 @@ export const useReadingPosition = ({
// Debounced save function // Debounced save function
const scheduleSave = useCallback((currentPosition: number) => { const scheduleSave = useCallback((currentPosition: number) => {
if (!syncEnabled || !onSave) { if (!syncEnabled || !onSave) {
console.log('[progress] ⏭️ scheduleSave skipped:', { syncEnabled, hasOnSave: !!onSave, position: Math.round(currentPosition * 100) + '%' })
return return
} }
@@ -43,7 +42,6 @@ export const useReadingPosition = ({
const isInitialSave = !hasSavedOnce.current const isInitialSave = !hasSavedOnce.current
if (!hasSignificantChange && !hasReachedCompletion && !isInitialSave) { if (!hasSignificantChange && !hasReachedCompletion && !isInitialSave) {
console.log('[progress] ⏭️ No significant change:', {
current: Math.round(currentPosition * 100) + '%', current: Math.round(currentPosition * 100) + '%',
last: Math.round(lastSavedPosition.current * 100) + '%', last: Math.round(lastSavedPosition.current * 100) + '%',
diff: Math.abs(currentPosition - lastSavedPosition.current), diff: Math.abs(currentPosition - lastSavedPosition.current),
@@ -58,9 +56,7 @@ export const useReadingPosition = ({
} }
// Schedule new save // Schedule new save
console.log('[progress] ⏰ Scheduling save in', autoSaveInterval + 'ms for position:', Math.round(currentPosition * 100) + '%')
saveTimerRef.current = setTimeout(() => { saveTimerRef.current = setTimeout(() => {
console.log('[progress] 💾 Auto-saving position:', Math.round(currentPosition * 100) + '%')
lastSavedPosition.current = currentPosition lastSavedPosition.current = currentPosition
hasSavedOnce.current = true hasSavedOnce.current = true
onSave(currentPosition) onSave(currentPosition)
@@ -78,7 +74,6 @@ export const useReadingPosition = ({
} }
// Always allow immediate save (including 0%) // Always allow immediate save (including 0%)
console.log('[progress] 💾 Immediate save triggered for position:', Math.round(position * 100) + '%')
lastSavedPosition.current = position lastSavedPosition.current = position
hasSavedOnce.current = true hasSavedOnce.current = true
onSave(position) onSave(position)
@@ -109,7 +104,6 @@ export const useReadingPosition = ({
const prevPercent = Math.floor(position * 20) // Groups by 5% const prevPercent = Math.floor(position * 20) // Groups by 5%
const newPercent = Math.floor(clampedProgress * 20) const newPercent = Math.floor(clampedProgress * 20)
if (prevPercent !== newPercent) { if (prevPercent !== newPercent) {
console.log('[progress] 📏 useReadingPosition:', Math.round(clampedProgress * 100) + '%', {
scrollTop, scrollTop,
documentHeight, documentHeight,
isAtBottom isAtBottom
@@ -131,12 +125,10 @@ export const useReadingPosition = ({
if (!hasTriggeredComplete.current && position === 1) { if (!hasTriggeredComplete.current && position === 1) {
setIsReadingComplete(true) setIsReadingComplete(true)
hasTriggeredComplete.current = true hasTriggeredComplete.current = true
console.log('[progress] ✅ Completion hold satisfied (100% for', completionHoldMs, 'ms)')
onReadingComplete?.() onReadingComplete?.()
} }
completionTimerRef.current = null completionTimerRef.current = null
}, completionHoldMs) }, completionHoldMs)
console.log('[progress] ⏳ Completion hold started (waiting', completionHoldMs, 'ms)')
} }
} else { } else {
// If we moved off 100%, cancel any pending completion hold // If we moved off 100%, cancel any pending completion hold
@@ -147,7 +139,6 @@ export const useReadingPosition = ({
if (clampedProgress >= readingCompleteThreshold) { if (clampedProgress >= readingCompleteThreshold) {
setIsReadingComplete(true) setIsReadingComplete(true)
hasTriggeredComplete.current = true hasTriggeredComplete.current = true
console.log('[progress] ✅ Completion via threshold:', readingCompleteThreshold)
onReadingComplete?.() onReadingComplete?.()
} }
} }

View File

@@ -48,7 +48,6 @@ export function useSettings({ relayPool, eventStore, pubkey, accountManager }: U
const root = document.documentElement.style const root = document.documentElement.style
const fontKey = settings.readingFont || 'system' const fontKey = settings.readingFont || 'system'
console.log('🎨 Applying settings styles:', { fontKey, fontSize: settings.fontSize, theme: settings.theme })
// Apply theme with color variants (defaults to 'system' if not set) // Apply theme with color variants (defaults to 'system' if not set)
applyTheme( applyTheme(
@@ -59,9 +58,7 @@ export function useSettings({ relayPool, eventStore, pubkey, accountManager }: U
// Load font first and wait for it to be ready // Load font first and wait for it to be ready
if (fontKey !== 'system') { if (fontKey !== 'system') {
console.log('⏳ Waiting for font to load...')
await loadFont(fontKey) await loadFont(fontKey)
console.log('✅ Font loaded, applying styles')
} }
// Apply font settings after font is loaded // Apply font settings after font is loaded
@@ -76,7 +73,6 @@ export function useSettings({ relayPool, eventStore, pubkey, accountManager }: U
// Set paragraph alignment // Set paragraph alignment
root.setProperty('--paragraph-alignment', settings.paragraphAlignment || 'justify') root.setProperty('--paragraph-alignment', settings.paragraphAlignment || 'justify')
console.log('✅ All styles applied')
} }
applyStyles() applyStyles()

View File

@@ -11,7 +11,6 @@ if ('serviceWorker' in navigator) {
navigator.serviceWorker navigator.serviceWorker
.register('/sw.js', { type: 'module' }) .register('/sw.js', { type: 'module' })
.then(registration => { .then(registration => {
console.log('✅ Service Worker registered:', registration.scope)
// Check for updates periodically // Check for updates periodically
setInterval(() => { setInterval(() => {
@@ -25,7 +24,6 @@ if ('serviceWorker' in navigator) {
newWorker.addEventListener('statechange', () => { newWorker.addEventListener('statechange', () => {
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) { if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
// New service worker available // New service worker available
console.log('🔄 New version available! Reload to update.')
// Optionally show a toast notification // Optionally show a toast notification
const updateAvailable = new CustomEvent('sw-update-available') const updateAvailable = new CustomEvent('sw-update-available')

View File

@@ -48,7 +48,6 @@ function getFromCache(naddr: string): ArticleContent | null {
return null return null
} }
console.log('📦 Loaded article from cache:', naddr)
return content return content
} catch { } catch {
return null return null
@@ -63,7 +62,6 @@ function saveToCache(naddr: string, content: ArticleContent): void {
timestamp: Date.now() timestamp: Date.now()
} }
localStorage.setItem(cacheKey, JSON.stringify(cached)) localStorage.setItem(cacheKey, JSON.stringify(cached))
console.log('💾 Saved article to cache:', naddr)
} catch (err) { } catch (err) {
console.warn('Failed to cache article:', err) console.warn('Failed to cache article:', err)
// Silently fail if storage is full or unavailable // Silently fail if storage is full or unavailable

View File

@@ -31,7 +31,6 @@ async function decryptEvent(
try { try {
await Helpers.unlockHiddenTags(evt, signerCandidate as HiddenContentSigner, 'nip44' as UnlockMode) await Helpers.unlockHiddenTags(evt, signerCandidate as HiddenContentSigner, 'nip44' as UnlockMode)
} catch (err) { } catch (err) {
console.log("[bunker] ❌ nip44.decrypt failed:", err instanceof Error ? err.message : String(err))
} }
} }
} else if (evt.content && evt.content.length > 0) { } else if (evt.content && evt.content.length > 0) {
@@ -46,7 +45,6 @@ async function decryptEvent(
try { try {
decryptedContent = await (signerCandidate as { nip44: { decrypt: DecryptFn } }).nip44.decrypt(evt.pubkey, evt.content) decryptedContent = await (signerCandidate as { nip44: { decrypt: DecryptFn } }).nip44.decrypt(evt.pubkey, evt.content)
} catch (err) { } catch (err) {
console.log("[bunker] ❌ nip44.decrypt failed:", err instanceof Error ? err.message : String(err))
} }
} }
@@ -55,7 +53,6 @@ async function decryptEvent(
try { try {
decryptedContent = await (signerCandidate as { nip04: { decrypt: DecryptFn } }).nip04.decrypt(evt.pubkey, evt.content) decryptedContent = await (signerCandidate as { nip04: { decrypt: DecryptFn } }).nip04.decrypt(evt.pubkey, evt.content)
} catch (err) { } catch (err) {
console.log("[bunker] ❌ nip04.decrypt failed:", err instanceof Error ? err.message : String(err))
} }
} }

View File

@@ -15,7 +15,6 @@ export const fetchContacts = async (
): Promise<Set<string>> => { ): Promise<Set<string>> => {
try { try {
const relayUrls = prioritizeLocalRelays(Array.from(relayPool.relays.values()).map(relay => relay.url)) const relayUrls = prioritizeLocalRelays(Array.from(relayPool.relays.values()).map(relay => relay.url))
console.log('🔍 Fetching contacts (kind 3) for user:', pubkey)
const partialFollowed = new Set<string>() const partialFollowed = new Set<string>()
const events = await queryEvents( const events = await queryEvents(
@@ -51,9 +50,7 @@ export const fetchContacts = async (
} }
// merged already via streams // merged already via streams
console.log('📊 Contact events fetched:', events.length)
console.log('👥 Followed contacts:', followed.size)
return followed return followed
} catch (error) { } catch (error) {
console.error('Failed to fetch contacts:', error) console.error('Failed to fetch contacts:', error)

View File

@@ -73,13 +73,11 @@ class ContactsController {
// Skip if already loaded for this pubkey (unless forced) // Skip if already loaded for this pubkey (unless forced)
if (!force && this.isLoadedFor(pubkey)) { if (!force && this.isLoadedFor(pubkey)) {
console.log('[contacts] ✅ Already loaded for', pubkey.slice(0, 8))
this.emitContacts(this.currentContacts) this.emitContacts(this.currentContacts)
return return
} }
this.setLoading(true) this.setLoading(true)
console.log('[contacts] 🔍 Loading contacts for', pubkey.slice(0, 8))
try { try {
const contacts = await fetchContacts( const contacts = await fetchContacts(
@@ -89,7 +87,6 @@ class ContactsController {
// Stream partial updates // Stream partial updates
this.currentContacts = new Set(partial) this.currentContacts = new Set(partial)
this.emitContacts(this.currentContacts) this.emitContacts(this.currentContacts)
console.log('[contacts] 📥 Partial contacts:', partial.size)
} }
) )
@@ -98,7 +95,6 @@ class ContactsController {
this.lastLoadedPubkey = pubkey this.lastLoadedPubkey = pubkey
this.emitContacts(this.currentContacts) this.emitContacts(this.currentContacts)
console.log('[contacts] ✅ Loaded', contacts.size, 'contacts')
} catch (error) { } catch (error) {
console.error('[contacts] ❌ Failed to load contacts:', error) console.error('[contacts] ❌ Failed to load contacts:', error)
this.currentContacts.clear() this.currentContacts.clear()

View File

@@ -36,12 +36,10 @@ export async function createDeletionRequest(
const signed = await factory.sign(draft) const signed = await factory.sign(draft)
console.log('🗑️ Created kind:5 deletion request for event:', eventId.slice(0, 8))
// Publish to relays // Publish to relays
await relayPool.publish(RELAYS, signed) await relayPool.publish(RELAYS, signed)
console.log('✅ Deletion request published to', RELAYS.length, 'relay(s)')
return signed return signed
} }

View File

@@ -33,11 +33,9 @@ export const fetchBlogPostsFromAuthors = async (
): Promise<BlogPostPreview[]> => { ): Promise<BlogPostPreview[]> => {
try { try {
if (pubkeys.length === 0) { if (pubkeys.length === 0) {
console.log('⚠️ No pubkeys to fetch blog posts from')
return [] return []
} }
console.log('📚 Fetching blog posts (kind 30023) from', pubkeys.length, 'authors', limit ? `(limit: ${limit})` : '(no limit)')
// Deduplicate replaceable events by keeping the most recent version // Deduplicate replaceable events by keeping the most recent version
// Group by author + d-tag identifier // Group by author + d-tag identifier
@@ -75,7 +73,6 @@ export const fetchBlogPostsFromAuthors = async (
} }
) )
console.log('📊 Blog post events fetched (unique):', uniqueEvents.size)
// Convert to blog post previews and sort by published date (most recent first) // Convert to blog post previews and sort by published date (most recent first)
const blogPosts: BlogPostPreview[] = Array.from(uniqueEvents.values()) const blogPosts: BlogPostPreview[] = Array.from(uniqueEvents.values())
@@ -97,7 +94,6 @@ export const fetchBlogPostsFromAuthors = async (
return timeB - timeA // Most recent first return timeB - timeA // Most recent first
}) })
console.log('📰 Processed', blogPosts.length, 'unique blog posts')
return blogPosts return blogPosts
} catch (error) { } catch (error) {

View File

@@ -46,7 +46,6 @@ export async function createHighlight(
} }
// Create EventFactory with the account as signer // Create EventFactory with the account as signer
console.log("[bunker] Creating EventFactory with signer:", { signerType: account.signer?.constructor?.name })
const factory = new EventFactory({ signer: account.signer }) const factory = new EventFactory({ signer: account.signer })
let blueprintSource: NostrEvent | AddressPointer | string let blueprintSource: NostrEvent | AddressPointer | string
@@ -117,9 +116,7 @@ export async function createHighlight(
} }
// Sign the event // Sign the event
console.log('[bunker] Signing highlight event...', { kind: highlightEvent.kind, tags: highlightEvent.tags.length })
const signedEvent = await factory.sign(highlightEvent) const signedEvent = await factory.sign(highlightEvent)
console.log('[bunker] ✅ Highlight signed successfully!', { id: signedEvent.id.slice(0, 8) })
// Use unified write service to store and publish // Use unified write service to store and publish
await publishEvent(relayPool, eventStore, signedEvent) await publishEvent(relayPool, eventStore, signedEvent)

View File

@@ -22,7 +22,6 @@ export const fetchHighlights = async (
const cacheKey = highlightCache.authorKey(pubkey) const cacheKey = highlightCache.authorKey(pubkey)
const cached = highlightCache.get(cacheKey) const cached = highlightCache.get(cacheKey)
if (cached) { if (cached) {
console.log(`📌 Using cached highlights for author (${cached.length} items)`)
// Stream cached highlights if callback provided // Stream cached highlights if callback provided
if (onHighlight) { if (onHighlight) {
cached.forEach(h => onHighlight(h)) cached.forEach(h => onHighlight(h))
@@ -50,7 +49,6 @@ export const fetchHighlights = async (
} }
) )
console.log(`📌 Fetched ${rawEvents.length} highlight events for author:`, pubkey.slice(0, 8))
// Store all events in event store if provided // Store all events in event store if provided
if (eventStore) { if (eventStore) {

View File

@@ -23,7 +23,6 @@ export const fetchHighlightsForArticle = async (
const cacheKey = highlightCache.articleKey(articleCoordinate) const cacheKey = highlightCache.articleKey(articleCoordinate)
const cached = highlightCache.get(cacheKey) const cached = highlightCache.get(cacheKey)
if (cached) { if (cached) {
console.log(`📌 Using cached highlights for article (${cached.length} items)`)
// Stream cached highlights if callback provided // Stream cached highlights if callback provided
if (onHighlight) { if (onHighlight) {
cached.forEach(h => onHighlight(h)) cached.forEach(h => onHighlight(h))
@@ -54,7 +53,6 @@ export const fetchHighlightsForArticle = async (
]) ])
const rawEvents = [...aTagEvents, ...eTagEvents] const rawEvents = [...aTagEvents, ...eTagEvents]
console.log(`📌 Fetched ${rawEvents.length} highlight events for article:`, articleCoordinate)
// Store all events in event store if provided // Store all events in event store if provided
if (eventStore) { if (eventStore) {

View File

@@ -22,7 +22,6 @@ export const fetchHighlightsForUrl = async (
const cacheKey = highlightCache.urlKey(url) const cacheKey = highlightCache.urlKey(url)
const cached = highlightCache.get(cacheKey) const cached = highlightCache.get(cacheKey)
if (cached) { if (cached) {
console.log(`📌 Using cached highlights for URL (${cached.length} items)`)
// Stream cached highlights if callback provided // Stream cached highlights if callback provided
if (onHighlight) { if (onHighlight) {
cached.forEach(h => onHighlight(h)) cached.forEach(h => onHighlight(h))
@@ -50,7 +49,6 @@ export const fetchHighlightsForUrl = async (
} }
) )
console.log(`📌 Fetched ${rawEvents.length} highlight events for URL:`, url)
// Store all events in event store if provided // Store all events in event store if provided
if (eventStore) { if (eventStore) {

View File

@@ -21,11 +21,9 @@ export const fetchHighlightsFromAuthors = async (
): Promise<Highlight[]> => { ): Promise<Highlight[]> => {
try { try {
if (pubkeys.length === 0) { if (pubkeys.length === 0) {
console.log('⚠️ No pubkeys to fetch highlights from')
return [] return []
} }
console.log('💡 Fetching highlights (kind 9802) from', pubkeys.length, 'authors')
const seenIds = new Set<string>() const seenIds = new Set<string>()
const rawEvents = await queryEvents( const rawEvents = await queryEvents(
@@ -55,7 +53,6 @@ export const fetchHighlightsFromAuthors = async (
const uniqueEvents = dedupeHighlights(rawEvents) const uniqueEvents = dedupeHighlights(rawEvents)
const highlights = uniqueEvents.map(eventToHighlight) const highlights = uniqueEvents.map(eventToHighlight)
console.log('💡 Processed', highlights.length, 'unique highlights')
return sortHighlights(highlights) return sortHighlights(highlights)
} catch (error) { } catch (error) {

View File

@@ -110,7 +110,6 @@ class HighlightsController {
// Skip if already loaded for this pubkey (unless forced) // Skip if already loaded for this pubkey (unless forced)
if (!force && this.isLoadedFor(pubkey)) { if (!force && this.isLoadedFor(pubkey)) {
console.log('[highlights] ✅ Already loaded for', pubkey.slice(0, 8))
this.emitHighlights(this.currentHighlights) this.emitHighlights(this.currentHighlights)
return return
} }
@@ -120,7 +119,6 @@ class HighlightsController {
const currentGeneration = this.generation const currentGeneration = this.generation
this.setLoading(true) this.setLoading(true)
console.log('[highlights] 🔍 Loading highlights for', pubkey.slice(0, 8))
try { try {
const seenIds = new Set<string>() const seenIds = new Set<string>()
@@ -134,7 +132,6 @@ class HighlightsController {
} }
if (lastSyncedAt) { if (lastSyncedAt) {
filter.since = lastSyncedAt filter.since = lastSyncedAt
console.log('[highlights] 📅 Incremental sync since', new Date(lastSyncedAt * 1000).toISOString())
} }
const events = await queryEvents( const events = await queryEvents(
@@ -165,7 +162,6 @@ class HighlightsController {
// Check if still active after async operation // Check if still active after async operation
if (currentGeneration !== this.generation) { if (currentGeneration !== this.generation) {
console.log('[highlights] ⚠️ Load cancelled (generation mismatch)')
return return
} }
@@ -189,7 +185,6 @@ class HighlightsController {
this.setLastSyncedAt(pubkey, newestTimestamp) this.setLastSyncedAt(pubkey, newestTimestamp)
} }
console.log('[highlights] ✅ Loaded', sorted.length, 'highlights')
} catch (error) { } catch (error) {
console.error('[highlights] ❌ Failed to load highlights:', error) console.error('[highlights] ❌ Failed to load highlights:', error)
this.currentHighlights = [] this.currentHighlights = []

View File

@@ -13,7 +13,6 @@ const CACHE_NAME = 'boris-image-cache-v1'
export async function clearImageCache(): Promise<void> { export async function clearImageCache(): Promise<void> {
try { try {
await caches.delete(CACHE_NAME) await caches.delete(CACHE_NAME)
console.log('🗑️ Cleared all cached images')
} catch (err) { } catch (err) {
console.error('Failed to clear image cache:', err) console.error('Failed to clear image cache:', err)
} }

View File

@@ -17,7 +17,6 @@ export async function fetchLinks(
userPubkey: string, userPubkey: string,
onItem?: (item: ReadItem) => void onItem?: (item: ReadItem) => void
): Promise<ReadItem[]> { ): Promise<ReadItem[]> {
console.log('🔗 [Links] Fetching external links for user:', userPubkey.slice(0, 8))
const linksMap = new Map<string, ReadItem>() const linksMap = new Map<string, ReadItem>()
@@ -37,7 +36,6 @@ export async function fetchLinks(
fetchReadArticles(relayPool, userPubkey) fetchReadArticles(relayPool, userPubkey)
]) ])
console.log('📊 [Links] Data fetched:', {
readingProgress: progressEvents.length, readingProgress: progressEvents.length,
markedAsRead: markedAsReadArticles.length markedAsRead: markedAsReadArticles.length
}) })
@@ -79,7 +77,6 @@ export async function fetchLinks(
const validLinks = filterValidItems(links) const validLinks = filterValidItems(links)
const sortedLinks = sortByReadingActivity(validLinks) const sortedLinks = sortByReadingActivity(validLinks)
console.log('✅ [Links] Processed', sortedLinks.length, 'total links')
return sortedLinks return sortedLinks
} catch (error) { } catch (error) {

View File

@@ -24,7 +24,6 @@ export const fetchNostrverseBlogPosts = async (
onPost?: (post: BlogPostPreview) => void onPost?: (post: BlogPostPreview) => void
): Promise<BlogPostPreview[]> => { ): Promise<BlogPostPreview[]> => {
try { try {
console.log('[NOSTRVERSE] 📚 Fetching blog posts (kind 30023), limit:', limit)
// Deduplicate replaceable events by keeping the most recent version // Deduplicate replaceable events by keeping the most recent version
const uniqueEvents = new Map<string, NostrEvent>() const uniqueEvents = new Map<string, NostrEvent>()
@@ -63,7 +62,6 @@ export const fetchNostrverseBlogPosts = async (
} }
) )
console.log('[NOSTRVERSE] 📊 Blog post events fetched (unique):', uniqueEvents.size)
// Convert to blog post previews and sort by published date (most recent first) // Convert to blog post previews and sort by published date (most recent first)
const blogPosts: BlogPostPreview[] = Array.from(uniqueEvents.values()) const blogPosts: BlogPostPreview[] = Array.from(uniqueEvents.values())
@@ -81,7 +79,6 @@ export const fetchNostrverseBlogPosts = async (
return timeB - timeA // Most recent first return timeB - timeA // Most recent first
}) })
console.log('[NOSTRVERSE] 📰 Processed', blogPosts.length, 'unique blog posts')
return blogPosts return blogPosts
} catch (error) { } catch (error) {
@@ -103,7 +100,6 @@ export const fetchNostrverseHighlights = async (
eventStore?: IEventStore eventStore?: IEventStore
): Promise<Highlight[]> => { ): Promise<Highlight[]> => {
try { try {
console.log('[NOSTRVERSE] 💡 Fetching highlights (kind 9802), limit:', limit)
const seenIds = new Set<string>() const seenIds = new Set<string>()
// Collect but do not block callers awaiting network completion // Collect but do not block callers awaiting network completion
@@ -133,7 +129,6 @@ export const fetchNostrverseHighlights = async (
const uniqueEvents = dedupeHighlights([...collected, ...rawEvents]) const uniqueEvents = dedupeHighlights([...collected, ...rawEvents])
const highlights = uniqueEvents.map(eventToHighlight) const highlights = uniqueEvents.map(eventToHighlight)
console.log('[NOSTRVERSE] 💡 Processed', highlights.length, 'unique highlights')
return sortHighlights(highlights) return sortHighlights(highlights)
} catch (error) { } catch (error) {

View File

@@ -20,7 +20,6 @@ const syncStateListeners: Array<(eventId: string, isSyncing: boolean) => void> =
*/ */
export function markEventAsOfflineCreated(eventId: string): void { export function markEventAsOfflineCreated(eventId: string): void {
offlineCreatedEvents.add(eventId) offlineCreatedEvents.add(eventId)
console.log(`📝 Marked event ${eventId.slice(0, 8)} as offline-created. Total: ${offlineCreatedEvents.size}`)
} }
/** /**
@@ -57,49 +56,35 @@ export async function syncLocalEventsToRemote(
eventStore: IEventStore eventStore: IEventStore
): Promise<void> { ): Promise<void> {
if (isSyncing) { if (isSyncing) {
console.log('⏳ Sync already in progress, skipping...')
return return
} }
console.log('🔄 Coming back online - syncing local events to remote relays...')
console.log(`📦 Offline events tracked: ${offlineCreatedEvents.size}`)
isSyncing = true isSyncing = true
try { try {
const remoteRelays = RELAYS.filter(url => !isLocalRelay(url)) const remoteRelays = RELAYS.filter(url => !isLocalRelay(url))
console.log(`📡 Remote relays: ${remoteRelays.length}`)
if (remoteRelays.length === 0) { if (remoteRelays.length === 0) {
console.log('⚠️ No remote relays available for sync')
isSyncing = false isSyncing = false
return return
} }
if (offlineCreatedEvents.size === 0) { if (offlineCreatedEvents.size === 0) {
console.log('✅ No offline events to sync')
isSyncing = false isSyncing = false
return return
} }
// Get events from EventStore using the tracked IDs // Get events from EventStore using the tracked IDs
const eventsToSync: NostrEvent[] = [] const eventsToSync: NostrEvent[] = []
console.log(`🔍 Querying EventStore for ${offlineCreatedEvents.size} offline events...`)
for (const eventId of offlineCreatedEvents) { for (const eventId of offlineCreatedEvents) {
const event = eventStore.getEvent(eventId) const event = eventStore.getEvent(eventId)
if (event) { if (event) {
console.log(`📥 Found event ${eventId.slice(0, 8)} (kind ${event.kind}) in EventStore`)
eventsToSync.push(event) eventsToSync.push(event)
} else {
console.warn(`⚠️ Event ${eventId.slice(0, 8)} not found in EventStore`)
} }
} }
console.log(`📊 Total events to sync: ${eventsToSync.length}`)
if (eventsToSync.length === 0) { if (eventsToSync.length === 0) {
console.log('✅ No events found in EventStore to sync')
isSyncing = false isSyncing = false
offlineCreatedEvents.clear() offlineCreatedEvents.clear()
return return
@@ -110,8 +95,6 @@ export async function syncLocalEventsToRemote(
new Map(eventsToSync.map(e => [e.id, e])).values() new Map(eventsToSync.map(e => [e.id, e])).values()
) )
console.log(`📤 Syncing ${uniqueEvents.length} event(s) to remote relays...`)
// Mark all events as syncing // Mark all events as syncing
uniqueEvents.forEach(event => { uniqueEvents.forEach(event => {
syncingEvents.add(event.id) syncingEvents.add(event.id)
@@ -127,13 +110,10 @@ export async function syncLocalEventsToRemote(
await relayPool.publish(remoteRelays, event) await relayPool.publish(remoteRelays, event)
successCount++ successCount++
successfulIds.push(event.id) successfulIds.push(event.id)
console.log(`✅ Synced event ${event.id.slice(0, 8)}`)
} catch (error) { } catch (error) {
console.warn(`⚠️ Failed to sync event ${event.id.slice(0, 8)}:`, error) // Silently fail for individual events
} }
} }
console.log(`✅ Synced ${successCount}/${uniqueEvents.length} events to remote relays`)
// Clear syncing state and offline tracking for successful events // Clear syncing state and offline tracking for successful events
successfulIds.forEach(eventId => { successfulIds.forEach(eventId => {
@@ -150,7 +130,7 @@ export async function syncLocalEventsToRemote(
} }
}) })
} catch (error) { } catch (error) {
console.error('❌ Error during offline sync:', error) // Silently fail
} finally { } finally {
isSyncing = false isSyncing = false
} }

View File

@@ -22,7 +22,6 @@ export const fetchProfiles = async (
} }
const uniquePubkeys = Array.from(new Set(pubkeys)) const uniquePubkeys = Array.from(new Set(pubkeys))
console.log('👤 Fetching profiles (kind:0) for', uniquePubkeys.length, 'authors')
const relayUrls = Array.from(relayPool.relays.values()).map(relay => relay.url) const relayUrls = Array.from(relayPool.relays.values()).map(relay => relay.url)
const prioritized = prioritizeLocalRelays(relayUrls) const prioritized = prioritizeLocalRelays(relayUrls)
@@ -65,7 +64,6 @@ export const fetchProfiles = async (
await lastValueFrom(merge(local$, remote$).pipe(toArray())) await lastValueFrom(merge(local$, remote$).pipe(toArray()))
const profiles = Array.from(profilesByPubkey.values()) const profiles = Array.from(profilesByPubkey.values())
console.log('✅ Fetched', profiles.length, 'unique profiles')
// Rebroadcast profiles to local/all relays based on settings // Rebroadcast profiles to local/all relays based on settings
if (profiles.length > 0) { if (profiles.length > 0) {

View File

@@ -42,12 +42,10 @@ export async function createEventReaction(
const signed = await factory.sign(draft) const signed = await factory.sign(draft)
console.log('📚 Created kind:7 reaction (mark as read) for event:', eventId.slice(0, 8))
// Publish to relays // Publish to relays
await relayPool.publish(RELAYS, signed) await relayPool.publish(RELAYS, signed)
console.log('✅ Reaction published to', RELAYS.length, 'relay(s)')
return signed return signed
} }
@@ -94,12 +92,10 @@ export async function createWebsiteReaction(
const signed = await factory.sign(draft) const signed = await factory.sign(draft)
console.log('📚 Created kind:17 reaction (mark as read) for URL:', normalizedUrl)
// Publish to relays // Publish to relays
await relayPool.publish(RELAYS, signed) await relayPool.publish(RELAYS, signed)
console.log('✅ Website reaction published to', RELAYS.length, 'relay(s)')
return signed return signed
} }

View File

@@ -27,31 +27,23 @@ export function processReadingProgress(
events: NostrEvent[], events: NostrEvent[],
readsMap: Map<string, ReadItem> readsMap: Map<string, ReadItem>
): void { ): void {
console.log('[progress] 🔧 processReadingProgress called with', events.length, 'events')
for (const event of events) { for (const event of events) {
if (event.kind !== READING_PROGRESS_KIND) { if (event.kind !== READING_PROGRESS_KIND) {
console.log('[progress] ⏭️ Skipping event with wrong kind:', event.kind)
continue continue
} }
const dTag = event.tags.find(t => t[0] === 'd')?.[1] const dTag = event.tags.find(t => t[0] === 'd')?.[1]
if (!dTag) { if (!dTag) {
console.log('[progress] ⚠️ Event missing d-tag:', event.id.slice(0, 8))
continue continue
} }
console.log('[progress] 📝 Processing event:', event.id.slice(0, 8), 'd-tag:', dTag.slice(0, 50))
try { try {
const content = JSON.parse(event.content) const content = JSON.parse(event.content)
const position = content.progress || 0 const position = content.progress || 0
console.log('[progress] 📊 Progress value:', position, '(' + Math.round(position * 100) + '%)')
// Validate progress is between 0 and 1 (NIP-85 requirement) // Validate progress is between 0 and 1 (NIP-85 requirement)
if (position < 0 || position > 1) { if (position < 0 || position > 1) {
console.warn('[progress] ❌ Invalid progress value (must be 0-1):', position, 'event:', event.id.slice(0, 8))
continue continue
} }
@@ -76,13 +68,10 @@ export function processReadingProgress(
}) })
itemId = naddr itemId = naddr
itemType = 'article' itemType = 'article'
console.log('[progress] ✅ Converted coordinate to naddr:', naddr.slice(0, 50))
} catch (e) { } catch (e) {
console.warn('[progress] ❌ Failed to encode naddr from coordinate:', dTag)
continue continue
} }
} else { } else {
console.warn('[progress] ⚠️ Invalid coordinate format:', dTag)
continue continue
} }
} else if (dTag.startsWith('url:')) { } else if (dTag.startsWith('url:')) {
@@ -92,13 +81,10 @@ export function processReadingProgress(
itemUrl = atob(encoded.replace(/-/g, '+').replace(/_/g, '/')) itemUrl = atob(encoded.replace(/-/g, '+').replace(/_/g, '/'))
itemId = itemUrl itemId = itemUrl
itemType = 'external' itemType = 'external'
console.log('[progress] ✅ Decoded URL:', itemUrl.slice(0, 50))
} catch (e) { } catch (e) {
console.warn('[progress] ❌ Failed to decode URL from d tag:', dTag)
continue continue
} }
} else { } else {
console.warn('[progress] ⚠️ Unknown d-tag format:', dTag)
continue continue
} }
@@ -114,16 +100,11 @@ export function processReadingProgress(
readingProgress: position, readingProgress: position,
readingTimestamp: timestamp readingTimestamp: timestamp
}) })
console.log('[progress] ✅ Added/updated item in readsMap:', itemId.slice(0, 50), '=', Math.round(position * 100) + '%')
} else {
console.log('[progress] ⏭️ Skipping older event for:', itemId.slice(0, 50))
} }
} catch (error) { } catch (error) {
console.warn('[progress] ❌ Failed to parse reading progress event:', error) // Silently fail
} }
} }
console.log('[progress] 🏁 processReadingProgress finished, readsMap size:', readsMap.size)
} }
/** /**

View File

@@ -49,14 +49,10 @@ function generateDTag(naddrOrUrl: string): string {
const decoded = nip19.decode(naddrOrUrl) const decoded = nip19.decode(naddrOrUrl)
if (decoded.type === 'naddr') { if (decoded.type === 'naddr') {
const dTag = `${decoded.data.kind}:${decoded.data.pubkey}:${decoded.data.identifier || ''}` const dTag = `${decoded.data.kind}:${decoded.data.pubkey}:${decoded.data.identifier || ''}`
console.log('[progress] 📋 Generated d-tag from naddr:', {
naddr: naddrOrUrl.slice(0, 50) + '...',
dTag: dTag.slice(0, 80) + '...'
})
return dTag return dTag
} }
} catch (e) { } catch (e) {
console.warn('Failed to decode naddr:', naddrOrUrl) // Ignore decode errors
} }
} }
@@ -119,14 +115,6 @@ export async function saveReadingPosition(
articleIdentifier: string, articleIdentifier: string,
position: ReadingPosition position: ReadingPosition
): Promise<void> { ): Promise<void> {
console.log('[progress] 💾 saveReadingPosition: Starting save:', {
identifier: articleIdentifier.slice(0, 50) + '...',
position: position.position,
positionPercent: Math.round(position.position * 100) + '%',
timestamp: position.timestamp,
scrollTop: position.scrollTop
})
const now = Math.floor(Date.now() / 1000) const now = Math.floor(Date.now() / 1000)
const progressContent: ReadingProgressContent = { const progressContent: ReadingProgressContent = {
@@ -138,13 +126,6 @@ export async function saveReadingPosition(
const tags = generateProgressTags(articleIdentifier) const tags = generateProgressTags(articleIdentifier)
console.log('[progress] 📝 Creating event with:', {
kind: READING_PROGRESS_KIND,
content: progressContent,
tags: tags.map(t => `[${t.join(', ')}]`).join(', '),
created_at: now
})
const draft = await factory.create(async () => ({ const draft = await factory.create(async () => ({
kind: READING_PROGRESS_KIND, kind: READING_PROGRESS_KIND,
content: JSON.stringify(progressContent), content: JSON.stringify(progressContent),
@@ -152,20 +133,9 @@ export async function saveReadingPosition(
created_at: now created_at: now
})) }))
console.log('[progress] ✍️ Signing event...')
const signed = await factory.sign(draft) const signed = await factory.sign(draft)
console.log('[progress] 📡 Publishing event:', {
id: signed.id,
kind: signed.kind,
pubkey: signed.pubkey.slice(0, 8) + '...',
content: signed.content,
tags: signed.tags
})
await publishEvent(relayPool, eventStore, signed) await publishEvent(relayPool, eventStore, signed)
console.log('[progress] ✅ Event published successfully, ID:', signed.id.slice(0, 16))
} }
/** /**
@@ -179,12 +149,6 @@ export async function loadReadingPosition(
): Promise<ReadingPosition | null> { ): Promise<ReadingPosition | null> {
const dTag = generateDTag(articleIdentifier) const dTag = generateDTag(articleIdentifier)
console.log('📖 [ReadingProgress] Loading position:', {
pubkey: pubkey.slice(0, 8) + '...',
identifier: articleIdentifier.slice(0, 32) + '...',
dTag: dTag.slice(0, 50) + '...'
})
// Check local event store first // Check local event store first
try { try {
const localEvent = await firstValueFrom( const localEvent = await firstValueFrom(
@@ -193,12 +157,6 @@ export async function loadReadingPosition(
if (localEvent) { if (localEvent) {
const content = getReadingProgressContent(localEvent) const content = getReadingProgressContent(localEvent)
if (content) { if (content) {
console.log('✅ [ReadingProgress] Loaded from local store:', {
position: content.position,
positionPercent: Math.round(content.position * 100) + '%',
timestamp: content.timestamp
})
// Fetch from relays in background to get any updates // Fetch from relays in background to get any updates
relayPool relayPool
.subscription(RELAYS, { .subscription(RELAYS, {
@@ -213,7 +171,7 @@ export async function loadReadingPosition(
} }
} }
} catch (err) { } catch (err) {
console.log('📭 No cached reading progress found, fetching from relays...') // Ignore errors and fetch from relays
} }
// Fetch from relays // Fetch from relays
@@ -226,13 +184,7 @@ export async function loadReadingPosition(
getReadingProgressContent getReadingProgressContent
) )
if (result) { return result || null
console.log('✅ [ReadingProgress] Loaded from relays')
return result
}
console.log('📭 No reading progress found')
return null
} }
// Helper function to fetch from relays with timeout // Helper function to fetch from relays with timeout

View File

@@ -45,7 +45,6 @@ class ReadingProgressController {
} }
private emitProgress(progressMap: Map<string, number>): void { private emitProgress(progressMap: Map<string, number>): void {
console.log('[progress] 📡 Emitting to', this.progressListeners.length, 'listeners with', progressMap.size, 'items')
this.progressListeners.forEach(cb => cb(new Map(progressMap))) this.progressListeners.forEach(cb => cb(new Map(progressMap)))
} }
@@ -81,7 +80,7 @@ class ReadingProgressController {
parsed[pubkey] = Object.fromEntries(progressMap.entries()) parsed[pubkey] = Object.fromEntries(progressMap.entries())
localStorage.setItem(PROGRESS_CACHE_KEY, JSON.stringify(parsed)) localStorage.setItem(PROGRESS_CACHE_KEY, JSON.stringify(parsed))
} catch (err) { } catch (err) {
console.warn('[progress] ⚠️ Failed to persist reading progress cache:', err) // Silently fail cache persistence
} }
} }
@@ -109,7 +108,7 @@ class ReadingProgressController {
try { try {
this.timelineSubscription.unsubscribe() this.timelineSubscription.unsubscribe()
} catch (err) { } catch (err) {
console.warn('[progress] ⚠️ Failed to unsubscribe timeline on reset:', err) // Silently fail on unsubscribe
} }
this.timelineSubscription = null this.timelineSubscription = null
} }
@@ -142,7 +141,7 @@ class ReadingProgressController {
parsed[pubkey] = timestamp parsed[pubkey] = timestamp
localStorage.setItem(LAST_SYNCED_KEY, JSON.stringify(parsed)) localStorage.setItem(LAST_SYNCED_KEY, JSON.stringify(parsed))
} catch (err) { } catch (err) {
console.warn('Failed to update last synced timestamp:', err) // Silently fail
} }
} }
@@ -160,12 +159,9 @@ class ReadingProgressController {
// Skip if already loaded for this pubkey and not forcing // Skip if already loaded for this pubkey and not forcing
if (!force && this.isLoadedFor(pubkey)) { if (!force && this.isLoadedFor(pubkey)) {
console.log('📊 [ReadingProgress] Already loaded for', pubkey.slice(0, 8))
return return
} }
console.log('📊 [ReadingProgress] Loading for', pubkey.slice(0, 8), force ? '(forced)' : '')
this.setLoading(true) this.setLoading(true)
this.lastLoadedPubkey = pubkey this.lastLoadedPubkey = pubkey
@@ -173,7 +169,6 @@ class ReadingProgressController {
// Seed from local cache immediately (survives refresh/flight mode) // Seed from local cache immediately (survives refresh/flight mode)
const cached = this.loadCachedProgress(pubkey) const cached = this.loadCachedProgress(pubkey)
if (cached.size > 0) { if (cached.size > 0) {
console.log('📊 [ReadingProgress] Seeded from cache:', cached.size, 'items')
this.currentProgressMap = cached this.currentProgressMap = cached
this.emitProgress(this.currentProgressMap) this.emitProgress(this.currentProgressMap)
} }
@@ -184,7 +179,7 @@ class ReadingProgressController {
try { try {
this.timelineSubscription.unsubscribe() this.timelineSubscription.unsubscribe()
} catch (err) { } catch (err) {
console.warn('[progress] ⚠️ Failed to unsubscribe previous timeline:', err) // Silently fail
} }
this.timelineSubscription = null this.timelineSubscription = null
} }
@@ -198,7 +193,6 @@ class ReadingProgressController {
// Ignore if controller generation has changed (e.g., logout/login) // Ignore if controller generation has changed (e.g., logout/login)
if (generationAtSubscribe !== this.generation) return if (generationAtSubscribe !== this.generation) return
if (!Array.isArray(localEvents) || localEvents.length === 0) return if (!Array.isArray(localEvents) || localEvents.length === 0) return
console.log('📊 [ReadingProgress] Timeline update with', localEvents.length, 'event(s)')
this.processEvents(localEvents) this.processEvents(localEvents)
}) })
@@ -214,15 +208,11 @@ class ReadingProgressController {
if (lastSynced && !needsFullSync) { if (lastSynced && !needsFullSync) {
filter.since = lastSynced filter.since = lastSynced
console.log('📊 [ReadingProgress] Incremental sync since', new Date(lastSynced * 1000).toISOString())
} else {
console.log('📊 [ReadingProgress] Full sync (map size:', this.currentProgressMap.size + ')')
} }
const relayEvents = await queryEvents(relayPool, filter, { relayUrls: RELAYS }) const relayEvents = await queryEvents(relayPool, filter, { relayUrls: RELAYS })
if (startGeneration !== this.generation) { if (startGeneration !== this.generation) {
console.log('📊 [ReadingProgress] Cancelled (generation changed)')
return return
} }
@@ -232,13 +222,10 @@ class ReadingProgressController {
// Process and emit (merge with existing) // Process and emit (merge with existing)
this.processEvents(relayEvents) this.processEvents(relayEvents)
console.log('📊 [ReadingProgress] Loaded', relayEvents.length, 'events from relays')
// Update last synced // Update last synced
const now = Math.floor(Date.now() / 1000) const now = Math.floor(Date.now() / 1000)
this.updateLastSyncedAt(pubkey, now) this.updateLastSyncedAt(pubkey, now)
} else {
console.log('📊 [ReadingProgress] No new events from relays')
} }
} catch (err) { } catch (err) {
console.error('📊 [ReadingProgress] Failed to load:', err) console.error('📊 [ReadingProgress] Failed to load:', err)
@@ -253,8 +240,6 @@ class ReadingProgressController {
* Process events and update progress map * Process events and update progress map
*/ */
private processEvents(events: NostrEvent[]): void { private processEvents(events: NostrEvent[]): void {
console.log('[progress] 🔄 Processing', events.length, 'events')
const readsMap = new Map<string, ReadItem>() const readsMap = new Map<string, ReadItem>()
// Merge with existing progress // Merge with existing progress
@@ -267,24 +252,17 @@ class ReadingProgressController {
}) })
} }
console.log('[progress] 📦 Starting with', readsMap.size, 'existing items')
// Process new events // Process new events
processReadingProgress(events, readsMap) processReadingProgress(events, readsMap)
console.log('[progress] 📦 After processing:', readsMap.size, 'items')
// Convert back to progress map (naddr -> progress) // Convert back to progress map (naddr -> progress)
const newProgressMap = new Map<string, number>() const newProgressMap = new Map<string, number>()
for (const [id, item] of readsMap.entries()) { for (const [id, item] of readsMap.entries()) {
if (item.readingProgress !== undefined && item.type === 'article') { if (item.readingProgress !== undefined && item.type === 'article') {
newProgressMap.set(id, item.readingProgress) newProgressMap.set(id, item.readingProgress)
console.log('[progress] ✅ Added:', id.slice(0, 50) + '...', '=', Math.round(item.readingProgress * 100) + '%')
} }
} }
console.log('[progress] 📊 Final progress map size:', newProgressMap.size)
this.currentProgressMap = newProgressMap this.currentProgressMap = newProgressMap
this.emitProgress(this.currentProgressMap) this.emitProgress(this.currentProgressMap)

View File

@@ -46,7 +46,6 @@ export async function fetchAllReads(
bookmarks: Bookmark[], bookmarks: Bookmark[],
onItem?: (item: ReadItem) => void onItem?: (item: ReadItem) => void
): Promise<ReadItem[]> { ): Promise<ReadItem[]> {
console.log('📚 [Reads] Fetching all reads for user:', userPubkey.slice(0, 8))
const readsMap = new Map<string, ReadItem>() const readsMap = new Map<string, ReadItem>()
@@ -66,7 +65,6 @@ export async function fetchAllReads(
fetchReadArticles(relayPool, userPubkey) fetchReadArticles(relayPool, userPubkey)
]) ])
console.log('📊 [Reads] Data fetched:', {
readingProgress: progressEvents.length, readingProgress: progressEvents.length,
markedAsRead: markedAsReadArticles.length, markedAsRead: markedAsReadArticles.length,
bookmarks: bookmarks.length bookmarks: bookmarks.length
@@ -120,7 +118,6 @@ export async function fetchAllReads(
.map(item => item.id) .map(item => item.id)
if (articleCoordinates.length > 0) { if (articleCoordinates.length > 0) {
console.log('📖 [Reads] Fetching article events for', articleCoordinates.length, 'articles')
// Parse coordinates and fetch events // Parse coordinates and fetch events
const articlesToFetch: Array<{ pubkey: string; identifier: string }> = [] const articlesToFetch: Array<{ pubkey: string; identifier: string }> = []
@@ -187,7 +184,6 @@ export async function fetchAllReads(
const validArticles = filterValidItems(articles) const validArticles = filterValidItems(articles)
const sortedReads = sortByReadingActivity(validArticles) const sortedReads = sortByReadingActivity(validArticles)
console.log('✅ [Reads] Processed', sortedReads.length, 'total reads')
return sortedReads return sortedReads
} catch (error) { } catch (error) {

View File

@@ -34,7 +34,6 @@ export async function rebroadcastEvents(
// If we're in flight mode (only local relays connected) and user wants to broadcast to all relays, skip // If we're in flight mode (only local relays connected) and user wants to broadcast to all relays, skip
if (broadcastToAll && !hasRemoteConnection) { if (broadcastToAll && !hasRemoteConnection) {
console.log('✈️ Flight mode: skipping rebroadcast to remote relays')
return return
} }
@@ -50,7 +49,6 @@ export async function rebroadcastEvents(
} }
if (targetRelays.length === 0) { if (targetRelays.length === 0) {
console.log('📡 No target relays for rebroadcast')
return return
} }
@@ -58,7 +56,6 @@ export async function rebroadcastEvents(
const rebroadcastPromises = events.map(async (event) => { const rebroadcastPromises = events.map(async (event) => {
try { try {
await relayPool.publish(targetRelays, event) await relayPool.publish(targetRelays, event)
console.log('📡 Rebroadcast event', event.id?.slice(0, 8), 'to', targetRelays.length, 'relay(s)')
} catch (error) { } catch (error) {
console.warn('⚠️ Failed to rebroadcast event', event.id?.slice(0, 8), error) console.warn('⚠️ Failed to rebroadcast event', event.id?.slice(0, 8), error)
} }
@@ -69,7 +66,6 @@ export async function rebroadcastEvents(
console.warn('⚠️ Some rebroadcasts failed:', err) console.warn('⚠️ Some rebroadcasts failed:', err)
}) })
console.log(`📡 Rebroadcasting ${events.length} event(s) to ${targetRelays.length} relay(s)`, {
broadcastToAll, broadcastToAll,
useLocalCache, useLocalCache,
targetRelays targetRelays

View File

@@ -40,11 +40,8 @@ export function updateAndGetRelayStatuses(relayPool: RelayPool): RelayStatus[] {
const connectedCount = statuses.filter(s => s.isInPool).length const connectedCount = statuses.filter(s => s.isInPool).length
const disconnectedCount = statuses.filter(s => !s.isInPool).length const disconnectedCount = statuses.filter(s => !s.isInPool).length
if (connectedCount === 0 || disconnectedCount > 0) { if (connectedCount === 0 || disconnectedCount > 0) {
console.log(`🔌 Relay status: ${connectedCount} connected, ${disconnectedCount} disconnected`)
const connected = statuses.filter(s => s.isInPool).map(s => s.url.replace(/^wss?:\/\//, '')) const connected = statuses.filter(s => s.isInPool).map(s => s.url.replace(/^wss?:\/\//, ''))
const disconnected = statuses.filter(s => !s.isInPool).map(s => s.url.replace(/^wss?:\/\//, '')) const disconnected = statuses.filter(s => !s.isInPool).map(s => s.url.replace(/^wss?:\/\//, ''))
if (connected.length > 0) console.log('✅ Connected:', connected.join(', '))
if (disconnected.length > 0) console.log('❌ Disconnected:', disconnected.join(', '))
} }
// Add recently seen relays that are no longer connected // Add recently seen relays that are no longer connected

View File

@@ -71,7 +71,6 @@ export async function loadSettings(
pubkey: string, pubkey: string,
relays: string[] relays: string[]
): Promise<UserSettings | null> { ): Promise<UserSettings | null> {
console.log('⚙️ Loading settings from nostr...', { pubkey: pubkey.slice(0, 8) + '...', relays })
// First, check if we already have settings in the local event store // First, check if we already have settings in the local event store
try { try {
@@ -80,7 +79,6 @@ export async function loadSettings(
) )
if (localEvent) { if (localEvent) {
const content = getAppDataContent<UserSettings>(localEvent) const content = getAppDataContent<UserSettings>(localEvent)
console.log('✅ Settings loaded from local store (cached):', content)
// Still fetch from relays in the background to get any updates // Still fetch from relays in the background to get any updates
relayPool relayPool
@@ -95,7 +93,6 @@ export async function loadSettings(
return content || null return content || null
} }
} catch (err) { } catch (err) {
console.log('📭 No cached settings found, fetching from relays...')
} }
// If not in local store, fetch from relays // If not in local store, fetch from relays
@@ -127,10 +124,8 @@ export async function loadSettings(
) )
if (event) { if (event) {
const content = getAppDataContent<UserSettings>(event) const content = getAppDataContent<UserSettings>(event)
console.log('✅ Settings loaded from relays:', content)
resolve(content || null) resolve(content || null)
} else { } else {
console.log('📭 No settings event found - using defaults')
resolve(null) resolve(null)
} }
} catch (err) { } catch (err) {
@@ -161,7 +156,6 @@ export async function saveSettings(
factory: EventFactory, factory: EventFactory,
settings: UserSettings settings: UserSettings
): Promise<void> { ): Promise<void> {
console.log('💾 Saving settings to nostr:', settings)
// Create NIP-78 application data event manually // Create NIP-78 application data event manually
// Note: AppDataBlueprint is not available in the npm package // Note: AppDataBlueprint is not available in the npm package
@@ -177,7 +171,6 @@ export async function saveSettings(
// Use unified write service // Use unified write service
await publishEvent(relayPool, eventStore, signed) await publishEvent(relayPool, eventStore, signed)
console.log('✅ Settings published successfully')
} }
export function watchSettings( export function watchSettings(

View File

@@ -78,7 +78,6 @@ export async function createWebBookmark(
// Publish to relays in the background (don't block UI) // Publish to relays in the background (don't block UI)
relayPool.publish(relays, signedEvent) relayPool.publish(relays, signedEvent)
.then(() => { .then(() => {
console.log('✅ Web bookmark published to', relays.length, 'relays:', signedEvent)
}) })
.catch((err) => { .catch((err) => {
console.warn('⚠️ Some relays failed to publish bookmark:', err) console.warn('⚠️ Some relays failed to publish bookmark:', err)

View File

@@ -19,7 +19,6 @@ export async function publishEvent(
// Store the event in the local EventStore FIRST for immediate UI display // Store the event in the local EventStore FIRST for immediate UI display
eventStore.add(event) eventStore.add(event)
console.log(`${logPrefix} 💾 Stored event in EventStore:`, event.id.slice(0, 8), `(kind ${event.kind})`)
// Check current connection status - are we online or in flight mode? // Check current connection status - are we online or in flight mode?
const connectedRelays = Array.from(relayPool.relays.values()) const connectedRelays = Array.from(relayPool.relays.values())
@@ -35,7 +34,6 @@ export async function publishEvent(
const isLocalOnly = areAllRelaysLocal(expectedSuccessRelays) const isLocalOnly = areAllRelaysLocal(expectedSuccessRelays)
console.log(`${logPrefix} 📍 Event relay status:`, {
targetRelays: RELAYS.length, targetRelays: RELAYS.length,
expectedSuccessRelays: expectedSuccessRelays.length, expectedSuccessRelays: expectedSuccessRelays.length,
isLocalOnly, isLocalOnly,
@@ -50,10 +48,8 @@ export async function publishEvent(
} }
// Publish to all configured relays in the background (non-blocking) // Publish to all configured relays in the background (non-blocking)
console.log(`${logPrefix} 📤 Publishing to relays:`, RELAYS)
relayPool.publish(RELAYS, event) relayPool.publish(RELAYS, event)
.then(() => { .then(() => {
console.log(`${logPrefix} ✅ Event published to`, RELAYS.length, 'relay(s):', event.id.slice(0, 8))
}) })
.catch((error) => { .catch((error) => {
console.warn(`${logPrefix} ⚠️ Failed to publish event to relays (event still saved locally):`, error) console.warn(`${logPrefix} ⚠️ Failed to publish event to relays (event still saved locally):`, error)

View File

@@ -138,7 +138,6 @@ class WritingsController {
// Skip if already loaded for this pubkey (unless forced) // Skip if already loaded for this pubkey (unless forced)
if (!force && this.isLoadedFor(pubkey)) { if (!force && this.isLoadedFor(pubkey)) {
console.log('[writings] ✅ Already loaded for', pubkey.slice(0, 8))
this.emitWritings(this.currentPosts) this.emitWritings(this.currentPosts)
return return
} }
@@ -148,7 +147,6 @@ class WritingsController {
const currentGeneration = this.generation const currentGeneration = this.generation
this.setLoading(true) this.setLoading(true)
console.log('[writings] 🔍 Loading writings for', pubkey.slice(0, 8))
try { try {
const seenIds = new Set<string>() const seenIds = new Set<string>()
@@ -162,7 +160,6 @@ class WritingsController {
} }
if (lastSyncedAt) { if (lastSyncedAt) {
filter.since = lastSyncedAt filter.since = lastSyncedAt
console.log('[writings] 📅 Incremental sync since', new Date(lastSyncedAt * 1000).toISOString())
} }
const events = await queryEvents( const events = await queryEvents(
@@ -201,7 +198,6 @@ class WritingsController {
// Check if still active after async operation // Check if still active after async operation
if (currentGeneration !== this.generation) { if (currentGeneration !== this.generation) {
console.log('[writings] ⚠️ Load cancelled (generation mismatch)')
return return
} }
@@ -231,7 +227,6 @@ class WritingsController {
this.setLastSyncedAt(pubkey, newestTimestamp) this.setLastSyncedAt(pubkey, newestTimestamp)
} }
console.log('[writings] ✅ Loaded', sorted.length, 'writings')
} catch (error) { } catch (error) {
console.error('[writings] ❌ Failed to load writings:', error) console.error('[writings] ❌ Failed to load writings:', error)
this.currentPosts = [] this.currentPosts = []

View File

@@ -22,7 +22,6 @@ export async function fetchBorisZappers(
relayPool: RelayPool relayPool: RelayPool
): Promise<ZapSender[]> { ): Promise<ZapSender[]> {
try { try {
console.log('⚡ Fetching zap receipts for Boris...', BORIS_PUBKEY)
// Use all configured relays plus specific zap-heavy relays // Use all configured relays plus specific zap-heavy relays
const zapRelays = [ const zapRelays = [
@@ -63,7 +62,6 @@ export async function fetchBorisZappers(
merge(local$, remote$).pipe(toArray()) merge(local$, remote$).pipe(toArray())
) )
console.log(`📊 Fetched ${zapReceipts.length} raw zap receipts`)
// Dedupe by event ID and validate // Dedupe by event ID and validate
const uniqueReceipts = new Map<string, NostrEvent>() const uniqueReceipts = new Map<string, NostrEvent>()
@@ -79,7 +77,6 @@ export async function fetchBorisZappers(
} }
}) })
console.log(`${uniqueReceipts.size} valid zap receipts (${invalidCount} invalid)`)
// Aggregate by sender using applesauce helpers // Aggregate by sender using applesauce helpers
const senderTotals = new Map<string, { totalSats: number; zapCount: number }>() const senderTotals = new Map<string, { totalSats: number; zapCount: number }>()
@@ -102,7 +99,6 @@ export async function fetchBorisZappers(
}) })
} }
console.log(`👥 Found ${senderTotals.size} unique senders`)
// Filter >= 2100 sats, mark whales >= 69420 sats, sort by total desc // Filter >= 2100 sats, mark whales >= 69420 sats, sort by total desc
const zappers: ZapSender[] = Array.from(senderTotals.entries()) const zappers: ZapSender[] = Array.from(senderTotals.entries())
@@ -115,7 +111,6 @@ export async function fetchBorisZappers(
})) }))
.sort((a, b) => b.totalSats - a.totalSats) .sort((a, b) => b.totalSats - a.totalSats)
console.log(`✅ Found ${zappers.length} supporters (${zappers.filter(z => z.isWhale).length} whales)`)
return zappers return zappers
} catch (error) { } catch (error) {

View File

@@ -22,7 +22,6 @@ cleanupOutdatedCaches()
sw.skipWaiting() sw.skipWaiting()
clientsClaim() clientsClaim()
console.log('[SW] Boris service worker loaded')
// Runtime cache: Cross-origin images // Runtime cache: Cross-origin images
// This preserves the existing image caching behavior // This preserves the existing image caching behavior

View File

@@ -16,18 +16,15 @@ const loadingFonts = new Map<string, Promise<void>>()
export async function loadFont(fontKey: string): Promise<void> { export async function loadFont(fontKey: string): Promise<void> {
if (fontKey === 'system') { if (fontKey === 'system') {
console.log('📝 Using system font')
return Promise.resolve() return Promise.resolve()
} }
if (loadedFonts.has(fontKey)) { if (loadedFonts.has(fontKey)) {
console.log('✅ Font already loaded:', fontKey)
return Promise.resolve() return Promise.resolve()
} }
// If font is currently loading, return the existing promise // If font is currently loading, return the existing promise
if (loadingFonts.has(fontKey)) { if (loadingFonts.has(fontKey)) {
console.log('⏳ Font already loading:', fontKey)
return loadingFonts.get(fontKey)! return loadingFonts.get(fontKey)!
} }
@@ -37,7 +34,6 @@ export async function loadFont(fontKey: string): Promise<void> {
return Promise.resolve() return Promise.resolve()
} }
console.log('🔤 Loading font:', fontFamily)
// Create a promise for this font loading // Create a promise for this font loading
const loadPromise = new Promise<void>((resolve) => { const loadPromise = new Promise<void>((resolve) => {
@@ -48,7 +44,6 @@ export async function loadFont(fontKey: string): Promise<void> {
// Wait for the stylesheet to load // Wait for the stylesheet to load
link.onload = () => { link.onload = () => {
console.log('📄 Stylesheet loaded for:', fontFamily)
// Use Font Loading API to wait for the actual font to be ready // Use Font Loading API to wait for the actual font to be ready
if ('fonts' in document) { if ('fonts' in document) {
@@ -56,7 +51,6 @@ export async function loadFont(fontKey: string): Promise<void> {
document.fonts.load(`400 16px "${fontFamily}"`), document.fonts.load(`400 16px "${fontFamily}"`),
document.fonts.load(`700 16px "${fontFamily}"`) document.fonts.load(`700 16px "${fontFamily}"`)
]).then(() => { ]).then(() => {
console.log('✅ Font ready:', fontFamily)
loadedFonts.add(fontKey) loadedFonts.add(fontKey)
loadingFonts.delete(fontKey) loadingFonts.delete(fontKey)
resolve() resolve()
@@ -69,7 +63,6 @@ export async function loadFont(fontKey: string): Promise<void> {
} else { } else {
// Fallback: just wait a bit for older browsers // Fallback: just wait a bit for older browsers
setTimeout(() => { setTimeout(() => {
console.log('✅ Font assumed ready (no Font Loading API):', fontFamily)
loadedFonts.add(fontKey) loadedFonts.add(fontKey)
loadingFonts.delete(fontKey) loadingFonts.delete(fontKey)
resolve() resolve()

View File

@@ -10,14 +10,12 @@ export function applyHighlightsToHTML(
highlightStyle: 'marker' | 'underline' = 'marker' highlightStyle: 'marker' | 'underline' = 'marker'
): string { ): string {
if (!html || highlights.length === 0) { if (!html || highlights.length === 0) {
console.log('⚠️ applyHighlightsToHTML: No HTML or highlights', {
htmlLength: html?.length, htmlLength: html?.length,
highlightsCount: highlights.length highlightsCount: highlights.length
}) })
return html return html
} }
console.log('🔨 applyHighlightsToHTML: Processing', highlights.length, 'highlights')
const tempDiv = document.createElement('div') const tempDiv = document.createElement('div')
tempDiv.innerHTML = html tempDiv.innerHTML = html
@@ -31,7 +29,6 @@ export function applyHighlightsToHTML(
mark.parentNode?.replaceChild(textNode, mark) mark.parentNode?.replaceChild(textNode, mark)
}) })
console.log('🧹 Removed', existingMarks.length, 'existing highlight marks')
let appliedCount = 0 let appliedCount = 0
@@ -42,7 +39,6 @@ export function applyHighlightsToHTML(
continue continue
} }
console.log('🔍 Searching for highlight:', searchText.substring(0, 50) + '...')
// Collect all text nodes // Collect all text nodes
const walker = document.createTreeWalker(tempDiv, NodeFilter.SHOW_TEXT, null) const walker = document.createTreeWalker(tempDiv, NodeFilter.SHOW_TEXT, null)
@@ -50,7 +46,6 @@ export function applyHighlightsToHTML(
let node: Node | null let node: Node | null
while ((node = walker.nextNode())) textNodes.push(node as Text) while ((node = walker.nextNode())) textNodes.push(node as Text)
console.log('📄 Found', textNodes.length, 'text nodes to search')
// Try exact match first, then normalized match // Try exact match first, then normalized match
const found = tryMarkInTextNodes(textNodes, searchText, highlight, false, highlightStyle) || const found = tryMarkInTextNodes(textNodes, searchText, highlight, false, highlightStyle) ||
@@ -58,13 +53,11 @@ export function applyHighlightsToHTML(
if (found) { if (found) {
appliedCount++ appliedCount++
console.log('✅ Highlight applied successfully')
} else { } else {
console.warn('❌ Could not find match for highlight:', searchText.substring(0, 50)) console.warn('❌ Could not find match for highlight:', searchText.substring(0, 50))
} }
} }
console.log('🎉 Applied', appliedCount, '/', highlights.length, 'highlights')
return tempDiv.innerHTML return tempDiv.innerHTML
} }

View File

@@ -44,7 +44,6 @@ export function applyTheme(
// Listen for system theme changes // Listen for system theme changes
mediaQueryListener = (e: MediaQueryListEvent) => { mediaQueryListener = (e: MediaQueryListEvent) => {
console.log('🎨 System theme changed to:', e.matches ? 'dark' : 'light')
// The CSS media query handles the color changes automatically // The CSS media query handles the color changes automatically
} }
@@ -59,5 +58,4 @@ export function applyTheme(
} }
} }
console.log('🎨 Applied theme:', theme, 'with colors:', { dark: darkColorTheme, light: lightColorTheme })
} }

View File

@@ -11,26 +11,21 @@ export function normalizeUrl(url: string): string {
export function filterHighlightsByUrl(highlights: Highlight[], selectedUrl: string | undefined): Highlight[] { export function filterHighlightsByUrl(highlights: Highlight[], selectedUrl: string | undefined): Highlight[] {
if (!selectedUrl || highlights.length === 0) { if (!selectedUrl || highlights.length === 0) {
console.log('🔍 filterHighlightsByUrl: No URL or highlights', { selectedUrl, count: highlights.length })
return [] return []
} }
console.log('🔍 filterHighlightsByUrl:', { selectedUrl, totalHighlights: highlights.length })
// For Nostr articles, we already fetched highlights specifically for this article // For Nostr articles, we already fetched highlights specifically for this article
// So we don't need to filter them - they're all relevant // So we don't need to filter them - they're all relevant
if (selectedUrl.startsWith('nostr:')) { if (selectedUrl.startsWith('nostr:')) {
console.log('📌 Nostr article - returning all', highlights.length, 'highlights')
return highlights return highlights
} }
// For web URLs, filter by URL matching // For web URLs, filter by URL matching
const normalizedSelected = normalizeUrl(selectedUrl) const normalizedSelected = normalizeUrl(selectedUrl)
console.log('🔗 Normalized selected URL:', normalizedSelected)
const filtered = highlights.filter(h => { const filtered = highlights.filter(h => {
if (!h.urlReference) { if (!h.urlReference) {
console.log('⚠️ Highlight has no urlReference:', h.id, 'eventReference:', h.eventReference)
return false return false
} }
const normalizedRef = normalizeUrl(h.urlReference) const normalizedRef = normalizeUrl(h.urlReference)
@@ -39,14 +34,11 @@ export function filterHighlightsByUrl(highlights: Highlight[], selectedUrl: stri
normalizedRef.includes(normalizedSelected) normalizedRef.includes(normalizedSelected)
if (matches) { if (matches) {
console.log('✅ URL match:', normalizedRef)
} else { } else {
console.log('❌ URL mismatch:', normalizedRef, 'vs', normalizedSelected)
} }
return matches return matches
}) })
console.log('📊 Filtered to', filtered.length, 'highlights')
return filtered return filtered
} }