Browse Source

bug-fixes

imwald
Silberengel 1 month ago
parent
commit
f99a96f619
  1. 35
      src/PageManager.tsx
  2. 9
      src/components/NoteList/index.tsx
  3. 2
      src/i18n/locales/ar.ts
  4. 2
      src/i18n/locales/de.ts
  5. 2
      src/i18n/locales/en.ts
  6. 2
      src/i18n/locales/es.ts
  7. 2
      src/i18n/locales/fa.ts
  8. 2
      src/i18n/locales/fr.ts
  9. 2
      src/i18n/locales/hi.ts
  10. 2
      src/i18n/locales/it.ts
  11. 2
      src/i18n/locales/ja.ts
  12. 2
      src/i18n/locales/ko.ts
  13. 2
      src/i18n/locales/pl.ts
  14. 2
      src/i18n/locales/pt-BR.ts
  15. 2
      src/i18n/locales/pt-PT.ts
  16. 2
      src/i18n/locales/ru.ts
  17. 2
      src/i18n/locales/th.ts
  18. 2
      src/i18n/locales/zh.ts
  19. 5
      src/pages/primary/SpellsPage/fauxSpellFeeds.ts
  20. 24
      src/pages/primary/SpellsPage/index.tsx
  21. 43
      src/services/client.service.ts

35
src/PageManager.tsx

