import { EventEmitter , Injectable , Optional } from '@angular/core' ; import { Race } from '@firestone-hs/reference-data' ; import { BehaviorSubject } from 'rxjs' ; import { ArenaClassFilterType } from '../models/arena/arena-class-filter.type' ; import { ArenaTimeFilterType } from '../models/arena/arena-time-filter.type' ; import { BgsStatsFilterId } from '../models/battlegrounds/post-match/bgs-stats-filter-id.type' ; import { DuelsClassFilterType } from '../models/duels/duels-class-filter.type' ; import { DuelsGameModeFilterType } from '../models/duels/duels-game-mode-filter.type' ; import { DuelsHeroSortFilterType } from '../models/duels/duels-hero-sort-filter.type' ; import { DuelsStatTypeFilterType } from '../models/duels/duels-stat-type-filter.type' ; import { DuelsTimeFilterType } from '../models/duels/duels-time-filter.type' ; import { DuelsTopDecksDustFilterType } from '../models/duels/duels-top-decks-dust-filter.type' ; import { DuelsTreasureStatTypeFilterType } from '../models/duels/duels-treasure-stat-type-filter.type' ; import { BgsActiveTimeFilterType } from '../models/mainwindow/battlegrounds/bgs-active-time-filter.type' ; import { BgsHeroSortFilterType } from '../models/mainwindow/battlegrounds/bgs-hero-sort-filter.type' ; import { BgsRankFilterType } from '../models/mainwindow/battlegrounds/bgs-rank-filter.type' ; import { MmrGroupFilterType } from '../models/mainwindow/battlegrounds/mmr-group-filter-type' ; import { CurrentAppType } from '../models/mainwindow/current-app.type' ; import { DeckFilters } from '../models/mainwindow/decktracker/deck-filters' ; import { ReplaysFilterCategoryType } from '../models/mainwindow/replays/replays-filter-category.type' ; import { StatsXpGraphSeasonFilterType } from '../models/mainwindow/stats/stats-xp-graph-season-filter.type' ; import { MemoryVisitor } from '../models/memory/memory-mercenaries-collection-info' ; import { MercenariesHeroLevelFilterType , MercenariesModeFilterType , MercenariesPveDifficultyFilterType , MercenariesPvpMmrFilterType , MercenariesRoleFilterType , MercenariesStarterFilterType , } from '../models/mercenaries/mercenaries-filter-types' ; import { MercenariesPersonalHeroesSortCriteria } from '../models/mercenaries/personal-heroes-sort-criteria.type' ; import { FORCE_LOCAL_PROP , Preferences } from '../models/preferences' ; import { Ftue } from '../models/preferences/ftue' ; import { ApiRunner } from './api-runner' ; import { GenericStorageService } from './generic-storage.service' ; import { OutOfCardsToken } from './mainwindow/out-of-cards.service' ; import { OverwolfService } from './overwolf.service' ; import { areDeepEqual , capitalizeFirstLetter } from './utils' ; declare let amplitude ; const PREF_UPDATE_URL = 'https://api.firestoneapp.com/userPrefs/post/preferences/{proxy+}' ; const PREF_RETRIEVE_URL = 'https://api.firestoneapp.com/userPrefs/get/preferences/{proxy+}' ; @ Injectable ( ) export class PreferencesService { public static readonly DECKTRACKER_OVERLAY_DISPLAY = 'DECKTRACKER_OVERLAY_DISPLAY' ; public static readonly DECKTRACKER_MATCH_OVERLAY_DISPLAY = 'DECKTRACKER_MATCH_OVERLAY_DISPLAY' ; public static readonly DECKTRACKER_OVERLAY_SIZE = 'DECKTRACKER_OVERLAY_SIZE' ; public static readonly TWITCH_CONNECTION_STATUS = 'TWITCH_CONNECTION_STATUS' ; private preferencesEventBus = new BehaviorSubject < Preferences > ( new Preferences ( ) ) ; constructor ( private readonly storage , @ Optional ( ) private readonly ow , private readonly api ) { if ( this . ow ) { this . setup ( ) ; } } private async setup ( ) { window [ 'preferencesEventBus' ] = this . preferencesEventBus ; const currentWindow = await this . ow ?. getCurrentWindow ( ) ; if ( currentWindow ?. name !== OverwolfService . MAIN_WINDOW ) { window [ 'preferencesEventBus' ] = null ; } } public init ( ) { if ( this . ow ) { this . startPrefsSync ( ) ; } } public getPreferences ( ) { return this . storage . getUserPreferences ( ) ; } public async reset ( ) { const currentPrefs = await this . getPreferences ( ) ; const newPrefs = Object . assign ( new Preferences ( ) , { desktopDeckHiddenDeckCodes : currentPrefs . desktopDeckHiddenDeckCodes , desktopDeckStatsReset : currentPrefs . desktopDeckStatsReset , } as Preferences ) ; await this . savePreferences ( newPrefs ) ; } public async resetDecktrackerPositions ( ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , decktrackerPosition : undefined , opponentOverlayPosition : undefined , } ; await this . savePreferences ( newPrefs ) ; } public async setValue ( field , pref ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , [ field ] : pref } ; await this . savePreferences ( newPrefs ) ; return newPrefs ; } public async setGlobalFtueDone ( ) { const prefs = await this . getPreferences ( ) ; const ftue = { ... prefs . ftue , hasSeenGlobalFtue : true } ; const newPrefs = { ... prefs , ftue : ftue } ; await this . savePreferences ( newPrefs ) ; } public async updateReplayFilterDeckstring ( type , value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , replaysFilterDeckstring : value } ; await this . savePreferences ( newPrefs ) ; } public async updateReplayFilterGameMode ( type , value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , replaysFilterGameMode : value } ; await this . savePreferences ( newPrefs ) ; } public async updateReplayFilterBgHero ( type , value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , replaysFilterBgHero : value } ; await this . savePreferences ( newPrefs ) ; } public async updateReplayFilterPlayerClass ( type , value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , replaysFilterPlayerClass : value } ; await this . savePreferences ( newPrefs ) ; } public async updateReplayFilterOpponentClass ( type , value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , replaysFilterOpponentClass : value } ; await this . savePreferences ( newPrefs ) ; } public async setDontShowNewVersionNotif ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , dontShowNewVersionNotif : value } ; await this . savePreferences ( newPrefs ) ; } public async setMainVisibleSection ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , currentMainVisibleSection : value } ; await this . savePreferences ( newPrefs ) ; } public async setContactEmail ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , contactEmail : value } ; await this . savePreferences ( newPrefs ) ; } public async toggleAdvancedSettings ( ) { const prefs = await this . getPreferences ( ) ; const advancedModeToggledOn = prefs . advancedModeToggledOn ; const newPrefs = { ... prefs , advancedModeToggledOn : ! advancedModeToggledOn } ; await this . savePreferences ( newPrefs ) ; } public async setHasSeenVideoCaptureChangeNotif ( pref ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , hasSeenVideoCaptureChangeNotif : pref } ; await this . savePreferences ( newPrefs ) ; } public async setTwitchAccessToken ( pref ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , twitchAccessToken : pref } ; await this . savePreferences ( newPrefs , PreferencesService . TWITCH_CONNECTION_STATUS ) ; } public async setTwitchUserName ( pref ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , twitchUserName : pref } ; await this . savePreferences ( newPrefs , PreferencesService . TWITCH_CONNECTION_STATUS ) ; } public async disconnectTwitch ( ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , twitchAccessToken : undefined } ; await this . savePreferences ( newPrefs , PreferencesService . TWITCH_CONNECTION_STATUS ) ; } public async udpateOutOfCardsToken ( token ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , outOfCardsToken : token } ; await this . savePreferences ( newPrefs ) ; } public async acknowledgeFtue ( pref ) { const prefs = await this . getPreferences ( ) ; const ftue = prefs . ftue ; const newFtue = { ... ftue , [ pref ] : true } as Ftue ; const newPrefs = { ... prefs , ftue : newFtue } ; await this . savePreferences ( newPrefs ) ; } public async acknowledgeReleaseNotes ( version ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , lastSeenReleaseNotes : version } ; await this . savePreferences ( newPrefs ) ; } public async updateTrackerPosition ( left , top ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , decktrackerPosition : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async updateOpponentTrackerPosition ( left , top ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , opponentOverlayPosition : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async updateSecretsHelperPosition ( left , top ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , secretsHelperPosition : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsSimulationWidgetPosition ( left , top ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsSimulationWidgetPosition : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsBannedTribedPosition ( left , top ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsBannedTribesWidgetPosition : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsMinionsListPosition ( left , top ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsMinionsListPosition : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async updateCounterPosition ( activeCounter , side , left , top ) { const prefs = await this . getPreferences ( ) ; const propertyName = this . buildCounterPropertyName ( activeCounter , side ) ; const newPrefs = { ... prefs , [ propertyName ] : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async getCounterPosition ( activeCounter , side ) { const prefs = await this . getPreferences ( ) ; return prefs [ this . buildCounterPropertyName ( activeCounter , side ) ] ; } public async updateSecretsHelperWidgetPosition ( left , top ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , secretsHelperWidgetPosition : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsOverlayButtonPosition ( left , top ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsOverlayButtonPosition : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsSelectedTabs ( selectedStats ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsSelectedTabs2 : selectedStats } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsNumberOfDisplayedTabs ( tabsNumber ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsNumberOfDisplayedTabs : tabsNumber } ; await this . savePreferences ( newPrefs ) ; } public async setZoneToggleDefaultClose ( name , side , close ) { const prefs = await this . getPreferences ( ) ; const propertyName = 'overlayZoneToggleDefaultClose_' + side + '_' + name ; const newPrefs = { ... prefs , [ propertyName ] : close } ; await this . savePreferences ( newPrefs ) ; } public async getZoneToggleDefaultClose ( name , side ) { const prefs = await this . getPreferences ( ) ; const propertyName = 'overlayZoneToggleDefaultClose_' + side + '_' + name ; return prefs [ propertyName ] ; } public async updateBgsTimeFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsActiveTimeFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsRankFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsActiveRankFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsTribesFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsActiveTribesFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsHeroSortFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsActiveHeroSortFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsHeroFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsActiveHeroFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsMmrGroupFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsActiveMmrGroupFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsActiveSimulatorMinionTribeFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsActiveSimulatorMinionTribeFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateBgsActiveSimulatorMinionTierFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , bgsActiveSimulatorMinionTierFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesModeFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesActiveModeFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesPveDifficultyFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesActivePveDifficultyFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesPvpMmrFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesActivePvpMmrFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesRoleFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesActiveRoleFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesHeroLevelFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesActiveHeroLevelFilter2 : value } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesStarterFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesActiveStarterFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesTeamPlayerPosition ( left , top ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesPlayerTeamOverlayPosition : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesActionsQueueOverlayPosition ( left , top ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesActionsQueueOverlayPosition : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesTeamOpponentPosition ( left , top ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesOpponentTeamOverlayPosition : { left , top } } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesVisitorsProgress ( info ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesVisitorsProgress : info } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesPersonalHeroesSortCriteria ( info ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesPersonalHeroesSortCriteria : info } ; await this . savePreferences ( newPrefs ) ; } public async updateMercenariesShowHiddenTeams ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesShowHiddenTeams : value } ; this . savePreferences ( newPrefs ) ; return newPrefs ; } public async updateMercenariesHiddenTeamIds ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , mercenariesHiddenTeamIds : value } ; this . savePreferences ( newPrefs ) ; return newPrefs ; } public async updateDuelsHeroSortFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsActiveHeroSortFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateDuelsTreasurePassiveTypeFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsActiveTreasureStatTypeFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateDuelsStatTypeFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsActiveStatTypeFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateDuelsGameModeFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsActiveGameModeFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateDuelsLeaderboardGameModeFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsActiveLeaderboardModeFilter : value as any } ; await this . savePreferences ( newPrefs ) ; } public async updateDuelsTimeFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsActiveTimeFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateDuelsTopDecksClassFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsActiveTopDecksClassFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateDuelsTopDecksDustFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsActiveTopDecksDustFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateDuelsMmrFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsActiveMmrFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateDuelsHeroPowerFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsActiveHeroPowerFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateDuelsSignatureTreasureFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsActiveSignatureTreasureFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateDuelsDeckName ( deckstring , newName ) { const prefs = await this . getPreferences ( ) ; const names = prefs . duelsPersonalDeckNames ; names [ deckstring ] = newName ; const newPrefs = { ... prefs , duelsPersonalDeckNames : names } ; await this . savePreferences ( newPrefs ) ; } public async updateArenaTimeFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , arenaActiveTimeFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateArenaClassFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , arenaActiveClassFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async updateStatsXpGraphFilter ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , statsXpGraphSeasonFilter : value } ; await this . savePreferences ( newPrefs ) ; } public async setDesktopDeckFilters ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , desktopDeckFilters : value } ; await this . savePreferences ( newPrefs ) ; return newPrefs ; } public async updateDesktopDecktrackerChangeMatchupAsPercentages ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , desktopDeckShowMatchupAsPercentages : value } ; await this . savePreferences ( newPrefs ) ; return newPrefs ; } public async setDeckResetDates ( deckstring , newResetDates ) { const prefs = await this . getPreferences ( ) ; const newReset = { ... prefs . desktopDeckStatsReset , [ deckstring ] : newResetDates , } ; const newPrefs = { ... prefs , desktopDeckStatsReset : newReset } ; this . savePreferences ( newPrefs ) ; return newPrefs ; } public async setDeckDeleteDates ( deckstring , newDeleteDates ) { const prefs = await this . getPreferences ( ) ; const newDelete = { ... prefs . desktopDeckDeletes , [ deckstring ] : newDeleteDates , } ; console . debug ( 'newDelete' , newDelete ) ; const newPrefs = { ... prefs , desktopDeckDeletes : newDelete } ; await this . savePreferences ( newPrefs ) ; return newPrefs ; } public async setDesktopDeckHiddenDeckCodes ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , desktopDeckHiddenDeckCodes : value } ; this . savePreferences ( newPrefs ) ; return newPrefs ; } public async setDuelsPersonalDeckHiddenDeckCodes ( value ) { const prefs = await this . getPreferences ( ) ; const newPrefs = { ... prefs , duelsPersonalDeckHiddenDeckCodes : value } ; this . savePreferences ( newPrefs ) ; return newPrefs ; } public async savePreferences ( userPrefs , eventName = null ) { const finalPrefs = { ... userPrefs , lastUpdateDate : new Date ( ) , } ; await this . storage . saveUserPreferences ( finalPrefs ) ; const eventBus = this . ow ?. getMainWindow ( ) . preferencesEventBus ; eventBus ?. next ( { name : eventName , preferences : finalPrefs , } ) ; } public async updateRemotePreferences ( ) { if ( ! this . ow ) { return ; } const userPrefs = await this . getPreferences ( ) ; console . log ( '[preferences] prefs from DB' , userPrefs != null ) ; const currentUser = await this . ow . getCurrentUser ( ) ; const prefsToSync = new Preferences ( ) ; for ( const prop in userPrefs ) { const meta = Reflect . getMetadata ( FORCE_LOCAL_PROP , prefsToSync , prop ) ; if ( ! meta ) { prefsToSync [ prop ] = userPrefs [ prop ] ; } } console . log ( '[preferences] saving remote prefs' ) ; await this . api . callPostApi ( PREF_UPDATE_URL , { userId : currentUser . userId , userName : currentUser . username , prefs : prefsToSync , } ) ; } public async loadRemotePrefs ( ) { if ( ! this . ow ) { return ; } const currentUser = await this . ow . getCurrentUser ( ) ; const result = await this . api . callPostApi ( PREF_RETRIEVE_URL , { userId : currentUser . userId , userName : currentUser . username , } ) ; if ( ! result ) { return result ; } const resultWithDate = { ... result , lastUpdateDate : result . lastUpdateDate ? new Date ( result . lastUpdateDate ) : null , } ; this . currentSyncDate = resultWithDate . lastUpdateDate ; this . lastSyncPrefs = resultWithDate ; console . debug ( '[preferences] remote prefs' , result , resultWithDate ) ; return resultWithDate ; } private buildCounterPropertyName ( activeCounter , side ) { return side + capitalizeFirstLetter ( activeCounter ) + 'CounterWidgetPosition' ; } private currentSyncDate : Date ; private lastSyncPrefs : Preferences ; private startPrefsSync ( ) { setInterval ( async ( ) => { console . debug ( '[preferences] checking prefs update' , this . currentSyncDate ) ; const userPrefs = await this . getPreferences ( ) ; console . debug ( '[preferences] got local prefs' , userPrefs . lastUpdateDate , this . currentSyncDate , this . currentSyncDate ?. getTime ( ) , userPrefs . lastUpdateDate ?. getTime ( ) ) ; if ( ! ! userPrefs . lastUpdateDate && ( ! this . currentSyncDate || userPrefs . lastUpdateDate . getTime ( ) > this . currentSyncDate . getTime ( ) ) ) { const userPrefsLocal = new Preferences ( ) ; for ( const prop in userPrefs ) { const meta = Reflect . getMetadata ( FORCE_LOCAL_PROP , userPrefsLocal , prop ) ; if ( ! meta && userPrefsLocal . hasOwnProperty ( prop ) ) { userPrefsLocal [ prop ] = userPrefs [ prop ] ; } } const remotePrefsLocal = new Preferences ( ) ; for ( const prop in this . lastSyncPrefs ) { const meta = Reflect . getMetadata ( FORCE_LOCAL_PROP , remotePrefsLocal , prop ) ; if ( ! meta && remotePrefsLocal . hasOwnProperty ( prop ) ) { remotePrefsLocal [ prop ] = this . lastSyncPrefs [ prop ] ; } } if ( ! areDeepEqual ( userPrefsLocal , remotePrefsLocal ) ) { console . log ( '[preferences] updating remote prefs' ) ; this . lastSyncPrefs = userPrefs ; this . currentSyncDate = userPrefs . lastUpdateDate ; await this . updateRemotePreferences ( ) ; } } } , 5 * 60 * 1000 ) ; } }