Browse Source

change spinners to skeletons

imwald
Silberengel 1 month ago
parent
commit
430237f53c
  1. 2
      src/components/AccountList/index.tsx
  2. 1
      src/components/FollowButton/index.tsx
  3. 2
      src/components/MailboxSetting/DiscoveredRelays.tsx
  4. 2
      src/components/MailboxSetting/SaveButton.tsx
  5. 2
      src/components/MuteButton/index.tsx
  6. 19
      src/components/Note/PublicationIndex/PublicationIndex.tsx
  7. 1
      src/components/NoteStats/Likes.tsx
  8. 10
      src/components/Profile/ProfileMediaFeed.tsx
  9. 8
      src/components/RefreshButton/index.tsx
  10. 24
      src/pages/primary/SpellsPage/fauxSpellFeeds.ts
  11. 2
      src/pages/secondary/MuteListPage/index.tsx
  12. 2
      src/pages/secondary/RssFeedSettingsPage/index.tsx
  13. 1
      src/pages/secondary/WalletPage/LightningAddressInput.tsx
  14. 2
      src/services/client.service.ts

2
src/components/AccountList/index.tsx

@ -6,7 +6,7 @@ import { formatPubkey } from '@/lib/pubkey' @@ -6,7 +6,7 @@ import { formatPubkey } from '@/lib/pubkey'
import { cn } from '@/lib/utils'
import { useNostr } from '@/providers/NostrProvider'
import { TAccountPointer, TSignerType } from '@/types'
import { Loader, Trash2 } from 'lucide-react'
import { Trash2 } from 'lucide-react'
import { useState } from 'react'
import { SimpleUserAvatar } from '../UserAvatar'
import { SimpleUsername } from '../Username'

1
src/components/FollowButton/index.tsx