@ -1563,16 +1563,16 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) { @@ -1563,16 +1563,16 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) {
window.history.go(-stackLength)
}
if (isSmallScreen) {
return (
<PrimaryPageContext.Provider
value={{
navigate: navigatePrimaryPage,
current: currentPrimaryPage,
currentPageProps,
display: secondaryStack.length === 0
}}
>
const primaryPageContextValue: TPrimaryPageContext = {
navigate: navigatePrimaryPage,
current: currentPrimaryPage,
currentPageProps,
display: isSmallScreen ? secondaryStack.length === 0 : true
}
return (
<PrimaryPageContext.Provider value={primaryPageContextValue}>
{isSmallScreen ? (
<KeyboardShortcutsHelpProvider>
<SecondaryPageContext.Provider
value={{
@ -1702,19 +1702,7 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) { @@ -1702,19 +1702,7 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) {
</CurrentRelaysProvider>
</SecondaryPageContext.Provider>
</KeyboardShortcutsHelpProvider>
</PrimaryPageContext.Provider>
)
}
return (
<PrimaryPageContext.Provider
value={{
navigate: navigatePrimaryPage,
current: currentPrimaryPage,
currentPageProps,
display: true
}}
>
) : (
<KeyboardShortcutsHelpProvider>
<SecondaryPageContext.Provider
value={{
@ -1866,6 +1854,7 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) { @@ -1866,6 +1854,7 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) {
</CurrentRelaysProvider>
</SecondaryPageContext.Provider>
</KeyboardShortcutsHelpProvider>
)}
</PrimaryPageContext.Provider>
)
}

9
src/components/NoteList/index.tsx

@ -531,9 +531,10 @@ const NoteList = forwardRef( @@ -531,9 +531,10 @@ const NoteList = forwardRef(
const batches = await Promise.all(
mappedSubRequests.map(({ urls, filter }) =>
client.fetchEvents(urls, filter, {
firstRelayResultGraceMs: false,
// Was `false`, which disabled feed grace and forced a wait for every relay EOSE (very slow).
firstRelayResultGraceMs: FIRST_RELAY_RESULT_GRACE_MS,
globalTimeout: 14_000,
eoseTimeout: 800,
eoseTimeout: 2_000,
cache: true
})
)
@ -1140,6 +1141,10 @@ const NoteList = forwardRef( @@ -1140,6 +1141,10 @@ const NoteList = forwardRef(
</div>
) : events.length > 0 ? (
<div className="text-center text-sm text-muted-foreground mt-2">{t('no more notes')}</div>
) : (spellFetchTimeoutMs != null && spellFetchTimeoutMs > 0) || oneShotFetch ? (
<div ref={bottomRef} className="mt-6 px-4 text-center text-sm text-muted-foreground">
{t('No posts loaded for this feed. Try refreshing.')}
</div>
) : (
<div ref={bottomRef} className="mt-2 min-h-4" aria-hidden />
)}

2
src/i18n/locales/ar.ts

@ -579,6 +579,8 @@ export default { @@ -579,6 +579,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'إعادة النشر إلى ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/de.ts

@ -602,6 +602,8 @@ export default { @@ -602,6 +602,8 @@ export default {
'Noch keine Lesezeichen mit Ereignis-IDs. Nur klassische (e-Tag-) Lesezeichen erscheinen in diesem Feed.',
'No follows or relays to load yet.': 'Noch keine Follows oder Relays zum Laden.',
'Nothing to load for this feed.': 'Für diesen Feed gibt es nichts zu laden.',
'No posts loaded for this feed. Try refreshing.':
'Keine Beiträge für diesen Feed geladen. Bitte aktualisieren.',
'Republish to ...': 'Erneut veröffentlichen zu ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/en.ts

@ -591,6 +591,8 @@ export default { @@ -591,6 +591,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'Republish to ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/es.ts

@ -584,6 +584,8 @@ export default { @@ -584,6 +584,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'Republicar a ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/fa.ts

@ -582,6 +582,8 @@ export default { @@ -582,6 +582,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'بازنشر به ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/fr.ts

@ -585,6 +585,8 @@ export default { @@ -585,6 +585,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'Reposter vers ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/hi.ts

@ -583,6 +583,8 @@ export default { @@ -583,6 +583,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'परकित कर...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/it.ts

@ -584,6 +584,8 @@ export default { @@ -584,6 +584,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'Ripubblica a...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/ja.ts

@ -581,6 +581,8 @@ export default { @@ -581,6 +581,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': '再公開先 ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/ko.ts

@ -579,6 +579,8 @@ export default { @@ -579,6 +579,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': '다시 게시 ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/pl.ts

@ -582,6 +582,8 @@ export default { @@ -582,6 +582,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'Przekaż ponownie do ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/pt-BR.ts

@ -583,6 +583,8 @@ export default { @@ -583,6 +583,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'Republicar em ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/pt-PT.ts

@ -583,6 +583,8 @@ export default { @@ -583,6 +583,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'Transmitir para...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/ru.ts

@ -583,6 +583,8 @@ export default { @@ -583,6 +583,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'Ретранслировать в ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/th.ts

@ -579,6 +579,8 @@ export default { @@ -579,6 +579,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': 'เผยแพรำไปยง ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

2
src/i18n/locales/zh.ts

@ -577,6 +577,8 @@ export default { @@ -577,6 +577,8 @@ export default {
'No bookmarked notes with id tags yet. Only classic (e-tag) bookmarks load in this feed.',
'No follows or relays to load yet.': 'No follows or relays to load yet.',
'Nothing to load for this feed.': 'Nothing to load for this feed.',
'No posts loaded for this feed. Try refreshing.':
'No posts loaded for this feed. Try refreshing.',
'Republish to ...': '重新发布到 ...',
'All available relays': 'All available relays',
'All active relays (monitoring list)': 'All active relays (monitoring list)',

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

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
/**
* Built-in faux spells: same NoteList + filters as kind-777 spells; except Following, feeds use one-shot
* `fetchEvents` per subRequest (see NoteList `oneShotFetch`) instead of a live timeline subscription.
* Built-in faux spells: same NoteList + filters as kind-777 spells. The Spells page uses live
* `subscribeTimeline` (same as Following) so the first relay results stream in immediately instead of
* waiting for every relay to EOSE on a one-shot query.
*/
import { ExtendedKind, PROFILE_FEED_KINDS, READ_ONLY_RELAY_URLS } from '@/constants'
import {

24
src/pages/primary/SpellsPage/index.tsx

@ -402,7 +402,7 @@ const SpellsPage = forwardRef<TPageRef>(function SpellsPage( @@ -402,7 +402,7 @@ const SpellsPage = forwardRef<TPageRef>(function SpellsPage(
if (spellProp?.trim()) {
if (typeof requestIdleCallback !== 'undefined') {
idleId = requestIdleCallback(run, { timeout: 2500 })
idleId = requestIdleCallback(run, { timeout: 400 })
} else {
timeoutId = setTimeout(run, 0)
}
@ -484,8 +484,8 @@ const SpellsPage = forwardRef<TPageRef>(function SpellsPage( @@ -484,8 +484,8 @@ const SpellsPage = forwardRef<TPageRef>(function SpellsPage(
let catalogSyncDone = false
/** Defer catalog REQ so faux/kind-777 feed opens sockets and paints first. */
const catalogDelayMs = 800
/** Catalog sync runs in parallel with the open feed; avoid an artificial delay. */
const catalogDelayMs = 0
if (cancelled) return
delayId = setTimeout(() => {
if (cancelled) return
@ -683,21 +683,25 @@ const SpellsPage = forwardRef<TPageRef>(function SpellsPage( @@ -683,21 +683,25 @@ const SpellsPage = forwardRef<TPageRef>(function SpellsPage(
return [{ urls, filter: buildDiscussionFilter() }]
}
if (selectedFauxSpell === 'media') {
if (!feedUrls.length) return []
return [{ urls: feedUrls, filter: buildMediaSpellFilter() }]
const urls = appendCuratedReadOnlyRelays(feedUrls, blockedRelays)
if (!urls.length) return []
return [{ urls, filter: buildMediaSpellFilter() }]
}
if (selectedFauxSpell === 'calendar') {
if (!feedUrls.length) return []
return [{ urls: feedUrls, filter: buildCalendarSpellFilter() }]
const urls = appendCuratedReadOnlyRelays(feedUrls, blockedRelays)
if (!urls.length) return []
return [{ urls, filter: buildCalendarSpellFilter() }]
}
if (selectedFauxSpell === 'interests') {
if (!pubkey || !interestListEvent) return []
const topics = interestListEvent.tags.filter((tag) => tag[0] === 't' && tag[1]).map((tag) => tag[1]!)
return buildInterestsSubRequests(feedUrls, topics, PROFILE_FEED_KINDS)
const urls = appendCuratedReadOnlyRelays(feedUrls, blockedRelays)
return buildInterestsSubRequests(urls, topics, PROFILE_FEED_KINDS)
}
if (selectedFauxSpell === 'bookmarks') {
if (!pubkey) return []
return buildBookmarksSubRequests(bookmarkListEvent, feedUrls)
const urls = appendCuratedReadOnlyRelays(feedUrls, blockedRelays)
return buildBookmarksSubRequests(bookmarkListEvent, urls)
}
if (selectedFauxSpell === 'followPacks') {
const urls = appendCuratedReadOnlyRelays(feedUrls, blockedRelays)
@ -1331,7 +1335,7 @@ const SpellsPage = forwardRef<TPageRef>(function SpellsPage( @@ -1331,7 +1335,7 @@ const SpellsPage = forwardRef<TPageRef>(function SpellsPage(
spellFeedInstrumentToken={spellFeedInstrumentToken}
onSpellFeedFirstPaint={handleSpellFeedFirstPaint}
useFilterAsIs={fauxNoteListUseFilterAsIs}
oneShotFetch={selectedFauxSpell !== 'following'}
oneShotFetch={false}
showKind1OPs={selectedFauxSpell === 'following' ? showKind1OPs : true}
showKind1Replies={selectedFauxSpell === 'following' ? showKind1Replies : true}
showKind1111={selectedFauxSpell === 'following' ? showKind1111 : true}

43
src/services/client.service.ts

@ -1045,10 +1045,7 @@ class ClientService extends EventTarget { @@ -1045,10 +1045,7 @@ class ClientService extends EventTarget {
}: {
startLogin?: () => void
needSort?: boolean
/**
* Ignored by {@link ClientService.subscribeTimeline} (kept for compatibility). Initial completion is
* aggregate relay EOSE only; per-event results stream via `onEvents` without faking EOSE.
*/
/** Passed to each shard’s {@link ClientService._subscribeTimeline}: 2s after first event completes initial load if EOSE is slower. */
firstRelayResultGraceMs?: number
} = {}
) {
@ -1513,8 +1510,12 @@ class ClientService extends EventTarget { @@ -1513,8 +1510,12 @@ class ClientService extends EventTarget {
{
startLogin,
needSort = true,
/** @deprecated No longer used; streaming does not fake EOSE (see flushStreamingSnapshot). Kept for call-site compatibility. */
firstRelayResultGraceMs: _unusedFirstRelayGraceMs = FIRST_RELAY_RESULT_GRACE_MS,
/**
* After the **first** stored event arrives from any relay, wait this long then treat the initial
* backlog as complete (same as aggregate EOSE): enables pagination + live `onNew` without waiting for
* every slow/hung relay. Real EOSE still clears the timer and completes earlier if all relays finish first.
*/
firstRelayResultGraceMs = FIRST_RELAY_RESULT_GRACE_MS,
relayReqLog
}: {
startLogin?: () => void
@ -1524,7 +1525,6 @@ class ClientService extends EventTarget { @@ -1524,7 +1525,6 @@ class ClientService extends EventTarget {
relayReqLog?: { groupId: string }
} = {}
) {
void _unusedFirstRelayGraceMs
const relays = Array.from(new Set(urls))
const key = this.generateTimelineKey(relays, filter)
let timeline = this.timelines[key]
@ -1543,11 +1543,28 @@ class ClientService extends EventTarget { @@ -1543,11 +1543,28 @@ class ClientService extends EventTarget {
let events: NEvent[] = []
let eosedAt: number | null = null
let firstResultGraceTimer: ReturnType<typeof setTimeout> | null = null
const clearFirstResultGraceTimer = () => {
if (firstResultGraceTimer != null) {
clearTimeout(firstResultGraceTimer)
firstResultGraceTimer = null
}
}
const armFirstResultGraceAfterFirstEvent = () => {
if (eosedAt != null || firstResultGraceTimer != null) return
if (events.length === 0) return
if (firstRelayResultGraceMs <= 0) return
firstResultGraceTimer = setTimeout(() => {
firstResultGraceTimer = null
if (eosedAt == null) {
handleTimelineEose(true)
}
}, firstRelayResultGraceMs)
}
/**
* Stream every matching event to the UI immediately. Do **not** use a "grace EOSE" timer: it set `eosedAt`
* to wall-clock time while relays were still returning historical rows, so `evt.created_at > eosedAt` was
* almost always false and later relay results were dropped until the feed looked empty/slow.
* Real initial completion is only when {@link ClientService.subscribe} fires aggregate `oneose` (all relays).
* Stream matching events to the UI immediately. Initial completion is either aggregate `oneose` from all
* relays, or {@link firstRelayResultGraceMs} after the first event (whichever comes first).
*/
let streamFlushMicrotask = false
const flushStreamingSnapshot = () => {
@ -1577,6 +1594,8 @@ class ClientService extends EventTarget { @@ -1577,6 +1594,8 @@ class ClientService extends EventTarget {
if (!eosed) return
if (eosedAt != null) return
clearFirstResultGraceTimer()
eosedAt = dayjs().unix()
if (!needSort) {
@ -1614,6 +1633,7 @@ class ClientService extends EventTarget { @@ -1614,6 +1633,7 @@ class ClientService extends EventTarget {
if (!eosedAt) {
events.push(evt)
flushStreamingSnapshot()
armFirstResultGraceAfterFirstEvent()
return
}
// new event
@ -1659,6 +1679,7 @@ class ClientService extends EventTarget { @@ -1659,6 +1679,7 @@ class ClientService extends EventTarget {
return {
timelineKey: key,
closer: () => {
clearFirstResultGraceTimer()
onEvents = () => {}
onNew = () => {}
subCloser.close()

Loading…
Cancel
Save