import { map, Observable } from "rxjs"; import { NeverDomains, EquivalentDomains, UriMatchStrategySetting, UriMatchStrategy, } from "../../models/domain/domain-service"; import { Utils } from "../../platform/misc/utils"; import { DOMAIN_SETTINGS_DISK, ActiveUserState, GlobalState, KeyDefinition, StateProvider, UserKeyDefinition, } from "../../platform/state"; import { UserId } from "../../types/guid"; const SHOW_FAVICONS = new KeyDefinition(DOMAIN_SETTINGS_DISK, "showFavicons", { deserializer: (value: boolean) => value ?? true, }); const NEVER_DOMAINS = new KeyDefinition(DOMAIN_SETTINGS_DISK, "neverDomains", { deserializer: (value: NeverDomains) => value ?? null, }); const EQUIVALENT_DOMAINS = new UserKeyDefinition(DOMAIN_SETTINGS_DISK, "equivalentDomains", { deserializer: (value: EquivalentDomains) => value ?? null, clearOn: ["logout"], }); const DEFAULT_URI_MATCH_STRATEGY = new UserKeyDefinition( DOMAIN_SETTINGS_DISK, "defaultUriMatchStrategy", { deserializer: (value: UriMatchStrategySetting) => value ?? UriMatchStrategy.Domain, clearOn: [], }, ); export abstract class DomainSettingsService { showFavicons$: Observable; setShowFavicons: (newValue: boolean) => Promise; neverDomains$: Observable; setNeverDomains: (newValue: NeverDomains) => Promise; equivalentDomains$: Observable; setEquivalentDomains: (newValue: EquivalentDomains, userId: UserId) => Promise; defaultUriMatchStrategy$: Observable; setDefaultUriMatchStrategy: (newValue: UriMatchStrategySetting) => Promise; getUrlEquivalentDomains: (url: string) => Observable>; } export class DefaultDomainSettingsService implements DomainSettingsService { private showFaviconsState: GlobalState; readonly showFavicons$: Observable; private neverDomainsState: GlobalState; readonly neverDomains$: Observable; private equivalentDomainsState: ActiveUserState; readonly equivalentDomains$: Observable; private defaultUriMatchStrategyState: ActiveUserState; readonly defaultUriMatchStrategy$: Observable; constructor(private stateProvider: StateProvider) { this.showFaviconsState = this.stateProvider.getGlobal(SHOW_FAVICONS); this.showFavicons$ = this.showFaviconsState.state$.pipe(map((x) => x ?? true)); this.neverDomainsState = this.stateProvider.getGlobal(NEVER_DOMAINS); this.neverDomains$ = this.neverDomainsState.state$.pipe(map((x) => x ?? null)); this.equivalentDomainsState = this.stateProvider.getActive(EQUIVALENT_DOMAINS); this.equivalentDomains$ = this.equivalentDomainsState.state$.pipe(map((x) => x ?? null)); this.defaultUriMatchStrategyState = this.stateProvider.getActive(DEFAULT_URI_MATCH_STRATEGY); this.defaultUriMatchStrategy$ = this.defaultUriMatchStrategyState.state$.pipe( map((x) => x ?? UriMatchStrategy.Domain), ); } async setShowFavicons(newValue: boolean): Promise { await this.showFaviconsState.update(() => newValue); } async setNeverDomains(newValue: NeverDomains): Promise { await this.neverDomainsState.update(() => newValue); } async setEquivalentDomains(newValue: EquivalentDomains, userId: UserId): Promise { await this.stateProvider.getUser(userId, EQUIVALENT_DOMAINS).update(() => newValue); } async setDefaultUriMatchStrategy(newValue: UriMatchStrategySetting): Promise { await this.defaultUriMatchStrategyState.update(() => newValue); } getUrlEquivalentDomains(url: string): Observable> { const domains$ = this.equivalentDomains$.pipe( map((equivalentDomains) => { const domain = Utils.getDomain(url); if (domain == null || equivalentDomains == null) { return new Set() as Set; } const equivalents = equivalentDomains.filter((ed) => ed.includes(domain)).flat(); return new Set(equivalents); }), ); return domains$; } }