@ -14,7 +14,6 @@ import { Skeleton } from '@/components/ui/skeleton' @@ -14,7 +14,6 @@ import { Skeleton } from '@/components/ui/skeleton'
import { useFollowList } from '@/providers/FollowListProvider'
import { useMuteList } from '@/providers/MuteListProvider'
import { useNostr } from '@/providers/NostrProvider'
import { Loader } from 'lucide-react'
import { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'

2
src/components/MailboxSetting/DiscoveredRelays.tsx

@ -5,7 +5,7 @@ import { normalizeUrl, isLocalNetworkUrl } from '@/lib/url' @@ -5,7 +5,7 @@ import { normalizeUrl, isLocalNetworkUrl } from '@/lib/url'
import { getRelaysFromNip07Extension, verifyNip05 } from '@/lib/nip05'
import { useNostr } from '@/providers/NostrProvider'
import { TMailboxRelay } from '@/types'
import { Loader2, Check, AlertCircle } from 'lucide-react'
import { Check, AlertCircle } from 'lucide-react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import RelayIcon from '../RelayIcon'

2
src/components/MailboxSetting/SaveButton.tsx

@ -4,7 +4,7 @@ import { createRelayListDraftEvent } from '@/lib/draft-event' @@ -4,7 +4,7 @@ import { createRelayListDraftEvent } from '@/lib/draft-event'
import { showPublishingFeedback, showSimplePublishSuccess, showPublishingError } from '@/lib/publishing-feedback'
import { useNostr } from '@/providers/NostrProvider'
import { TMailboxRelay } from '@/types'
import { CloudUpload, Loader } from 'lucide-react'
import { CloudUpload } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import logger from '@/lib/logger'

2
src/components/MuteButton/index.tsx

@ -10,7 +10,7 @@ import { @@ -10,7 +10,7 @@ import {
import { useMuteList } from '@/providers/MuteListProvider'
import { useNostr } from '@/providers/NostrProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { BellOff, Loader } from 'lucide-react'
import { BellOff } from 'lucide-react'
import { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'

19
src/components/Note/PublicationIndex/PublicationIndex.tsx

@ -10,6 +10,7 @@ import client from '@/services/client.service' @@ -10,6 +10,7 @@ import client from '@/services/client.service'
import { eventService, queryService, replaceableEventService } from '@/services/client.service'
import logger from '@/lib/logger'
import { Button } from '@/components/ui/button'
import { Skeleton } from '@/components/ui/skeleton'
import { RefreshCw, ArrowUp } from 'lucide-react'
import indexedDb from '@/services/indexed-db.service'
import { isReplaceableEvent } from '@/lib/event'
@ -1442,7 +1443,11 @@ export default function PublicationIndex({ @@ -1442,7 +1443,11 @@ export default function PublicationIndex({
onClick={handleManualRetry}
disabled={isRetrying}
>
<RefreshCw className={cn("h-4 w-4 mr-2", isRetrying && "animate-spin")} />
{isRetrying ? (
<Skeleton className="mr-2 inline-block size-4 shrink-0 rounded-sm align-middle" aria-hidden />
) : (
<RefreshCw className="h-4 w-4 mr-2" />
)}
Retry All
</Button>
</div>
@ -1466,7 +1471,11 @@ export default function PublicationIndex({ @@ -1466,7 +1471,11 @@ export default function PublicationIndex({
onClick={handleManualRetry}
disabled={isRetrying}
>
<RefreshCw className={cn("h-4 w-4 mr-2", isRetrying && "animate-spin")} />
{isRetrying ? (
<Skeleton className="mr-2 inline-block size-4 shrink-0 rounded-sm align-middle" aria-hidden />
) : (
<RefreshCw className="h-4 w-4 mr-2" />
)}
Retry Loading
</Button>
</div>
@ -1527,7 +1536,11 @@ export default function PublicationIndex({ @@ -1527,7 +1536,11 @@ export default function PublicationIndex({
disabled={isRetrying}
className="shrink-0"
>
<RefreshCw className={cn("h-4 w-4", isRetrying && "animate-spin")} />
{isRetrying ? (
<Skeleton className="size-4 shrink-0 rounded-sm" aria-hidden />
) : (
<RefreshCw className="h-4 w-4" />
)}
Retry
</Button>
</div>

1
src/components/NoteStats/Likes.tsx

@ -10,7 +10,6 @@ import { useNostr } from '@/providers/NostrProvider' @@ -10,7 +10,6 @@ import { useNostr } from '@/providers/NostrProvider'
import { useUserTrust } from '@/providers/UserTrustProvider'
import noteStatsService from '@/services/note-stats.service'
import { TEmoji } from '@/types'
import { Loader } from 'lucide-react'
import { Event } from 'nostr-tools'
import { useMemo, useRef, useState } from 'react'
import Emoji from '../Emoji'

10
src/components/Profile/ProfileMediaFeed.tsx

@ -2,9 +2,7 @@ import NoteList, { type TNoteListRef } from '@/components/NoteList' @@ -2,9 +2,7 @@ import NoteList, { type TNoteListRef } from '@/components/NoteList'
import { buildProfilePageReadRelayUrls } from '@/lib/favorites-feed-relays'
import { computeSpellSubRequestsIdentityKey } from '@/lib/spell-feed-request-identity'
import {
applyFauxSpellCapsToSubRequests,
appendCuratedReadOnlyRelays,
buildProfileMediaSpellFilter,
buildProfileMediaSubRequests,
MEDIA_SPELL_KINDS,
PROFILE_MEDIA_REQ_LIMIT
} from '@/pages/primary/SpellsPage/fauxSpellFeeds'
@ -58,11 +56,7 @@ const ProfileMediaFeed = forwardRef<TNoteListRef, { pubkey: string }>(({ pubkey @@ -58,11 +56,7 @@ const ProfileMediaFeed = forwardRef<TNoteListRef, { pubkey: string }>(({ pubkey
const subRequests = useMemo(() => {
const pk = pubkey?.trim()
if (!pk || profileRelayUrls === null) return []
const urls = appendCuratedReadOnlyRelays(profileRelayUrls, blockedRelays)
if (!urls.length) return []
return applyFauxSpellCapsToSubRequests([
{ urls, filter: buildProfileMediaSpellFilter(pk) }
])
return buildProfileMediaSubRequests(profileRelayUrls, blockedRelays, pk)
}, [pubkey, profileRelayUrls, blockedRelays])
const feedSubscriptionKey = useMemo(

8
src/components/RefreshButton/index.tsx

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils'
import { Skeleton } from '@/components/ui/skeleton'
import { RefreshCcw } from 'lucide-react'
import { useState } from 'react'
@ -18,7 +18,11 @@ export function RefreshButton({ onClick }: { onClick: () => void }) { @@ -18,7 +18,11 @@ export function RefreshButton({ onClick }: { onClick: () => void }) {
}}
className="text-muted-foreground focus:text-foreground [&_svg]:size-3 h-8 px-2 text-xs"
>
<RefreshCcw className={cn(refreshing ? 'animate-spin' : '')} />
{refreshing ? (
<Skeleton className="size-3 shrink-0 rounded-sm" aria-hidden />
) : (
<RefreshCcw />
)}
</Button>
)
}

24
src/pages/primary/SpellsPage/fauxSpellFeeds.ts

@ -8,7 +8,8 @@ @@ -8,7 +8,8 @@
* topics go in a single `#t` filter (NIP-01 OR semantics). The notifications spell uses a narrow
* kind list vs full profile kinds.
*/
import { ExtendedKind, PROFILE_FEED_KINDS, READ_ONLY_RELAY_URLS } from '@/constants'
import { ExtendedKind, FAST_READ_RELAY_URLS, PROFILE_FEED_KINDS, READ_ONLY_RELAY_URLS } from '@/constants'
import { mergeRelayUrlLayers } from '@/lib/favorites-feed-relays'
import { normalizeTopic } from '@/lib/discussion-topics'
import { normalizeUrl } from '@/lib/url'
import type { TFeedSubRequest } from '@/types'
@ -21,6 +22,13 @@ export const FAUX_SPELL_EVENT_LIMIT = 200 @@ -21,6 +22,13 @@ export const FAUX_SPELL_EVENT_LIMIT = 200
/** Profile Media tab: single REQ `limit` (matches merged cap in NoteList one-shot). */
export const PROFILE_MEDIA_REQ_LIMIT = 200
/**
* More sockets than {@link FAUX_SPELL_MAX_RELAYS}: profile media must query read aggregators plus the
* author stack. {@link appendCuratedReadOnlyRelays} + {@link applyFauxSpellCapsToSubRequests} used to put
* aggr *after* six NIP-65 relays, then slice to six so aggr was never hit and media was often missing.
*/
export const PROFILE_MEDIA_MAX_RELAYS = 16
/**
* Trim relay lists and filter limits (and bookmark `ids`) so faux feeds stay cheap to open.
*/
@ -123,6 +131,20 @@ export function buildProfileMediaSpellFilter(pubkey: string): Filter { @@ -123,6 +131,20 @@ export function buildProfileMediaSpellFilter(pubkey: string): Filter {
}
}
/** Read-only + {@link FAST_READ_RELAY_URLS} before the author’s six-relay stack so major mirrors are always queried. */
export function buildProfileMediaSubRequests(
profileRelayUrls: string[],
blockedRelays: string[],
pubkey: string
): TFeedSubRequest[] {
const readOnlyLayer = READ_ONLY_RELAY_URLS.map((u) => normalizeUrl(u) || u).filter(Boolean)
const fastReadLayer = FAST_READ_RELAY_URLS.map((u) => normalizeUrl(u) || u).filter(Boolean)
const merged = mergeRelayUrlLayers([readOnlyLayer, fastReadLayer, profileRelayUrls], blockedRelays)
const urls = merged.slice(0, PROFILE_MEDIA_MAX_RELAYS)
if (!urls.length) return []
return [{ urls, filter: buildProfileMediaSpellFilter(pubkey) }]
}
export function buildCalendarSpellFilter(): Filter {
return {
kinds: [ExtendedKind.CALENDAR_EVENT_DATE, ExtendedKind.CALENDAR_EVENT_TIME],

2
src/pages/secondary/MuteListPage/index.tsx

@ -10,7 +10,7 @@ import SecondaryPageLayout from '@/layouts/SecondaryPageLayout' @@ -10,7 +10,7 @@ import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
import { usePrimaryNoteView } from '@/PageManager'
import { useMuteList } from '@/providers/MuteListProvider'
import { useNostr } from '@/providers/NostrProvider'
import { Loader, Lock, Unlock } from 'lucide-react'
import { Lock, Unlock } from 'lucide-react'
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import NotFoundPage from '../NotFoundPage'

2
src/pages/secondary/RssFeedSettingsPage/index.tsx

@ -14,7 +14,7 @@ import { Switch } from '@/components/ui/switch' @@ -14,7 +14,7 @@ import { Switch } from '@/components/ui/switch'
import storage from '@/services/local-storage.service'
import { createRssFeedListDraftEvent } from '@/lib/draft-event'
import { showPublishingFeedback, showSimplePublishSuccess, showPublishingError } from '@/lib/publishing-feedback'
import { CloudUpload, Loader, Trash2, Plus, Download, Upload } from 'lucide-react'
import { CloudUpload, Trash2, Plus, Download, Upload } from 'lucide-react'
import logger from '@/lib/logger'
import { queryService } from '@/services/client.service'
import indexedDb from '@/services/indexed-db.service'

1
src/pages/secondary/WalletPage/LightningAddressInput.tsx

@ -5,7 +5,6 @@ import { Label } from '@/components/ui/label' @@ -5,7 +5,6 @@ import { Label } from '@/components/ui/label'
import { createProfileDraftEvent } from '@/lib/draft-event'
import { isEmail } from '@/lib/utils'
import { useNostr } from '@/providers/NostrProvider'
import { Loader } from 'lucide-react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'

2
src/services/client.service.ts

@ -151,7 +151,7 @@ class ClientService extends EventTarget { @@ -151,7 +151,7 @@ class ClientService extends EventTarget {
private async prewarmProfileSearchIndexFromIdb(): Promise<void> {
const t0 = typeof performance !== 'undefined' ? performance.now() : 0
let profileRows = 0
await indexedDb.iterateProfileEvents((profileEvent) => {
await indexedDb.iterateProfileEvents(async (profileEvent) => {
this.addUsernameToIndex(profileEvent)
profileRows += 1
})

Loading…
Cancel
Save