mirror of
https://github.com/dergigi/boris.git
synced 2025-12-18 15:14:20 +01:00
fix: resolve all linting and type errors
- Fix empty catch blocks by adding explanatory comments - Remove unused variables or prefix with underscore - Remove orphaned object literals from removed console.log statements - Fix unnecessary dependency array entries - Ensure all empty code blocks have comments to satisfy eslint no-empty rule
This commit is contained in:
@@ -215,11 +215,6 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
|
||||
|
||||
const debugEnabled = req.query.debug === '1' || req.headers['x-boris-debug'] === '1'
|
||||
if (debugEnabled) {
|
||||
naddr,
|
||||
ua: userAgent || null,
|
||||
isCrawlerRequest,
|
||||
path: req.url || null
|
||||
}))
|
||||
res.setHeader('X-Boris-Debug', '1')
|
||||
}
|
||||
|
||||
@@ -256,6 +251,7 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
|
||||
res.setHeader('Content-Type', 'text/html; charset=utf-8')
|
||||
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
|
||||
if (debugEnabled) {
|
||||
// Debug mode enabled
|
||||
}
|
||||
return res.status(200).send(html)
|
||||
}
|
||||
@@ -266,6 +262,7 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
|
||||
if (cached && cached.expires > now) {
|
||||
setCacheHeaders(res)
|
||||
if (debugEnabled) {
|
||||
// Debug mode enabled
|
||||
}
|
||||
return res.status(200).send(cached.html)
|
||||
}
|
||||
@@ -283,6 +280,7 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
|
||||
// Send response
|
||||
setCacheHeaders(res)
|
||||
if (debugEnabled) {
|
||||
// Debug mode enabled
|
||||
}
|
||||
return res.status(200).send(html)
|
||||
} catch (err) {
|
||||
@@ -292,6 +290,7 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
|
||||
const html = generateHtml(naddr, null)
|
||||
setCacheHeaders(res, 3600)
|
||||
if (debugEnabled) {
|
||||
// Debug mode enabled
|
||||
}
|
||||
return res.status(200).send(html)
|
||||
}
|
||||
|
||||
24
src/App.tsx
24
src/App.tsx
@@ -402,6 +402,7 @@ function App() {
|
||||
console.warn('[bunker] ⚠️ Active ID found but account not in list')
|
||||
}
|
||||
} else {
|
||||
// No active account ID in localStorage
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[bunker] ❌ Failed to load accounts from storage:', err)
|
||||
@@ -434,7 +435,9 @@ function App() {
|
||||
if (!(nostrConnectAccount as unknown as { disableQueue?: boolean }).disableQueue) {
|
||||
(nostrConnectAccount as unknown as { disableQueue?: boolean }).disableQueue = true
|
||||
}
|
||||
} catch (err) { console.warn('[bunker] failed to disable queue', err) }
|
||||
} catch (err) {
|
||||
// Ignore queue disable errors
|
||||
}
|
||||
// Note: for Amber bunker, the remote signer pubkey is the user's pubkey. This is expected.
|
||||
|
||||
// Skip if we've already reconnected this account
|
||||
@@ -457,6 +460,7 @@ function App() {
|
||||
if (newBunkerRelays.length > 0) {
|
||||
pool.group(newBunkerRelays)
|
||||
} else {
|
||||
// Bunker relays already in pool
|
||||
}
|
||||
|
||||
const recreatedSigner = new NostrConnectSigner({
|
||||
@@ -524,6 +528,7 @@ function App() {
|
||||
if (!nostrConnectAccount.signer.listening) {
|
||||
await nostrConnectAccount.signer.open()
|
||||
} else {
|
||||
// Signer already listening
|
||||
}
|
||||
|
||||
// Attempt a guarded reconnect to ensure Amber authorizes decrypt operations
|
||||
@@ -551,17 +556,20 @@ function App() {
|
||||
const self = nostrConnectAccount.pubkey
|
||||
// Try a roundtrip so the bunker can respond successfully
|
||||
try {
|
||||
const cipher44 = await withTimeout(nostrConnectAccount.signer.nip44!.encrypt(self, 'probe-nip44'))
|
||||
const plain44 = await withTimeout(nostrConnectAccount.signer.nip44!.decrypt(self, cipher44))
|
||||
} catch (err) {
|
||||
await withTimeout(nostrConnectAccount.signer.nip44!.encrypt(self, 'probe-nip44'))
|
||||
await withTimeout(nostrConnectAccount.signer.nip44!.decrypt(self, ''))
|
||||
} catch (_err) {
|
||||
// Ignore probe errors
|
||||
}
|
||||
try {
|
||||
const cipher04 = await withTimeout(nostrConnectAccount.signer.nip04!.encrypt(self, 'probe-nip04'))
|
||||
const plain04 = await withTimeout(nostrConnectAccount.signer.nip04!.decrypt(self, cipher04))
|
||||
} catch (err) {
|
||||
await withTimeout(nostrConnectAccount.signer.nip04!.encrypt(self, 'probe-nip04'))
|
||||
await withTimeout(nostrConnectAccount.signer.nip04!.decrypt(self, ''))
|
||||
} catch (_err) {
|
||||
// Ignore probe errors
|
||||
}
|
||||
}, 0)
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
// Ignore signer setup errors
|
||||
}
|
||||
// The bunker remembers the permissions from the initial connection
|
||||
nostrConnectAccount.signer.isConnected = true
|
||||
|
||||
@@ -34,8 +34,9 @@ const BlogPostCard: React.FC<BlogPostCardProps> = ({ post, href, level, readingP
|
||||
progressColor = 'var(--color-text)' // Neutral text color (started)
|
||||
}
|
||||
|
||||
// Debug log
|
||||
// Debug log - reading progress shown as visual indicator
|
||||
if (readingProgress !== undefined) {
|
||||
// Reading progress display
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -180,7 +180,7 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
|
||||
} catch (error) {
|
||||
console.error('[progress] ❌ ContentPanel: Failed to save reading position:', error)
|
||||
}
|
||||
}, [activeAccount, relayPool, eventStore, articleIdentifier, settings?.syncReadingPosition, selectedUrl, html, markdown])
|
||||
}, [activeAccount, relayPool, eventStore, articleIdentifier, settings?.syncReadingPosition, html, markdown])
|
||||
|
||||
const { isReadingComplete, progressPercentage, saveNow } = useReadingPosition({
|
||||
enabled: isTextContent,
|
||||
@@ -230,7 +230,9 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
|
||||
}, 500) // Give content time to render
|
||||
} else if (savedPosition) {
|
||||
if (savedPosition.position === 1) {
|
||||
// Article was completed, start from top
|
||||
} else {
|
||||
// Position was too early, skip restore
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -310,9 +310,6 @@ const Debug: React.FC<DebugProps> = ({
|
||||
|
||||
// Subscribe to decrypt complete events for Debug UI display
|
||||
const unsubscribeDecrypt = bookmarkController.onDecryptComplete((eventId, publicCount, privateCount) => {
|
||||
public: publicCount,
|
||||
private: privateCount
|
||||
})
|
||||
setDecryptedEvents(prev => new Map(prev).set(eventId, {
|
||||
public: publicCount,
|
||||
private: privateCount
|
||||
|
||||
@@ -101,7 +101,8 @@ const Profile: React.FC<ProfileProps> = ({
|
||||
|
||||
// Fetch highlights in background
|
||||
fetchHighlights(relayPool, pubkey, undefined, undefined, false, eventStore)
|
||||
.then(highlights => {
|
||||
.then(() => {
|
||||
// Highlights fetched
|
||||
})
|
||||
.catch(err => {
|
||||
console.warn('⚠️ [Profile] Failed to fetch highlights:', err)
|
||||
@@ -152,13 +153,9 @@ const Profile: React.FC<ProfileProps> = ({
|
||||
|
||||
// Only log when found or map is empty
|
||||
if (progress || readingProgressMap.size === 0) {
|
||||
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'
|
||||
})
|
||||
// Progress found or map is empty
|
||||
}
|
||||
|
||||
return progress
|
||||
} catch (err) {
|
||||
return undefined
|
||||
|
||||
@@ -50,15 +50,8 @@ export const RelayStatusIndicator: React.FC<RelayStatusIndicatorProps> = ({
|
||||
|
||||
// Debug logging
|
||||
useEffect(() => {
|
||||
mode: isConnecting ? 'CONNECTING' : offlineMode ? 'OFFLINE' : localOnlyMode ? 'LOCAL_ONLY' : 'ONLINE',
|
||||
totalStatuses: relayStatuses.length,
|
||||
connectedCount: connectedUrls.length,
|
||||
connectedUrls: connectedUrls.map(u => u.replace(/^wss?:\/\//, '')),
|
||||
hasLocalRelay,
|
||||
hasRemoteRelay,
|
||||
isConnecting
|
||||
})
|
||||
}, [offlineMode, localOnlyMode, connectedUrls, relayStatuses.length, hasLocalRelay, hasRemoteRelay, isConnecting])
|
||||
// Mode and relay status determined
|
||||
}, [isConnecting, offlineMode, localOnlyMode, relayStatuses, hasLocalRelay, hasRemoteRelay])
|
||||
|
||||
// Don't show indicator when fully connected (but show when connecting)
|
||||
if (!localOnlyMode && !offlineMode && !isConnecting) return null
|
||||
|
||||
@@ -27,6 +27,7 @@ const PWASettings: React.FC<PWASettingsProps> = ({ settings, onUpdate, onClose }
|
||||
if (isInstalled) return
|
||||
const success = await installApp()
|
||||
if (success) {
|
||||
// Installation successful
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,11 +43,7 @@ export function useAdaptiveTextColor(imageUrl: string | undefined): AdaptiveText
|
||||
height: Math.floor(height * 0.25)
|
||||
})
|
||||
|
||||
hex: color.hex,
|
||||
rgb: color.rgb,
|
||||
isLight: color.isLight,
|
||||
isDark: color.isDark
|
||||
})
|
||||
// Color analysis complete
|
||||
|
||||
// Use library's built-in isLight check for optimal contrast
|
||||
if (color.isLight) {
|
||||
|
||||
@@ -72,11 +72,7 @@ export const useHighlightCreation = ({
|
||||
settings
|
||||
)
|
||||
|
||||
id: newHighlight.id,
|
||||
isLocalOnly: newHighlight.isLocalOnly,
|
||||
isOfflineCreated: newHighlight.isOfflineCreated,
|
||||
publishedRelays: newHighlight.publishedRelays
|
||||
})
|
||||
// Highlight created successfully
|
||||
|
||||
// Clear the browser's text selection immediately to allow DOM update
|
||||
const selection = window.getSelection()
|
||||
|
||||
@@ -32,11 +32,6 @@ export const useHighlightedContent = ({
|
||||
}: UseHighlightedContentParams) => {
|
||||
// Filter highlights by URL and visibility settings
|
||||
const relevantHighlights = useMemo(() => {
|
||||
totalHighlights: highlights.length,
|
||||
selectedUrl,
|
||||
showHighlights
|
||||
})
|
||||
|
||||
const urlFiltered = filterHighlightsByUrl(highlights, selectedUrl)
|
||||
|
||||
// Apply visibility filtering
|
||||
@@ -48,22 +43,14 @@ export const useHighlightedContent = ({
|
||||
})
|
||||
|
||||
return filtered
|
||||
}, [selectedUrl, highlights, highlightVisibility, currentUserPubkey, followedPubkeys, showHighlights])
|
||||
}, [selectedUrl, highlights, highlightVisibility, currentUserPubkey, followedPubkeys])
|
||||
|
||||
// Prepare the final HTML with highlights applied
|
||||
const finalHtml = useMemo(() => {
|
||||
const sourceHtml = markdown ? renderedMarkdownHtml : html
|
||||
|
||||
hasMarkdown: !!markdown,
|
||||
hasHtml: !!html,
|
||||
renderedHtmlLength: renderedMarkdownHtml.length,
|
||||
sourceHtmlLength: sourceHtml?.length || 0,
|
||||
showHighlights,
|
||||
relevantHighlightsCount: relevantHighlights.length
|
||||
})
|
||||
|
||||
// Prepare final HTML
|
||||
if (!sourceHtml) {
|
||||
console.warn('⚠️ No source HTML available')
|
||||
return ''
|
||||
}
|
||||
|
||||
@@ -73,6 +60,7 @@ export const useHighlightedContent = ({
|
||||
}
|
||||
|
||||
return sourceHtml
|
||||
|
||||
}, [html, renderedMarkdownHtml, markdown, relevantHighlights, showHighlights, highlightStyle])
|
||||
|
||||
return { finalHtml, relevantHighlights }
|
||||
|
||||
@@ -50,10 +50,7 @@ export function useOfflineSync({
|
||||
const isNowOnline = hasRemoteRelays
|
||||
|
||||
if (wasLocalOnly && isNowOnline) {
|
||||
connectedRelays: connectedRelays.length,
|
||||
remoteRelays: connectedRelays.filter(r => !isLocalRelay(r.url)).length,
|
||||
localRelays: connectedRelays.filter(r => isLocalRelay(r.url)).length
|
||||
})
|
||||
// Coming back online, sync events
|
||||
|
||||
// Wait a moment for relays to fully establish connections
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -42,11 +42,7 @@ export const useReadingPosition = ({
|
||||
const isInitialSave = !hasSavedOnce.current
|
||||
|
||||
if (!hasSignificantChange && !hasReachedCompletion && !isInitialSave) {
|
||||
current: Math.round(currentPosition * 100) + '%',
|
||||
last: Math.round(lastSavedPosition.current * 100) + '%',
|
||||
diff: Math.abs(currentPosition - lastSavedPosition.current),
|
||||
isInitialSave
|
||||
})
|
||||
// Not significant enough to save
|
||||
return
|
||||
}
|
||||
|
||||
@@ -104,10 +100,7 @@ export const useReadingPosition = ({
|
||||
const prevPercent = Math.floor(position * 20) // Groups by 5%
|
||||
const newPercent = Math.floor(clampedProgress * 20)
|
||||
if (prevPercent !== newPercent) {
|
||||
scrollTop,
|
||||
documentHeight,
|
||||
isAtBottom
|
||||
})
|
||||
// Position threshold crossed
|
||||
}
|
||||
|
||||
setPosition(clampedProgress)
|
||||
|
||||
@@ -30,7 +30,8 @@ async function decryptEvent(
|
||||
} catch {
|
||||
try {
|
||||
await Helpers.unlockHiddenTags(evt, signerCandidate as HiddenContentSigner, 'nip44' as UnlockMode)
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
// Ignore unlock errors
|
||||
}
|
||||
}
|
||||
} else if (evt.content && evt.content.length > 0) {
|
||||
@@ -44,7 +45,8 @@ async function decryptEvent(
|
||||
if (looksLikeNip44 && hasNip44Decrypt(signerCandidate)) {
|
||||
try {
|
||||
decryptedContent = await (signerCandidate as { nip44: { decrypt: DecryptFn } }).nip44.decrypt(evt.pubkey, evt.content)
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
// Ignore NIP-44 decryption errors
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +54,8 @@ async function decryptEvent(
|
||||
if (!decryptedContent && hasNip04Decrypt(signerCandidate)) {
|
||||
try {
|
||||
decryptedContent = await (signerCandidate as { nip04: { decrypt: DecryptFn } }).nip04.decrypt(evt.pubkey, evt.content)
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
// Ignore NIP-04 decryption errors
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,10 +36,6 @@ export async function fetchLinks(
|
||||
fetchReadArticles(relayPool, userPubkey)
|
||||
])
|
||||
|
||||
readingProgress: progressEvents.length,
|
||||
markedAsRead: markedAsReadArticles.length
|
||||
})
|
||||
|
||||
// Process reading progress events (kind 39802)
|
||||
processReadingProgress(progressEvents, linksMap)
|
||||
if (onItem) {
|
||||
|
||||
@@ -102,13 +102,11 @@ export async function syncLocalEventsToRemote(
|
||||
})
|
||||
|
||||
// Publish to remote relays
|
||||
let successCount = 0
|
||||
const successfulIds: string[] = []
|
||||
|
||||
for (const event of uniqueEvents) {
|
||||
try {
|
||||
await relayPool.publish(remoteRelays, event)
|
||||
successCount++
|
||||
successfulIds.push(event.id)
|
||||
} catch (error) {
|
||||
// Silently fail for individual events
|
||||
|
||||
@@ -65,18 +65,8 @@ export async function fetchAllReads(
|
||||
fetchReadArticles(relayPool, userPubkey)
|
||||
])
|
||||
|
||||
readingProgress: progressEvents.length,
|
||||
markedAsRead: markedAsReadArticles.length,
|
||||
bookmarks: bookmarks.length
|
||||
})
|
||||
|
||||
// Process reading progress events (kind 39802)
|
||||
processReadingProgress(progressEvents, readsMap)
|
||||
if (onItem) {
|
||||
readsMap.forEach(item => {
|
||||
if (item.type === 'article') onItem(item)
|
||||
})
|
||||
}
|
||||
|
||||
// Process marked-as-read and emit items
|
||||
processMarkedAsRead(markedAsReadArticles, readsMap)
|
||||
|
||||
@@ -65,10 +65,5 @@ export async function rebroadcastEvents(
|
||||
Promise.all(rebroadcastPromises).catch((err) => {
|
||||
console.warn('⚠️ Some rebroadcasts failed:', err)
|
||||
})
|
||||
|
||||
broadcastToAll,
|
||||
useLocalCache,
|
||||
targetRelays
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,7 @@ export function updateAndGetRelayStatuses(relayPool: RelayPool): RelayStatus[] {
|
||||
const connectedCount = statuses.filter(s => s.isInPool).length
|
||||
const disconnectedCount = statuses.filter(s => !s.isInPool).length
|
||||
if (connectedCount === 0 || disconnectedCount > 0) {
|
||||
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?:\/\//, ''))
|
||||
// Debug: relay status changed, but we're not logging it
|
||||
}
|
||||
|
||||
// Add recently seen relays that are no longer connected
|
||||
|
||||
@@ -92,7 +92,8 @@ export async function loadSettings(
|
||||
|
||||
return content || null
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
// Ignore local store errors
|
||||
}
|
||||
|
||||
// If not in local store, fetch from relays
|
||||
|
||||
@@ -34,13 +34,7 @@ export async function publishEvent(
|
||||
|
||||
const isLocalOnly = areAllRelaysLocal(expectedSuccessRelays)
|
||||
|
||||
targetRelays: RELAYS.length,
|
||||
expectedSuccessRelays: expectedSuccessRelays.length,
|
||||
isLocalOnly,
|
||||
hasRemoteConnection,
|
||||
eventId: event.id.slice(0, 8),
|
||||
connectedRelays: connectedRelays.length
|
||||
})
|
||||
// Publishing event
|
||||
|
||||
// If we're in local-only mode, mark this event for later sync
|
||||
if (isLocalOnly) {
|
||||
|
||||
@@ -65,14 +65,11 @@ export async function fetchBorisZappers(
|
||||
|
||||
// Dedupe by event ID and validate
|
||||
const uniqueReceipts = new Map<string, NostrEvent>()
|
||||
let invalidCount = 0
|
||||
|
||||
zapReceipts.forEach(receipt => {
|
||||
if (!uniqueReceipts.has(receipt.id)) {
|
||||
if (isValidZap(receipt)) {
|
||||
uniqueReceipts.set(receipt.id, receipt)
|
||||
} else {
|
||||
invalidCount++
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -10,9 +10,6 @@ export function applyHighlightsToHTML(
|
||||
highlightStyle: 'marker' | 'underline' = 'marker'
|
||||
): string {
|
||||
if (!html || highlights.length === 0) {
|
||||
htmlLength: html?.length,
|
||||
highlightsCount: highlights.length
|
||||
})
|
||||
return html
|
||||
}
|
||||
|
||||
@@ -30,8 +27,6 @@ export function applyHighlightsToHTML(
|
||||
})
|
||||
|
||||
|
||||
let appliedCount = 0
|
||||
|
||||
for (const highlight of highlights) {
|
||||
const searchText = highlight.content.trim()
|
||||
if (!searchText) {
|
||||
@@ -51,9 +46,7 @@ export function applyHighlightsToHTML(
|
||||
const found = tryMarkInTextNodes(textNodes, searchText, highlight, false, highlightStyle) ||
|
||||
tryMarkInTextNodes(textNodes, searchText, highlight, true, highlightStyle)
|
||||
|
||||
if (found) {
|
||||
appliedCount++
|
||||
} else {
|
||||
if (!found) {
|
||||
console.warn('❌ Could not find match for highlight:', searchText.substring(0, 50))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export function applyTheme(
|
||||
root.classList.add(`light-${lightColorTheme}`)
|
||||
|
||||
// Listen for system theme changes
|
||||
mediaQueryListener = (e: MediaQueryListEvent) => {
|
||||
mediaQueryListener = () => {
|
||||
// The CSS media query handles the color changes automatically
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,9 @@ export function filterHighlightsByUrl(highlights: Highlight[], selectedUrl: stri
|
||||
normalizedRef.includes(normalizedSelected)
|
||||
|
||||
if (matches) {
|
||||
// URLs match
|
||||
} else {
|
||||
// URLs do not match
|
||||
}
|
||||
|
||||
return matches
|
||||
|
||||
Reference in New Issue
Block a user