lint fix wip

This commit is contained in:
Nicolas Cantu 2026-01-06 17:10:07 +01:00
parent cc84d85193
commit 5b7b77aa9a
13 changed files with 99 additions and 34 deletions

View File

@ -5,9 +5,9 @@ interface ArticlePagesProps {
pages: Page[]
}
export function ArticlePages({ pages }: ArticlePagesProps): React.ReactElement {
export function ArticlePages({ pages }: ArticlePagesProps): React.ReactElement | null {
if (!pages || pages.length === 0) {
return <></>
return null
}
return (

View File

@ -232,7 +232,7 @@ function PresentationForm({
</button>
</div>
{hasExistingPresentation && (
<DeleteButton onDelete={handleDelete} deleting={deleting} />
<DeleteButton onDelete={() => { void handleDelete() }} deleting={deleting} />
)}
</div>
</form>
@ -392,7 +392,7 @@ function NoAccountView(): React.ReactElement {
</p>
{error && <p className="text-sm text-red-400">{error}</p>}
<NoAccountActionButtons
onGenerate={handleGenerate}
onGenerate={() => { void handleGenerate() }}
onImport={() => setShowImportModal(true)}
/>
{generating && (
@ -482,7 +482,7 @@ function AuthorPresentationFormView({
loading={state.loading}
handleSubmit={state.handleSubmit}
deleting={state.deleting}
handleDelete={state.handleDelete}
handleDelete={() => { void state.handleDelete() }}
hasExistingPresentation={existingPresentation !== null && existingPresentation !== undefined}
/>
)

View File

@ -165,7 +165,7 @@ export function ConnectButton(): React.ReactElement {
error={error ?? createError}
showUnlockModal={showUnlockModal}
setShowUnlockModal={setShowUnlockModal}
onCreateAccount={handleCreateAccount}
onCreateAccount={() => { void handleCreateAccount() }}
/>
{showRecoveryStep && (
<RecoveryStep

View File

@ -163,10 +163,10 @@ export function CreateAccountModal({ onSuccess, onClose, initialStep = 'choose'
loading,
error,
handleContinue,
handleImport,
() => { void handleImport() },
setStep,
setError,
handleGenerate,
() => { void handleGenerate() },
onClose
)
}

View File

@ -26,7 +26,7 @@ export function RecoveryStep({
<div className="bg-cyber-dark border border-neon-cyan/30 rounded-lg p-6 max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto shadow-glow-cyan">
<h2 className="text-2xl font-bold mb-4 text-neon-cyan">{t('account.create.recovery.title')}</h2>
<RecoveryWarning />
<RecoveryPhraseDisplay recoveryPhrase={recoveryPhrase} copied={copied} onCopy={handleCopy} />
<RecoveryPhraseDisplay recoveryPhrase={recoveryPhrase} copied={copied} onCopy={() => { void handleCopy() }} />
<PublicKeyDisplay npub={npub} />
<div className="flex gap-4">
<button

View File

@ -27,9 +27,9 @@ function ImagePreview({ value }: { value: string }): React.ReactElement {
function UploadButtonLabel({ uploading, value }: { uploading: boolean; value: string | undefined }): React.ReactElement {
if (uploading) {
return <>{t('presentation.field.picture.uploading')}</>
return <span>{t('presentation.field.picture.uploading')}</span>
}
return <>{value ? t('presentation.field.picture.change') : t('presentation.field.picture.upload')}</>
return <span>{value ? t('presentation.field.picture.change') : t('presentation.field.picture.upload')}</span>
}
function RemoveButton({ value, onChange }: { value: string | undefined; onChange: (url: string) => void }): React.ReactElement | null {

View File

@ -252,8 +252,8 @@ export function KeyManagementManager(): React.ReactElement {
</div>
)}
{/* Sync Progress Bar */}
{publicKeys && <SyncProgressBar />}
{/* Sync Progress Bar - Always show if connected, even if publicKeys not loaded yet */}
<SyncProgressBar />
{!publicKeys && !accountExists && (
<div className="bg-yellow-900/20 border border-yellow-400/50 rounded-lg p-4 mb-6">

View File

@ -213,6 +213,7 @@ function UnlockAccountForm({
<div className="mb-4">
<WordInputs words={words} onWordChange={handleWordChange} />
<button
type="button"
onClick={() => {
void handlePaste()
}}

View File

@ -29,25 +29,47 @@ export function useArticles(searchQuery: string = '', filters: ArticleFilters |
const cachedAuthors = await objectCache.getAll('author')
const authors = cachedAuthors as Article[]
// Calculate totalSponsoring for each author
const authorsWithSponsoring = await Promise.all(
authors.map(async (author) => {
if (author.isPresentation && author.pubkey) {
author.totalSponsoring = await getAuthorSponsoring(author.pubkey)
}
return author
})
)
if (authorsWithSponsoring.length > 0) {
// Display authors immediately (with existing totalSponsoring if available)
if (authors.length > 0) {
setArticles((prev) => {
// Merge with existing articles, avoiding duplicates
const existingIds = new Set(prev.map((a) => a.id))
const newAuthors = authorsWithSponsoring.filter((a) => !existingIds.has(a.id))
const newAuthors = authors.filter((a) => !existingIds.has(a.id))
const merged = [...prev, ...newAuthors].sort((a, b) => b.createdAt - a.createdAt)
hasArticlesRef.current = merged.length > 0
return merged
})
setLoading(false)
}
// Calculate totalSponsoring asynchronously from cache (non-blocking)
// Only update authors that don't have totalSponsoring yet
const authorsNeedingSponsoring = authors.filter(
(author) => author.isPresentation && author.pubkey && author.totalSponsoring === undefined
)
if (authorsNeedingSponsoring.length > 0) {
// Load sponsoring from cache in parallel (fast, no network)
const sponsoringPromises = authorsNeedingSponsoring.map(async (author) => {
if (author.pubkey) {
const totalSponsoring = await getAuthorSponsoring(author.pubkey, true)
return { authorId: author.id, totalSponsoring }
}
return null
})
const sponsoringResults = await Promise.all(sponsoringPromises)
// Update articles with sponsoring amounts
setArticles((prev) =>
prev.map((article) => {
const sponsoringResult = sponsoringResults.find((r) => r?.authorId === article.id)
if (sponsoringResult && article.isPresentation) {
return { ...article, totalSponsoring: sponsoringResult.totalSponsoring }
}
return article
})
)
}
} catch (error) {
console.error('Error loading authors from cache:', error)

View File

@ -47,7 +47,7 @@ export class AlbyService {
try {
await webln.enable()
} catch (_error) {
} catch {
throw new Error('User rejected WebLN permission request')
}
}
@ -175,7 +175,7 @@ export class AlbyService {
}
setTimeout(checkPayment, interval)
} catch (_error) {
} catch {
resolve({ paid: false, paymentHash })
}
}

View File

@ -88,7 +88,7 @@ async function tryUploadEndpoint(endpoint: string, formData: FormData, useProxy:
try {
const text = await response.text()
errorMessage = text || `HTTP ${response.status} ${response.statusText}`
} catch (_e) {
} catch {
errorMessage = `HTTP ${response.status} ${response.statusText}`
}
throw new Error(errorMessage)

View File

@ -37,7 +37,7 @@ class NostrService {
if (decoded.type === 'nsec' && typeof decoded.data === 'string') {
this.privateKey = decoded.data
}
} catch (_e) {
} catch {
// Assume it's already a hex string
}
}
@ -57,7 +57,7 @@ class NostrService {
if (decoded.type === 'npub' && typeof decoded.data === 'string') {
this.publicKey = decoded.data
}
} catch (_e) {
} catch {
// Assume it's already a hex string
}
}

View File

@ -1,17 +1,59 @@
import { getSponsoringByAuthor } from './sponsoringQueries'
import { objectCache } from './objectCache'
import type { Article } from '@/types/nostr'
import type { Sponsoring } from '@/types/nostr'
/**
* Get total sponsoring for an author by their pubkey from IndexedDB cache
* This is much faster than network queries
* Returns both the amount and whether the cache was empty (to avoid duplicate calls)
*/
async function getAuthorSponsoringFromCache(pubkey: string): Promise<{ amount: number; cacheWasEmpty: boolean }> {
try {
const allSponsoring = await objectCache.getAll('sponsoring')
const sponsoringList = allSponsoring as Sponsoring[]
// If cache is empty, return immediately
if (sponsoringList.length === 0) {
return { amount: 0, cacheWasEmpty: true }
}
// Filter by author pubkey and sum amounts
const amount = sponsoringList
.filter((sponsoring) => sponsoring.authorPubkey === pubkey)
.reduce((total, sponsoring) => total + sponsoring.amount, 0)
return { amount, cacheWasEmpty: false }
} catch (error) {
console.error('Error calculating author sponsoring from cache:', error)
return { amount: 0, cacheWasEmpty: true }
}
}
/**
* Get total sponsoring for an author by their pubkey
* Calculates from cache (sponsoring queries) instead of tags
* First tries cache, then falls back to network query if needed
* If cache is empty, returns 0 immediately (very fast, no network request)
*/
export async function getAuthorSponsoring(pubkey: string): Promise<number> {
export async function getAuthorSponsoring(pubkey: string, useCacheOnly: boolean = true): Promise<number> {
try {
// Try cache first (much faster)
const { amount: cachedAmount, cacheWasEmpty } = await getAuthorSponsoringFromCache(pubkey)
// If cache is empty, return 0 immediately (no network request)
if (cacheWasEmpty) {
return 0
}
if (cachedAmount > 0 || useCacheOnly) {
return cachedAmount
}
// Fallback to network query if cache exists but cacheOnly is false
const sponsoringList = await getSponsoringByAuthor(pubkey, 5000)
// Sum all sponsoring amounts for this author
return sponsoringList.reduce((total, sponsoring) => total + sponsoring.amount, 0)
} catch (error) {
console.error('Error calculating author sponsoring from cache:', error)
console.error('Error calculating author sponsoring:', error)
return 0
}
}