@@ -12,7 +12,7 @@ import {
1212 getCachedProfileEvents ,
1313 getCachedProfiles
1414} from '$lib/nostr/cache' ;
15- import { defaultCustomFeedSettings , defaultGuestNip05 , defaultRelays , globalFeedCuratorPubkey , globalFeedHashtags , keywordsForInterests } from '$lib/nostr/config' ;
15+ import { defaultCustomFeedSettings , defaultGlobalFeedAuthors , defaultGuestNip05 , defaultRelays , globalFeedCuratorPubkey , globalFeedHashtags , keywordsForInterests } from '$lib/nostr/config' ;
1616import { appPath } from '$lib/paths' ;
1717import { markRelaysOffline , markRelaysOnline , syncRelayStatus } from '$lib/stores/relayStatus' ;
1818import { insertTimelineItems , timelineCursor , uniqueFreshItems } from '$lib/timeline/window' ;
@@ -83,7 +83,7 @@ const maxFeedEvents = 600;
8383const maxPendingNewerEvents = 600 ;
8484const maxCachedOlderEvents = 600 ;
8585const cachedFeedBufferLimit = maxFeedEvents + maxPendingNewerEvents + maxCachedOlderEvents ;
86- const olderFetchBatchLimit = 80 ;
86+ const olderFetchBatchLimit = 160 ;
8787const olderFetchTarget = pageFeedLimit ;
8888const olderFetchMaxAttempts = 5 ;
8989const olderFetchEmptyAttemptLimit = 2 ;
@@ -153,7 +153,7 @@ let currentSettings = defaultCustomFeedSettings;
153153let currentMode : FeedMode = initialFeedMode ;
154154let currentHashtag = '' ;
155155let currentSessionValue : Session | null = initialSession ;
156- let currentGlobalFeedAuthors : string [ ] = [ ] ;
156+ let currentGlobalFeedAuthors : string [ ] = defaultGlobalFeedAuthors ;
157157let currentNotifications : NotificationItem [ ] = [ ] ;
158158let currentDirectMessages : DirectMessage [ ] = [ ] ;
159159let currentNotificationSeenAt = initialSession && browser ? readLastSeen ( notificationSeenStorageKey , initialSession . pubkey ) : 0 ;
@@ -239,7 +239,10 @@ export async function bootstrap() {
239239 }
240240
241241 const [ cachedEvents , cachedProfiles ] = await Promise . all ( [ getCachedEvents ( cachedFeedBufferLimit ) , getCachedProfiles ( ) ] ) ;
242- const cachedTopLevelEvents = recentFeedEventsForMode ( currentMode , cachedEventsForMode ( currentMode , topLevelFeedEvents ( filterSpam ( cachedEvents , currentMutedPubkeys ) ) , cachedFeedBufferLimit ) ) ;
242+ const cachedTopLevelEvents = recentFeedEventsForMode (
243+ currentMode ,
244+ cachedEventsForMode ( currentMode , topLevelFeedEvents ( filterSpam ( cachedEvents , currentMutedPubkeys , trustedFeedPubkeys ( currentMode ) ) ) , cachedFeedBufferLimit )
245+ ) ;
243246 const visibleEvents = cachedTopLevelEvents . slice ( 0 , Math . min ( initialFeedLimit , maxFeedEvents ) ) ;
244247 cachedOlderEvents = limitFeedBuffer ( cachedTopLevelEvents . slice ( visibleEvents . length ) , maxCachedOlderEvents ) ;
245248 events . set ( visibleEvents ) ;
@@ -375,12 +378,16 @@ function eventsForFeedMode(mode: FeedMode, items: NostrEvent[], follows = curren
375378 ) ;
376379 }
377380 if ( currentHashtag ) return items . filter ( ( event ) => ! eventHasImgurUrl ( event ) ) ;
378- return items . filter ( ( event ) => globalFeedHashtags . some ( ( tag ) => eventHasHashtag ( event , tag ) ) && ! eventHasImgurUrl ( event ) ) ;
381+ return items . filter ( ( event ) => isGlobalFeedEvent ( event ) ) ;
379382}
380383
381384async function getCachedFeedCandidates ( mode : FeedMode , limit = cachedFeedBufferLimit ) {
382385 const cachedEvents = currentHashtag ? await getCachedHashtagEvents ( currentHashtag , limit ) : await getCachedEvents ( limit ) ;
383- return recentFeedEventsForMode ( mode , topLevelFeedEvents ( filterSpam ( cachedEventsForMode ( mode , topLevelFeedEvents ( filterSpam ( cachedEvents , currentMutedPubkeys ) ) , limit ) , currentMutedPubkeys ) ) ) ;
386+ const trustedPubkeys = trustedFeedPubkeys ( mode ) ;
387+ return recentFeedEventsForMode (
388+ mode ,
389+ topLevelFeedEvents ( filterSpam ( cachedEventsForMode ( mode , topLevelFeedEvents ( filterSpam ( cachedEvents , currentMutedPubkeys , trustedPubkeys ) ) , limit ) , currentMutedPubkeys , trustedPubkeys ) )
390+ ) ;
384391}
385392
386393async function primeCachedFeedBuffers ( mode : FeedMode , visibleEvents : NostrEvent [ ] ) {
@@ -1401,8 +1408,8 @@ function mergeFeedEvents(incoming: NostrEvent[], existing: NostrEvent[]) {
14011408 const byId = new Map < string , NostrEvent > ( ) ;
14021409 [ ...existing , ...incoming ] . forEach ( ( event ) => byId . set ( event . id , event ) ) ;
14031410 const merged = [ ...byId . values ( ) ] . filter ( ( event ) => ! currentDeletedEventIds . has ( event . id ) ) . sort ( ( a , b ) => b . created_at - a . created_at ) ;
1404- const globalClean = currentMode === 'global' ? merged . filter ( ( event ) => ! eventHasImgurUrl ( event ) ) : merged ;
1405- const limited = currentMode === 'global' ? limitCryptoTopicDensity ( limitConsecutiveAuthors ( globalClean , 2 ) , 10 ) : globalClean ;
1411+ const globalClean = currentMode === 'global' ? merged . filter ( ( event ) => currentGlobalFeedAuthors . includes ( event . pubkey ) || ! eventHasImgurUrl ( event ) ) : merged ;
1412+ const limited = currentMode === 'global' ? applyGlobalFeedLimits ( globalClean ) : globalClean ;
14061413 return limited ;
14071414}
14081415
@@ -1423,6 +1430,28 @@ function eventHasHashtag(event: NostrEvent, tag: string) {
14231430 return new RegExp ( `(^|\\s)#${ normalized . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) } \\b` , 'i' ) . test ( event . content ) ;
14241431}
14251432
1433+ function isGlobalFeedEvent ( event : NostrEvent ) {
1434+ if ( currentGlobalFeedAuthors . includes ( event . pubkey ) ) return true ;
1435+ return globalFeedHashtags . some ( ( tag ) => eventHasHashtag ( event , tag ) ) && ! eventHasImgurUrl ( event ) ;
1436+ }
1437+
1438+ function trustedFeedPubkeys ( mode : FeedMode ) {
1439+ return mode === 'global' && ! currentHashtag ? new Set ( currentGlobalFeedAuthors ) : new Set < string > ( ) ;
1440+ }
1441+
1442+ function applyGlobalFeedLimits ( items : NostrEvent [ ] ) {
1443+ const trusted = items . filter ( ( event ) => currentGlobalFeedAuthors . includes ( event . pubkey ) ) ;
1444+ const limited = limitCryptoTopicDensity (
1445+ limitConsecutiveAuthors (
1446+ items . filter ( ( event ) => ! currentGlobalFeedAuthors . includes ( event . pubkey ) ) ,
1447+ 2
1448+ ) ,
1449+ 10
1450+ ) ;
1451+ if ( ! trusted . length ) return limited ;
1452+ return [ ...trusted , ...limited ] . sort ( ( a , b ) => b . created_at - a . created_at ) ;
1453+ }
1454+
14261455function feedKeywordHashtags ( settings : CustomFeedSettings ) {
14271456 return [
14281457 ...new Set (
@@ -2014,9 +2043,9 @@ async function resolveDefaultGlobalFeedContext() {
20142043 mergeRelayHints ( relayList . map ( ( relay ) => relay . url ) , 90 ) ;
20152044 const contacts = await fetchContactListDetails ( profile . pubkey , currentRelays ) . catch ( ( ) => ( { pubkeys : [ ] , relayHints : [ ] , items : [ ] } ) ) ;
20162045 mergeRelayHints ( contacts . relayHints , 74 ) ;
2017- currentGlobalFeedAuthors = mergeGlobalFeedAuthors ( contacts . pubkeys , curatorContacts . pubkeys ) ;
2046+ currentGlobalFeedAuthors = mergeGlobalFeedAuthors ( defaultGlobalFeedAuthors , contacts . pubkeys , curatorContacts . pubkeys ) ;
20182047 } else {
2019- currentGlobalFeedAuthors = mergeGlobalFeedAuthors ( curatorContacts . pubkeys ) ;
2048+ currentGlobalFeedAuthors = mergeGlobalFeedAuthors ( defaultGlobalFeedAuthors , curatorContacts . pubkeys ) ;
20202049 }
20212050}
20222051
0 commit comments