Skip to content

Commit

Permalink
[PM-9552] add a toggle for the routing animation (#10005)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
slonkazoid and shane-melton committed Aug 23, 2024
1 parent c2829cd commit f2be150
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 1 deletion.
3 changes: 3 additions & 0 deletions apps/browser/src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3987,6 +3987,9 @@
}
}
},
"enableAnimations": {
"message": "Enable animations"
},
"addAccount": {
"message": "Add account"
},
Expand Down
13 changes: 12 additions & 1 deletion apps/browser/src/popup/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -39,6 +40,7 @@ export class AppComponent implements OnInit, OnDestroy {
private lastActivity: Date;
private activeUserId: UserId;
private recordActivitySubject = new Subject<void>();
private routerAnimations = false;

private destroy$ = new Subject<void>();

Expand All @@ -57,6 +59,7 @@ export class AppComponent implements OnInit, OnDestroy {
private messageListener: MessageListener,
private toastService: ToastService,
private accountService: AccountService,
private animationControlService: AnimationControlService,
) {}

async ngOnInit() {
Expand Down Expand Up @@ -173,6 +176,12 @@ export class AppComponent implements OnInit, OnDestroy {
}
}
});

this.animationControlService.enableRoutingAnimation$
.pipe(takeUntil(this.destroy$))
.subscribe((state) => {
this.routerAnimations = state;
});
}

ngOnDestroy(): void {
Expand All @@ -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 (
Expand Down
9 changes: 9 additions & 0 deletions apps/browser/src/popup/services/services.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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,
Expand Down
13 changes: 13 additions & 0 deletions apps/browser/src/vault/popup/settings/appearance.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,17 @@ <h1 class="center">
{{ accountSwitcherEnabled ? ("faviconDescAlt" | i18n) : ("faviconDesc" | i18n) }}
</div>
</div>
<div class="box">
<div class="box-content">
<div class="box-content-row box-content-row-checkbox" appBoxRow>
<label for="routing">{{ "enableAnimations" | i18n }}</label>
<input
id="routing"
type="checkbox"
(change)="updateRoutingAnimation()"
[(ngModel)]="enableRoutingAnimation"
/>
</div>
</div>
</div>
</main>
11 changes: 11 additions & 0 deletions apps/browser/src/vault/popup/settings/appearance.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -20,13 +21,15 @@ export class AppearanceComponent implements OnInit {
theme: ThemeType;
themeOptions: any[];
accountSwitcherEnabled = false;
enableRoutingAnimation: boolean;

constructor(
private messagingService: MessagingService,
private domainSettingsService: DomainSettingsService,
private badgeSettingsService: BadgeSettingsServiceAbstraction,
i18nService: I18nService,
private themeStateService: ThemeStateService,
private animationControlService: AnimationControlService,
) {
this.themeOptions = [
{ name: i18nService.t("default"), value: ThemeType.System },
Expand All @@ -40,13 +43,21 @@ 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$);

this.theme = await firstValueFrom(this.themeStateService.selectedTheme$);
}

async updateRoutingAnimation() {
await this.animationControlService.setEnableRoutingAnimation(this.enableRoutingAnimation);
}

async updateFavicon() {
await this.domainSettingsService.setShowFavicons(this.enableFavicon);
}
Expand Down
39 changes: 39 additions & 0 deletions libs/common/src/platform/abstractions/animation-control.service.ts
Original file line number Diff line number Diff line change
@@ -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<boolean>;

/**
* A method for updating the state of the animation toggle.
* @param theme The new state.
*/
abstract setEnableRoutingAnimation(state: boolean): Promise<void>;
}

const ROUTING_ANIMATION = new KeyDefinition<boolean>(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<void> {
await this.enableRoutingAnimationState.update(() => state, {
shouldUpdate: (currentState) => currentState !== state,
});
}
}
1 change: 1 addition & 0 deletions libs/common/src/platform/state/state-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit f2be150

Please sign in to comment.