import moment from 'moment' ; import { Observable , BehaviorSubject } from 'rxjs' ; /**
 * Persistence layer for the newsfeed driver
 */ export class NewsfeedStorage { private readonly lastFetchStorageKey : string ; private readonly readStatusStorageKey : string ; private readonly unreadStatus$ : BehaviorSubject < boolean > ; constructor ( storagePrefix ) { this . lastFetchStorageKey = getStorageKey ( storagePrefix , 'lastFetch' ) ; this . readStatusStorageKey = getStorageKey ( storagePrefix , 'readStatus' ) ; this . unreadStatus$ = new BehaviorSubject < boolean > ( anyUnread ( this . getReadStatus ( ) ) ) ; } getLastFetchTime ( ) { const lastFetchUtc = localStorage . getItem ( this . lastFetchStorageKey ) ; if ( ! lastFetchUtc ) { return undefined ; } return moment ( lastFetchUtc , 'x' ) . toDate ( ) ; } setLastFetchTime ( date ) { localStorage . setItem ( this . lastFetchStorageKey , JSON . stringify ( date . getTime ( ) ) ) ; } setFetchedItems ( itemHashes ) { const currentReadStatus = this . getReadStatus ( ) ; const newReadStatus = { } ; itemHashes . forEach ( ( hash ) => { newReadStatus [ hash ] = currentReadStatus [ hash ] ?? false ; } ) ; return this . setReadStatus ( newReadStatus ) ; } /**
     * Marks given items as read, and return the overall unread status.
     */ markItemsAsRead ( itemHashes ) { const updatedReadStatus = this . getReadStatus ( ) ; itemHashes . forEach ( ( hash ) => { updatedReadStatus [ hash ] = true ; } ) ; return this . setReadStatus ( updatedReadStatus ) ; } isAnyUnread ( ) { return this . unreadStatus$ . value ; } isAnyUnread$ ( ) { return this . unreadStatus$ . asObservable ( ) ; } private getReadStatus ( ) { try { return JSON . parse ( localStorage . getItem ( this . readStatusStorageKey ) || '{}' ) ; } catch ( e ) { return { } ; } } private setReadStatus ( status ) { const hasUnread = anyUnread ( status ) ; this . unreadStatus$ . next ( anyUnread ( status ) ) ; localStorage . setItem ( this . readStatusStorageKey , JSON . stringify ( status ) ) ; return hasUnread ; } } const anyUnread = ( status ) : boolean => Object . values ( status ) . some ( ( read ) => ! read ) ; internal export const getStorageKey = ( prefix , key ) => `newsfeed.${ prefix }.${ key }` ;