1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-10 05:30:01 +00:00

switch dependency injection to next achievement service

This commit is contained in:
✨ Audrey ✨
2025-03-20 21:27:31 -04:00
parent a253bf2737
commit 1a6cc6b4eb
5 changed files with 35 additions and 129 deletions

View File

@@ -247,10 +247,10 @@ import { AuditService } from "@bitwarden/common/services/audit.service";
import { EventCollectionService } from "@bitwarden/common/services/event/event-collection.service";
import { EventUploadService } from "@bitwarden/common/services/event/event-upload.service";
import { SearchService } from "@bitwarden/common/services/search.service";
import { AchievementService as AchievementServiceAbstraction } from "@bitwarden/common/tools/achievements/achievement.service.abstraction";
import { EventStore } from "@bitwarden/common/tools/achievements/event-store";
import { EventStoreAbstraction } from "@bitwarden/common/tools/achievements/event-store.abstraction.service";
import { HubAchievementService } from "@bitwarden/common/tools/achievements/hub-achievement.service";
import { AchievementService } from "@bitwarden/common/tools/achievements/achievement.service.abstraction";
import { NextAchievementService } from "@bitwarden/common/tools/achievements/next-achievement.service";
import { DefaultUserEventCollector } from "@bitwarden/common/tools/log/default-user-event-collector";
import { UserEventCollector } from "@bitwarden/common/tools/log/user-event-collector";
import {
PasswordStrengthService,
PasswordStrengthServiceAbstraction,
@@ -359,7 +359,6 @@ import {
ENV_ADDITIONAL_REGIONS,
} from "./injection-tokens";
import { ModalService } from "./modal.service";
import { AchievementHub } from "@bitwarden/common/tools/achievements/achievement-hub";
/**
* Provider definitions used in the ngModule.
@@ -1498,21 +1497,21 @@ const safeProviders: SafeProvider[] = [
],
}),
safeProvider({
provide: EventStoreAbstraction,
useClass: EventStore,
deps: [],
provide: UserEventCollector,
useClass: DefaultUserEventCollector,
deps: [AppIdServiceAbstraction, PlatformUtilsServiceAbstraction],
}),
safeProvider({
provide: AchievementServiceAbstraction,
useClass: HubAchievementService,
deps: [],
provide: AchievementService,
useClass: NextAchievementService,
deps: [UserEventCollector],
}),
safeProvider({
provide: AchievementNotifierServiceAbstraction,
useClass: AchievementNotifierService,
deps: [
AccountServiceAbstraction,
AchievementServiceAbstraction,
AchievementService,
PlatformUtilsServiceAbstraction,
I18nServiceAbstraction,
ToastService,

View File

@@ -3,7 +3,7 @@ import { concat, filter, map, mergeAll, switchMap } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { NextAchievementService } from "@bitwarden/common/tools/achievements/next-achievement.service";
import { AchievementService } from "@bitwarden/common/tools/achievements/achievement.service.abstraction";
import { Achievement } from "@bitwarden/common/tools/achievements/types";
import { UserId } from "@bitwarden/common/types/guid";
import { Icon, ToastService } from "@bitwarden/components";
@@ -15,7 +15,7 @@ import { iconMap } from "./icons/iconMap";
export class AchievementNotifierService implements AchievementNotifierServiceAbstraction {
constructor(
private accountService: AccountService,
private achievementService: NextAchievementService,
private achievementService: AchievementService,
private platformUtilsService: PlatformUtilsService,
private i18nService: I18nService,
private toastService: ToastService,

View File

@@ -1,16 +1,26 @@
import { Observable } from "rxjs";
import { UserId } from "@bitwarden/common/types/guid";
import { Account } from "../../auth/abstractions/account.service";
import { Achievement, AchievementEarnedEvent, AchievementProgressEvent } from "./types";
import {
Achievement,
AchievementEarnedEvent,
AchievementId,
AchievementProgressEvent,
MetricId,
} from "./types";
export abstract class AchievementService {
abstract achievementById$: (achievementId: string) => Observable<Achievement>;
abstract achievementMap: () => Map<AchievementId, Achievement>;
abstract achievementsEarned$: (userId: UserId) => Observable<AchievementEarnedEvent>;
abstract achievementsInProgress$: (userId: UserId) => Observable<AchievementProgressEvent>;
abstract earnedStream$: (account: Account, all?: boolean) => Observable<AchievementEarnedEvent>;
abstract earned$: Observable<AchievementEarnedEvent>;
abstract inProgress$: Observable<AchievementProgressEvent>;
abstract earnedMap$: (account: Account) => Observable<Map<AchievementId, AchievementEarnedEvent>>;
abstract progressStream$: (
account: Account,
all?: boolean,
) => Observable<AchievementProgressEvent>;
abstract metricsMap$: (account: Account) => Observable<Map<MetricId, AchievementProgressEvent>>;
}

View File

@@ -1,76 +0,0 @@
import { filter, find, from, map, Observable } from "rxjs";
import { UserId } from "@bitwarden/common/types/guid";
import { AchievementHub } from "./achievement-hub";
import { AchievementService as AchievementServiceAbstraction } from "./achievement.service.abstraction";
import { EventStoreAbstraction } from "./event-store.abstraction.service";
import {
VaultItems_1_Added_Achievement,
VaultItems_10_Added_Achievement,
} from "./examples/achievements";
import { isEarnedEvent, isProgressEvent } from "./meta";
import {
Achievement,
AchievementEarnedEvent,
AchievementEvent,
AchievementId,
AchievementProgressEvent,
} from "./types";
// Service might be deprecated in favor of the AchievmentHub
// The hub is currently missing a way of listing all achievements, finding by id, but that could be possibly done via the AchievementManager
export class DefaultAchievementService implements AchievementServiceAbstraction {
private _achievements: Achievement[] = [
VaultItems_1_Added_Achievement,
VaultItems_10_Added_Achievement,
];
private _achievementsSubject = from(this._achievements);
achievementById$: (achievementId: string) => Observable<Achievement>;
// Provided by the AchievementHub
achievementsEarned$: (userId: UserId) => Observable<AchievementEarnedEvent>;
// Provided by the AchievementHub
earned$: Observable<AchievementEarnedEvent>;
// Provided by the AchievementHub
achievementsInProgress$: (userId: UserId) => Observable<AchievementProgressEvent>;
// Provided by the AchievementHub
inProgress$: Observable<AchievementProgressEvent>;
constructor(protected eventStore: EventStoreAbstraction, protected achievementHub: AchievementHub) {
this.achievementById$ = (achievementId: AchievementId) =>
this._achievementsSubject.pipe(find((item: Achievement) => item.name === achievementId));
this.achievementsEarned$ = (userId: UserId) => {
return this.eventStore.events$.pipe(
filter(
(event): event is AchievementEarnedEvent =>
isEarnedEvent(event as AchievementEvent) && event.user.id === userId,
),
);
};
this.achievementsInProgress$ = (userId: UserId) => {
return this.eventStore.events$.pipe(
filter(
(event): event is AchievementProgressEvent =>
isProgressEvent(event as AchievementEvent) && event.user.id === userId,
),
);
};
this.earned$ = this.achievementHub.new$().pipe(filter((event) => isEarnedEvent(event)), map((event) => {
return event as AchievementEarnedEvent;
}));
this.inProgress$ = this.achievementHub.new$().pipe(filter((event) => isProgressEvent(event)), map((event) => {
return event as AchievementProgressEvent;
}));
}
}

View File

@@ -1,6 +1,4 @@
import { BehaviorSubject, EMPTY, filter, find, from, Observable } from "rxjs";
import { UserId } from "@bitwarden/common/types/guid";
import { BehaviorSubject, filter, from } from "rxjs";
import { Account } from "../../auth/abstractions/account.service";
import { UserEventCollector } from "../log/user-event-collector";
@@ -8,20 +6,14 @@ import { UserEventCollector } from "../log/user-event-collector";
import { AchievementHub } from "./achievement-hub";
import { AchievementService as AchievementServiceAbstraction } from "./achievement.service.abstraction";
import { isEarnedEvent, isProgressEvent } from "./meta";
import {
Achievement,
AchievementEarnedEvent,
AchievementEvent,
AchievementProgressEvent,
AchievementValidator,
} from "./types";
import { Achievement, AchievementEvent, AchievementValidator } from "./types";
import { ItemCreatedCountConfig } from "./validators/config/item-created-count-config";
import { SendItemCreatedCountConfig } from "./validators/config/send-created-count-config";
import { SendItemCreatedCountValidator } from "./validators/send-item-created-count-validator";
import { VaultItemCreatedCountValidator } from "./validators/vault-item-created-count-validator";
export class NextAchievementService implements AchievementServiceAbstraction {
constructor(private readonly eventLogs: UserEventCollector) {}
constructor(private readonly collector: UserEventCollector) {}
private hubs = new Map<string, AchievementHub>();
@@ -35,7 +27,7 @@ export class NextAchievementService implements AchievementServiceAbstraction {
// FIXME: load stored achievements
const achievements$ = from([] as AchievementEvent[]);
const events$ = this.eventLogs.events$(account);
const events$ = this.collector.events$(account);
const hub = new AchievementHub(validators$, events$, achievements$);
this.hubs.set(account.id, hub);
@@ -49,8 +41,6 @@ export class NextAchievementService implements AchievementServiceAbstraction {
...SendItemCreatedCountConfig.AllConfigs,
];
private _achievementsSubject = from(this._achievements);
achievementMap() {
return new Map(this._achievements.map((a) => [a.achievement, a] as const));
}
@@ -80,21 +70,4 @@ export class NextAchievementService implements AchievementServiceAbstraction {
metricsMap$(account: Account) {
return this.getHub(account).metrics$();
}
achievementById$(achievementId: string): Observable<Achievement> {
return this._achievementsSubject.pipe(
find((item: Achievement) => item.name === achievementId),
filter((f): f is Achievement => !!f),
);
}
earned$: Observable<AchievementEarnedEvent> = EMPTY;
inProgress$: Observable<AchievementProgressEvent> = EMPTY;
achievementsEarned$(userId: UserId): Observable<AchievementEarnedEvent> {
return EMPTY;
}
achievementsInProgress$(userId: UserId): Observable<AchievementProgressEvent> {
return EMPTY;
}
}