From f2be150b70827269020f9a2552c01294aac35258 Mon Sep 17 00:00:00 2001 From: slonkazoid Date: Sat, 24 Aug 2024 00:13:43 +0300 Subject: [PATCH] [PM-9552] add a toggle for the routing animation (#10005) * add a toggle for the routing animation * add missing period (thanks mat) * rename routingAnimation to enableRoutingAnimation for consistency * move animation-control.service.ts into abstractions * simplify config option * fixup! simplify config option remove dead aria reference --------- Co-authored-by: Shane Melton --- apps/browser/src/_locales/en/messages.json | 3 ++ apps/browser/src/popup/app.component.ts | 13 ++++++- .../src/popup/services/services.module.ts | 9 +++++ .../popup/settings/appearance.component.html | 13 +++++++ .../popup/settings/appearance.component.ts | 11 ++++++ .../abstractions/animation-control.service.ts | 39 +++++++++++++++++++ .../src/platform/state/state-definitions.ts | 1 + 7 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 libs/common/src/platform/abstractions/animation-control.service.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 5ed28c6ec0ef..1e8fd03ade39 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -3987,6 +3987,9 @@ } } }, + "enableAnimations": { + "message": "Enable animations" + }, "addAccount": { "message": "Add account" }, diff --git a/apps/browser/src/popup/app.component.ts b/apps/browser/src/popup/app.component.ts index 7ac3e02160d5..27fc868a9bb9 100644 --- a/apps/browser/src/popup/app.component.ts +++ b/apps/browser/src/popup/app.component.ts @@ -6,6 +6,7 @@ import { LogoutReason } from "@bitwarden/auth/common"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { AnimationControlService } from "@bitwarden/common/platform/abstractions/animation-control.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; @@ -39,6 +40,7 @@ export class AppComponent implements OnInit, OnDestroy { private lastActivity: Date; private activeUserId: UserId; private recordActivitySubject = new Subject(); + private routerAnimations = false; private destroy$ = new Subject(); @@ -57,6 +59,7 @@ export class AppComponent implements OnInit, OnDestroy { private messageListener: MessageListener, private toastService: ToastService, private accountService: AccountService, + private animationControlService: AnimationControlService, ) {} async ngOnInit() { @@ -173,6 +176,12 @@ export class AppComponent implements OnInit, OnDestroy { } } }); + + this.animationControlService.enableRoutingAnimation$ + .pipe(takeUntil(this.destroy$)) + .subscribe((state) => { + this.routerAnimations = state; + }); } ngOnDestroy(): void { @@ -181,7 +190,9 @@ export class AppComponent implements OnInit, OnDestroy { } getState(outlet: RouterOutlet) { - if (outlet.activatedRouteData.state === "ciphers") { + if (!this.routerAnimations) { + return; + } else if (outlet.activatedRouteData.state === "ciphers") { const routeDirection = (window as any).routeDirection != null ? (window as any).routeDirection : ""; return ( diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index f6f3bf732b0c..7c5e49e741bf 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -41,6 +41,10 @@ import { } from "@bitwarden/common/autofill/services/user-notification-settings.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { ClientType } from "@bitwarden/common/enums"; +import { + AnimationControlService, + DefaultAnimationControlService, +} from "@bitwarden/common/platform/abstractions/animation-control.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; @@ -527,6 +531,11 @@ const safeProviders: SafeProvider[] = [ useClass: Fido2UserVerificationService, deps: [PasswordRepromptService, UserVerificationService, DialogService], }), + safeProvider({ + provide: AnimationControlService, + useClass: DefaultAnimationControlService, + deps: [GlobalStateProvider], + }), safeProvider({ provide: TaskSchedulerService, useExisting: ForegroundTaskSchedulerService, diff --git a/apps/browser/src/vault/popup/settings/appearance.component.html b/apps/browser/src/vault/popup/settings/appearance.component.html index 36b219051273..a431fc72a1f7 100644 --- a/apps/browser/src/vault/popup/settings/appearance.component.html +++ b/apps/browser/src/vault/popup/settings/appearance.component.html @@ -64,4 +64,17 @@

{{ accountSwitcherEnabled ? ("faviconDescAlt" | i18n) : ("faviconDesc" | i18n) }} +
+
+
+ + +
+
+
diff --git a/apps/browser/src/vault/popup/settings/appearance.component.ts b/apps/browser/src/vault/popup/settings/appearance.component.ts index 154d4e426d83..1095b56a75c4 100644 --- a/apps/browser/src/vault/popup/settings/appearance.component.ts +++ b/apps/browser/src/vault/popup/settings/appearance.component.ts @@ -3,6 +3,7 @@ import { firstValueFrom } from "rxjs"; import { BadgeSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/badge-settings.service"; import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service"; +import { AnimationControlService } from "@bitwarden/common/platform/abstractions/animation-control.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { ThemeType } from "@bitwarden/common/platform/enums"; @@ -20,6 +21,7 @@ export class AppearanceComponent implements OnInit { theme: ThemeType; themeOptions: any[]; accountSwitcherEnabled = false; + enableRoutingAnimation: boolean; constructor( private messagingService: MessagingService, @@ -27,6 +29,7 @@ export class AppearanceComponent implements OnInit { private badgeSettingsService: BadgeSettingsServiceAbstraction, i18nService: I18nService, private themeStateService: ThemeStateService, + private animationControlService: AnimationControlService, ) { this.themeOptions = [ { name: i18nService.t("default"), value: ThemeType.System }, @@ -40,6 +43,10 @@ export class AppearanceComponent implements OnInit { } async ngOnInit() { + this.enableRoutingAnimation = await firstValueFrom( + this.animationControlService.enableRoutingAnimation$, + ); + this.enableFavicon = await firstValueFrom(this.domainSettingsService.showFavicons$); this.enableBadgeCounter = await firstValueFrom(this.badgeSettingsService.enableBadgeCounter$); @@ -47,6 +54,10 @@ export class AppearanceComponent implements OnInit { this.theme = await firstValueFrom(this.themeStateService.selectedTheme$); } + async updateRoutingAnimation() { + await this.animationControlService.setEnableRoutingAnimation(this.enableRoutingAnimation); + } + async updateFavicon() { await this.domainSettingsService.setShowFavicons(this.enableFavicon); } diff --git a/libs/common/src/platform/abstractions/animation-control.service.ts b/libs/common/src/platform/abstractions/animation-control.service.ts new file mode 100644 index 000000000000..9d16e284dcdb --- /dev/null +++ b/libs/common/src/platform/abstractions/animation-control.service.ts @@ -0,0 +1,39 @@ +import { Observable, map } from "rxjs"; + +import { GlobalStateProvider, KeyDefinition, ANIMATION_DISK } from "../state"; + +export abstract class AnimationControlService { + /** + * The routing animation toggle. + */ + abstract enableRoutingAnimation$: Observable; + + /** + * A method for updating the state of the animation toggle. + * @param theme The new state. + */ + abstract setEnableRoutingAnimation(state: boolean): Promise; +} + +const ROUTING_ANIMATION = new KeyDefinition(ANIMATION_DISK, "routing", { + deserializer: (s) => s, +}); + +export class DefaultAnimationControlService implements AnimationControlService { + private readonly enableRoutingAnimationState = this.globalStateProvider.get(ROUTING_ANIMATION); + + enableRoutingAnimation$ = this.enableRoutingAnimationState.state$.pipe( + map((state) => state ?? this.defaultEnableRoutingAnimation), + ); + + constructor( + private globalStateProvider: GlobalStateProvider, + private defaultEnableRoutingAnimation: boolean = true, + ) {} + + async setEnableRoutingAnimation(state: boolean): Promise { + await this.enableRoutingAnimationState.update(() => state, { + shouldUpdate: (currentState) => currentState !== state, + }); + } +} diff --git a/libs/common/src/platform/state/state-definitions.ts b/libs/common/src/platform/state/state-definitions.ts index f3880633e064..32307203b295 100644 --- a/libs/common/src/platform/state/state-definitions.ts +++ b/libs/common/src/platform/state/state-definitions.ts @@ -117,6 +117,7 @@ export const POPUP_VIEW_MEMORY = new StateDefinition("popupView", "memory", { export const SYNC_DISK = new StateDefinition("sync", "disk", { web: "memory" }); export const THEMING_DISK = new StateDefinition("theming", "disk", { web: "disk-local" }); export const TRANSLATION_DISK = new StateDefinition("translation", "disk", { web: "disk-local" }); +export const ANIMATION_DISK = new StateDefinition("animation", "disk"); export const TASK_SCHEDULER_DISK = new StateDefinition("taskScheduler", "disk"); // Secrets Manager