From 78e35081a71224acd08fb19b8b70ee9698232160 Mon Sep 17 00:00:00 2001 From: dcaslin Date: Sun, 5 Apr 2026 20:47:04 -0400 Subject: [PATCH 1/2] Adopt Angular signals for reactive state (#611) Convert BehaviorSubjects to WritableSignals in AppStateService, ChildComponent, and 7 service-level loading flags. Replace | async pipe with signal() reads in 54 templates. Replace .next() with .set() and .getValue() with () across 24 TS files. Remove AsyncPipe import from 11 components that no longer need it. Convert FriendsComponent members to signal with effect() for reactive state derivation. Co-Authored-By: Claude Opus 4.6 --- docs/modernization-plan.md | 9 +++- package.json | 2 +- src/app/auth/auth/auth.component.html | 2 +- src/app/auth/auth/auth.component.ts | 4 +- .../bungie-search.component.html | 2 +- .../bungie-search/bungie-search.component.ts | 8 +-- .../clan-search/clan-search.component.html | 2 +- .../clan-search/clan-search.component.ts | 4 +- .../clan-badges/clan-badges.component.html | 2 +- .../clan-collection-item.component.html | 2 +- .../clan-collection-item.component.ts | 4 +- .../clan-lifetime.component.html | 2 +- .../clan-members/clan-members.component.html | 2 +- .../clan-milestones.component.html | 22 ++++----- src/app/clan/clan-state.service.ts | 10 ++-- .../clan-seals/clan-seals.component.html | 2 +- src/app/clan/clan.component.html | 4 +- .../weapon-compare-dialog.component.html | 2 +- .../friends/friends/friends.component.html | 16 +++--- src/app/friends/friends/friends.component.ts | 49 +++++++++---------- .../gamer-tag-search.component.html | 2 +- .../gamer-tag-search.component.ts | 4 +- .../gear-compare-dialog.component.html | 6 +-- .../gear-utilities-dialog.component.html | 2 +- src/app/gear/gear/gear.component.html | 14 +++--- src/app/gear/gear/gear.component.ts | 6 +-- .../mod-helper-dialog.component.html | 4 +- .../optimize-gun-perks-dialog.component.html | 4 +- .../select-mod-dialog.component.html | 2 +- .../select-mod-dialog.component.ts | 4 +- .../possible-rolls-dialog.component.html | 2 +- .../possible-rolls-dialog.component.ts | 4 +- .../writable-sockets.component.html | 10 ++-- .../writable-sockets.component.ts | 4 +- .../history/history/history.component.html | 4 +- src/app/history/history/history.component.ts | 4 +- src/app/home/home.component.html | 8 +-- src/app/home/home.component.ts | 4 +- src/app/party/party.component.html | 2 +- src/app/party/party.component.ts | 4 +- src/app/perkbench/perkbench.component.ts | 12 ++--- .../pgcr-entry-dialog.component.html | 2 +- .../pgcr-entry-dialog.component.ts | 4 +- src/app/pgcr/pgcr2/pgcr2.component.html | 2 +- .../player/checklist/checklist.component.html | 8 +-- .../collection-badge.component.html | 6 +-- .../collection-badges.component.html | 2 +- .../collection-search.component.html | 4 +- .../collection-tree.component.html | 4 +- .../player/lifetime/lifetime.component.html | 2 +- .../milestones/milestones.component.html | 14 +++--- .../player/milestones/milestones.component.ts | 2 +- src/app/player/player.component.html | 2 +- .../player/progress/progress.component.html | 4 +- .../pursuit-list/pursuit-list.component.html | 2 +- .../quest-dialog/quest-dialog.component.html | 2 +- .../quest-dialog/quest-dialog.component.ts | 4 +- .../special-triumph-list.component.html | 2 +- .../triumph-closest.component.html | 2 +- .../triumph-seals.component.html | 4 +- .../triumph-search.component.html | 2 +- .../triumph-seasons.component.html | 2 +- .../triumph-tracked.component.html | 2 +- .../triumph-tree/triumph-tree.component.html | 4 +- .../recent-players.component.html | 4 +- .../recent-players.component.ts | 8 +-- src/app/service/app-state.service.ts | 31 ++++++------ src/app/service/dim-sync.service.ts | 23 ++++----- src/app/service/gear.service.ts | 28 +++++------ src/app/service/mark.service.ts | 8 +-- src/app/service/streaming.service.ts | 13 +++-- .../settings/settings/settings.component.html | 4 +- .../settings/settings/settings.component.ts | 4 +- src/app/shared/ad-slot/ad-slot.component.html | 2 +- src/app/shared/child.component.ts | 5 +- .../friend-star/friend-star.component.html | 2 +- .../friend-star/friend-star.component.ts | 14 +++--- .../legendary-lost-sector.component.html | 2 +- .../legendary-lost-sector.component.ts | 3 +- .../uber-list-builder.component.html | 8 +-- .../uber-list-view.component.html | 8 +-- .../vendors-container.component.html | 2 +- 82 files changed, 251 insertions(+), 256 deletions(-) diff --git a/docs/modernization-plan.md b/docs/modernization-plan.md index 7df1e3d7a..511e04fa3 100644 --- a/docs/modernization-plan.md +++ b/docs/modernization-plan.md @@ -142,7 +142,14 @@ Angular migrations must go one major version at a time: - Replaced `takeUntil(this.unsubscribe$)` with `takeUntilDestroyed(this.destroyRef)` in 40+ components - Removed `unsubscribe$` from 7 root services (singletons never destroy) - Deleted unused `StreamingChildComponent` -- [ ] Adopt Angular signals where beneficial +- [x] Adopt Angular signals where beneficial + - Converted `AppStateService` BehaviorSubjects to `WritableSignal` (disableAds, debugmode, favoritesList$, favoritesMap, hiddenMilestones, hiddenClanMilestones) + - Converted `ChildComponent.loading` to `signal(false)` + - Converted service-level `loading` BehaviorSubjects to signals (StreamingService, GearService, ClanStateService, FriendStarComponent, PerkbenchComponent, DimSyncService, MarkService) + - Updated 54 templates: replaced `field | async` with `field()` signal reads + - Replaced `.next()` with `.set()` and `.getValue()` with `()` across 24 TS files + - Removed `AsyncPipe` import from 11 components that no longer use it + - Converted `FriendsComponent.members` to signal, used `effect()` for reactive state - [x] Evaluate esbuild-based builder (`@angular-devkit/build-angular:application`) - Switched from webpack `browser` builder to esbuild `application` builder - Replaced `require()` with ESM `import` for package.json in environment files diff --git a/package.json b/package.json index 40228d22c..d2241bf42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "d2-checklist", - "version": "29.3.0", + "version": "29.4.0", "manifest": "242999.26.03.25.2000-1-bnet.64463", "license": "MIT", "scripts": { diff --git a/src/app/auth/auth/auth.component.html b/src/app/auth/auth/auth.component.html index 8ffda813e..9d3fcc5fa 100644 --- a/src/app/auth/auth/auth.component.html +++ b/src/app/auth/auth/auth.component.html @@ -1,6 +1,6 @@
- +

{{statusMsg}}

diff --git a/src/app/auth/auth/auth.component.ts b/src/app/auth/auth/auth.component.ts index ddcb97fea..633524c80 100644 --- a/src/app/auth/auth/auth.component.ts +++ b/src/app/auth/auth/auth.component.ts @@ -5,7 +5,7 @@ import { takeUntil } from 'rxjs/operators'; import { AuthService } from '../../service/auth.service'; import { ChildComponent } from '../../shared/child.component'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { NgIf, AsyncPipe } from '@angular/common'; +import { NgIf } from '@angular/common'; import { MatProgressSpinner } from '@angular/material/progress-spinner'; @@ -15,7 +15,7 @@ import { MatProgressSpinner } from '@angular/material/progress-spinner'; templateUrl: './auth.component.html', styleUrls: ['./auth.component.scss'], standalone: true, - imports: [NgIf, MatProgressSpinner, AsyncPipe] + imports: [NgIf, MatProgressSpinner] }) export class AuthComponent extends ChildComponent implements OnInit { statusMsg = 'Authorizing'; diff --git a/src/app/bungie-search/bungie-search/bungie-search.component.html b/src/app/bungie-search/bungie-search/bungie-search.component.html index 8794727b0..19626156b 100644 --- a/src/app/bungie-search/bungie-search/bungie-search.component.html +++ b/src/app/bungie-search/bungie-search/bungie-search.component.html @@ -1,5 +1,5 @@
- +

Search Bungie

Wild-card search Bungie accounts by name. Note that sometimes these are diff --git a/src/app/bungie-search/bungie-search/bungie-search.component.ts b/src/app/bungie-search/bungie-search/bungie-search.component.ts index 0fac13cd1..eba920c98 100644 --- a/src/app/bungie-search/bungie-search/bungie-search.component.ts +++ b/src/app/bungie-search/bungie-search/bungie-search.component.ts @@ -40,13 +40,13 @@ export class BungieSearchComponent extends ChildComponent implements OnInit { } public async loadClan(member: BungieGlobalSearchResult) { - this.loading.next(true); + this.loading.set(true); try { const x = await this.bungieService.getClans(member.bungieNetMembershipId!); member.clans = x; } finally { - this.loading.next(false); + this.loading.set(false); } this.ref.markForCheck(); @@ -65,13 +65,13 @@ export class BungieSearchComponent extends ChildComponent implements OnInit { private async load() { console.log('loading'); - this.loading.next(true); + this.loading.set(true); try { const x: BungieGlobalSearchResult[] = await this.bungieService.searchBungieUsers(this.name); this.rows$.next(x); } finally { - this.loading.next(false); + this.loading.set(false); } } diff --git a/src/app/clan-search/clan-search/clan-search.component.html b/src/app/clan-search/clan-search/clan-search.component.html index cc6639322..782f8cbbd 100644 --- a/src/app/clan-search/clan-search/clan-search.component.html +++ b/src/app/clan-search/clan-search/clan-search.component.html @@ -1,5 +1,5 @@
- +

Clan Search

Clan names must match exactly. diff --git a/src/app/clan-search/clan-search/clan-search.component.ts b/src/app/clan-search/clan-search/clan-search.component.ts index f41e912cd..aa62b7c16 100644 --- a/src/app/clan-search/clan-search/clan-search.component.ts +++ b/src/app/clan-search/clan-search/clan-search.component.ts @@ -35,7 +35,7 @@ export class ClanSearchComponent extends ChildComponent implements OnInit { } private async load() { - this.loading.next(true); + this.loading.set(true); try { const x = await this.bungieService.searchClans(this.name); this.clan.next(x); @@ -44,7 +44,7 @@ export class ClanSearchComponent extends ChildComponent implements OnInit { this.clan = null!; } finally { - this.loading.next(false); + this.loading.set(false); } } diff --git a/src/app/clan/clan-collections/clan-badges/clan-badges.component.html b/src/app/clan/clan-collections/clan-badges/clan-badges.component.html index 824903636..f8f96cba7 100644 --- a/src/app/clan/clan-collections/clan-badges/clan-badges.component.html +++ b/src/app/clan/clan-collections/clan-badges/clan-badges.component.html @@ -8,7 +8,7 @@
{{badge.data.name}} - {{badge.data.hash}} + {{badge.data.hash}}
diff --git a/src/app/clan/clan-collections/clan-collection-item/clan-collection-item.component.ts b/src/app/clan/clan-collections/clan-collection-item/clan-collection-item.component.ts index 801377116..5fa18bb30 100644 --- a/src/app/clan/clan-collections/clan-collection-item/clan-collection-item.component.ts +++ b/src/app/clan/clan-collections/clan-collection-item/clan-collection-item.component.ts @@ -3,7 +3,7 @@ import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; import { ClanSearchableCollection, ClanStateService } from '@app/clan/clan-state.service'; import { ChildComponent } from '@app/shared/child.component'; import { ClanCollectionItemDialogComponent } from '../clan-collection-item-dialog/clan-collection-item-dialog.component'; -import { NgIf, AsyncPipe } from '@angular/common'; +import { NgIf } from '@angular/common'; import { MatButton } from '@angular/material/button'; import { MatProgressBar } from '@angular/material/progress-bar'; @@ -14,7 +14,7 @@ import { MatProgressBar } from '@angular/material/progress-bar'; templateUrl: './clan-collection-item.component.html', styleUrls: ['./clan-collection-item.component.scss'], standalone: true, - imports: [NgIf, MatButton, MatProgressBar, AsyncPipe] + imports: [NgIf, MatButton, MatProgressBar] }) export class ClanCollectionItemComponent extends ChildComponent { diff --git a/src/app/clan/clan-lifetime/clan-lifetime.component.html b/src/app/clan/clan-lifetime/clan-lifetime.component.html index 850f9b3d1..bf5fc77b6 100644 --- a/src/app/clan/clan-lifetime/clan-lifetime.component.html +++ b/src/app/clan/clan-lifetime/clan-lifetime.component.html @@ -4,7 +4,7 @@

- +
diff --git a/src/app/clan/clan-members/clan-members.component.html b/src/app/clan/clan-members/clan-members.component.html index 69f954183..5f4516e25 100644 --- a/src/app/clan/clan-members/clan-members.component.html +++ b/src/app/clan/clan-members/clan-members.component.html @@ -14,7 +14,7 @@

{{member.destinyUserInfo.displayName}} {{member.destinyUserInfo.platformName}} - + diff --git a/src/app/clan/clan-milestones/clan-milestones.component.html b/src/app/clan/clan-milestones/clan-milestones.component.html index 80534fc11..5ed45bfee 100644 --- a/src/app/clan/clan-milestones/clan-milestones.component.html +++ b/src/app/clan/clan-milestones/clan-milestones.component.html @@ -1,11 +1,11 @@
-
@@ -28,10 +28,10 @@ - + {{mileStoneName.name}} - {{mileStoneName.key}} + {{mileStoneName.key}} @@ -48,7 +48,7 @@ {{member.destinyUserInfo.displayName}} {{member.destinyUserInfo.platformName}} - + @@ -70,7 +70,7 @@ - @@ -83,7 +83,7 @@ - ... + ... @@ -99,10 +99,10 @@ - + {{mileStoneName.name}} - {{mileStoneName.key}} + {{mileStoneName.key}} @@ -149,11 +149,11 @@

diff --git a/src/app/clan/clan-state.service.ts b/src/app/clan/clan-state.service.ts index 1c259d576..71e97a122 100644 --- a/src/app/clan/clan-state.service.ts +++ b/src/app/clan/clan-state.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, signal} from '@angular/core'; import { Router } from '@angular/router'; import { BungieService } from '@app/service/bungie.service'; import { Sort } from '@app/service/model'; @@ -99,7 +99,7 @@ export interface ClanSearchableCollection extends ClanAggregate { providedIn: 'root' }) export class ClanStateService { - public loading: BehaviorSubject = new BehaviorSubject(false); + public loading = signal(false); public notFound: BehaviorSubject = new BehaviorSubject(false); public inactiveMembers: BungieGroupMember[] = []; public defunctMembers: BungieGroupMember[] = []; @@ -705,7 +705,7 @@ export class ClanStateService { this.aggHistoryAllLoaded.next(false); this.aggHistory.next([]); this.notFound.next(false); - this.loading.next(true); + this.loading.set(true); this.members = []; this.defunctMembers = []; @@ -753,7 +753,7 @@ export class ClanStateService { this.sortData(); const operateOnMe = this.sortedMembers.getValue(); console.log(`Active ${operateOnMe.length} / ${functMembers.length}`); - this.loading.next(false); + this.loading.set(false); for (const t of operateOnMe) { if (this.modelPlayer.getValue() == null) { await this.loadSpecificPlayer(t, false); @@ -762,7 +762,7 @@ export class ClanStateService { } } } catch (x) { - this.loading.next(false); + this.loading.set(false); } } diff --git a/src/app/clan/clan-triumphs/clan-seals/clan-seals.component.html b/src/app/clan/clan-triumphs/clan-seals/clan-seals.component.html index ae1ae9329..417e81f11 100644 --- a/src/app/clan/clan-triumphs/clan-seals/clan-seals.component.html +++ b/src/app/clan/clan-triumphs/clan-seals/clan-seals.component.html @@ -7,7 +7,7 @@
{{s.data.title}} - {{s.data.hash}} + {{s.data.hash}}

diff --git a/src/app/deals/weapon-compare-dialog/weapon-compare-dialog.component.html b/src/app/deals/weapon-compare-dialog/weapon-compare-dialog.component.html index cdbdd0aca..e27992379 100644 --- a/src/app/deals/weapon-compare-dialog/weapon-compare-dialog.component.html +++ b/src/app/deals/weapon-compare-dialog/weapon-compare-dialog.component.html @@ -105,7 +105,7 @@

{{title}}

- + diff --git a/src/app/friends/friends/friends.component.html b/src/app/friends/friends/friends.component.html index 81c5ce702..87b9ec108 100644 --- a/src/app/friends/friends/friends.component.html +++ b/src/app/friends/friends/friends.component.html @@ -10,16 +10,16 @@

Friends

Refresh - Show Hidden + Show Hidden Milestones
+ *ngIf="loading()===true || (modelPlayer==null && members()!.length>0)">
- +
- + + diff --git a/src/app/friends/friends/friends.component.ts b/src/app/friends/friends/friends.component.ts index d23a71be8..eb181b1c1 100644 --- a/src/app/friends/friends/friends.component.ts +++ b/src/app/friends/friends/friends.component.ts @@ -1,16 +1,13 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, effect, signal } from '@angular/core'; import { Router, RouterLink } from '@angular/router'; import { BungieService } from '@app/service/bungie.service'; import { IconService } from '@app/service/icon.service'; import { FriendListEntry, Player, UserInfo } from '@app/service/model'; -import { BehaviorSubject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; import { StorageService } from '../../service/storage.service'; import { ChildComponent } from '../../shared/child.component'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { MatAnchor } from '@angular/material/button'; -import { NgIf, NgFor, AsyncPipe, DecimalPipe } from '@angular/common'; +import { NgIf, NgFor, DecimalPipe, AsyncPipe } from '@angular/common'; import { MatProgressSpinner } from '@angular/material/progress-spinner'; import { MatTooltip } from '@angular/material/tooltip'; import { MilestoneCheckComponent } from '../../shared/milestone-check/milestone-check.component'; @@ -23,10 +20,10 @@ import { AgoHumanizedPipe } from '../../shared/pipe/timing.pipe'; templateUrl: './friends.component.html', styleUrls: ['./friends.component.scss'], standalone: true, - imports: [FaIconComponent, MatAnchor, NgIf, MatProgressSpinner, NgFor, MatTooltip, RouterLink, MilestoneCheckComponent, AgoHumanizedPipe, AsyncPipe, DecimalPipe] + imports: [FaIconComponent, MatAnchor, NgIf, MatProgressSpinner, NgFor, MatTooltip, RouterLink, MilestoneCheckComponent, AgoHumanizedPipe, DecimalPipe, AsyncPipe] }) export class FriendsComponent extends ChildComponent { - public members: BehaviorSubject = new BehaviorSubject([]); + public members = signal([]); modelPlayer!: Player; playerCntr!: 0; @@ -34,19 +31,17 @@ export class FriendsComponent extends ChildComponent { private router: Router, private ref: ChangeDetectorRef) { super(); - this.favoritesList$.pipe( - takeUntilDestroyed(this.destroyRef)) - .subscribe( - (x: UserInfo[]) => { - const members: FriendListEntry[] = []; - for (const f of x) { - const member = new FriendListEntry(); - member.user = f; - members.push(member); - } - this.members.next(members); - this.load(); - }); + effect(() => { + const x = this.favoritesList$(); + const members: FriendListEntry[] = []; + for (const f of x) { + const member = new FriendListEntry(); + member.user = f; + members.push(member); + } + this.members.set(members); + this.load(); + }); } public async loadPlayer(friend: FriendListEntry): Promise { @@ -69,19 +64,19 @@ export class FriendsComponent extends ChildComponent { private async slowlyLoadRest(): Promise { this.ref.markForCheck(); - if (this.playerCntr >= this.members.value.length) { + if (this.playerCntr >= this.members().length) { return; } try { - await this.loadPlayer(this.members.value[this.playerCntr]); + await this.loadPlayer(this.members()[this.playerCntr]); this.playerCntr++; this.slowlyLoadRest(); } catch (err) { console.dir(err); // reloading mid load can break this - if (this.members.value[this.playerCntr] != null) { - console.log('Skipping error on ' + this.members.value[this.playerCntr].user.displayName + ' and continuing'); + if (this.members()[this.playerCntr] != null) { + console.log('Skipping error on ' + this.members()[this.playerCntr].user.displayName + ' and continuing'); this.playerCntr++; this.slowlyLoadRest(); } @@ -98,10 +93,10 @@ export class FriendsComponent extends ChildComponent { public load() { - this.loading.next(true); + this.loading.set(true); this.modelPlayer = null!; this.playerCntr = 0; - for (const m of this.members.value) { + for (const m of this.members()) { m.player$.next(null); m.errorMsg$.next(null); } @@ -109,7 +104,7 @@ export class FriendsComponent extends ChildComponent { this.slowlyLoadRest(); } finally { - this.loading.next(false); + this.loading.set(false); } } diff --git a/src/app/gamer-tag-search/gamer-tag-search.component.html b/src/app/gamer-tag-search/gamer-tag-search.component.html index 4af795cd5..29e3f3507 100644 --- a/src/app/gamer-tag-search/gamer-tag-search.component.html +++ b/src/app/gamer-tag-search/gamer-tag-search.component.html @@ -18,5 +18,5 @@

Search Bungie account names or return home to try again:

- +
\ No newline at end of file diff --git a/src/app/gamer-tag-search/gamer-tag-search.component.ts b/src/app/gamer-tag-search/gamer-tag-search.component.ts index 0c62b0576..cc89d0885 100644 --- a/src/app/gamer-tag-search/gamer-tag-search.component.ts +++ b/src/app/gamer-tag-search/gamer-tag-search.component.ts @@ -35,7 +35,7 @@ export class GamerTagSearchComponent extends ChildComponent implements OnInit { } private async init(params: Params) { - this.loading.next(true); + this.loading.set(true); try { this.errorMsg.next(null); this.progressMsg.next(null); @@ -65,7 +65,7 @@ export class GamerTagSearchComponent extends ChildComponent implements OnInit { } catch (exc) { this.errorMsg.next(exc); } finally { - this.loading.next(false); + this.loading.set(false); } } diff --git a/src/app/gear/gear/gear-compare-dialog/gear-compare-dialog.component.html b/src/app/gear/gear/gear-compare-dialog/gear-compare-dialog.component.html index b93b41754..4597e1a43 100644 --- a/src/app/gear/gear/gear-compare-dialog/gear-compare-dialog.component.html +++ b/src/app/gear/gear/gear-compare-dialog/gear-compare-dialog.component.html @@ -97,7 +97,7 @@ @@ -266,7 +266,7 @@
+ [debugmode]="debugmode()!">
diff --git a/src/app/gear/gear/gear-utilities-dialog/gear-utilities-dialog.component.html b/src/app/gear/gear/gear-utilities-dialog/gear-utilities-dialog.component.html index ee265e815..4fd96c282 100644 --- a/src/app/gear/gear/gear-utilities-dialog/gear-utilities-dialog.component.html +++ b/src/app/gear/gear/gear-utilities-dialog/gear-utilities-dialog.component.html @@ -1,6 +1,6 @@
- +
diff --git a/src/app/gear/gear/gear.component.html b/src/app/gear/gear/gear.component.html index 5e431e0fe..2ca5598e5 100644 --- a/src/app/gear/gear/gear.component.html +++ b/src/app/gear/gear/gear.component.html @@ -1,10 +1,10 @@
- -
- +
@@ -380,14 +380,14 @@ - [{{i.id}} {{i.hash}}] - version {{i.versionNumber}} + [{{i.id}} {{i.hash}}] - version {{i.versionNumber}}
{{owner.label}} - +
@@ -28,9 +28,9 @@

Friends

+ *ngIf="hiddenMilestones()!.indexOf(mileStoneName.key)===-1"> {{mileStoneName.name}} - {{mileStoneName.key}} + {{mileStoneName.key}} @@ -41,7 +41,7 @@

Friends

{{member.user.displayName}} @@ -82,7 +82,7 @@

Friends

*ngIf="player.characters!=null && player.characters.length>0 && player.characters[0].milestones!=null && modelPlayer!=null"> -
Friends - ......
- +
- +
- + Mod Wizard
-

This operates based on your currently equipped inventory. Pick your activity and priority energy, and we'll do the rest. diff --git a/src/app/gear/gear/optimize-gun-perks-dialog/optimize-gun-perks-dialog.component.html b/src/app/gear/gear/optimize-gun-perks-dialog/optimize-gun-perks-dialog.component.html index cd5a8db77..8b148cf33 100644 --- a/src/app/gear/gear/optimize-gun-perks-dialog/optimize-gun-perks-dialog.component.html +++ b/src/app/gear/gear/optimize-gun-perks-dialog/optimize-gun-perks-dialog.component.html @@ -1,11 +1,11 @@

Optimize Gun Perks
-

This will modify the selected perks on all of your guns to choose those preferred by your god rolls.

diff --git a/src/app/gear/gear/select-mod-dialog/select-mod-dialog.component.html b/src/app/gear/gear/select-mod-dialog/select-mod-dialog.component.html index 74814f254..79a24090e 100644 --- a/src/app/gear/gear/select-mod-dialog/select-mod-dialog.component.html +++ b/src/app/gear/gear/select-mod-dialog/select-mod-dialog.component.html @@ -2,7 +2,7 @@
{{item.name}}
-
diff --git a/src/app/gear/gear/select-mod-dialog/select-mod-dialog.component.ts b/src/app/gear/gear/select-mod-dialog/select-mod-dialog.component.ts index 83b80d120..d42818169 100644 --- a/src/app/gear/gear/select-mod-dialog/select-mod-dialog.component.ts +++ b/src/app/gear/gear/select-mod-dialog/select-mod-dialog.component.ts @@ -5,7 +5,7 @@ import { GearService } from '@app/service/gear.service'; import { IconService } from '@app/service/icon.service'; import { InventoryItem, InventorySocket } from '@app/service/model'; import { CdkScrollable } from '@angular/cdk/scrolling'; -import { NgIf, NgFor, AsyncPipe } from '@angular/common'; +import { NgIf, NgFor } from '@angular/common'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { ManifestItemIconComponent } from '../../../shared/manifest-item-icon/manifest-item-icon.component'; @@ -14,7 +14,7 @@ import { ManifestItemIconComponent } from '../../../shared/manifest-item-icon/ma templateUrl: './select-mod-dialog.component.html', styleUrls: ['./select-mod-dialog.component.scss'], standalone: true, - imports: [MatDialogTitle, CdkScrollable, MatDialogContent, NgIf, FaIconComponent, NgFor, ManifestItemIconComponent, AsyncPipe] + imports: [MatDialogTitle, CdkScrollable, MatDialogContent, NgIf, FaIconComponent, NgFor, ManifestItemIconComponent] }) export class SelectModDialogComponent { public item: InventoryItem; diff --git a/src/app/gear/possible-rolls-dialog/possible-rolls-dialog.component.html b/src/app/gear/possible-rolls-dialog/possible-rolls-dialog.component.html index 8813d5b77..7ec6ce608 100644 --- a/src/app/gear/possible-rolls-dialog/possible-rolls-dialog.component.html +++ b/src/app/gear/possible-rolls-dialog/possible-rolls-dialog.component.html @@ -26,7 +26,7 @@ - +

Details

diff --git a/src/app/player/checklist/checklist.component.html b/src/app/player/checklist/checklist.component.html index e26d62f1a..50716b0bb 100644 --- a/src/app/player/checklist/checklist.component.html +++ b/src/app/player/checklist/checklist.component.html @@ -14,7 +14,7 @@

This user has blocked access to this information via their Bungie.net privac -  [{{checklist.hash}}] +  [{{checklist.hash}}] @@ -52,7 +52,7 @@

This user has blocked access to this information via their Bungie.net privac - +  [{{check.hash}}]   @@ -82,7 +82,7 @@

This user has blocked access to this information via their Bungie.net privac {{checklist.name}} -  [{{checklist.hash}}] +  [{{checklist.hash}}] {{t.char.className}} @@ -113,7 +113,7 @@

This user has blocked access to this information via their Bungie.net privac * - +  [{{check.hash}}]   diff --git a/src/app/player/collections/collection-badge/collection-badge.component.html b/src/app/player/collections/collection-badge/collection-badge.component.html index 34d37146f..ef6ff3777 100644 --- a/src/app/player/collections/collection-badge/collection-badge.component.html +++ b/src/app/player/collections/collection-badge/collection-badge.component.html @@ -4,7 +4,7 @@

{{b.name}} - {{b.hash}} + {{b.hash}} @@ -47,13 +47,13 @@

{{t.name}}: {{t.complete}}/{{t.total}}
{{t.name}} - {{t.hash}} + {{t.hash}}
{{p.path}} - {{p.hash}} + {{p.hash}} / diff --git a/src/app/player/collections/collection-badges/collection-badges.component.html b/src/app/player/collections/collection-badges/collection-badges.component.html index f5bd0573f..d2d149972 100644 --- a/src/app/player/collections/collection-badges/collection-badges.component.html +++ b/src/app/player/collections/collection-badges/collection-badges.component.html @@ -12,7 +12,7 @@ {{b.name}} - {{b.hash}} + {{b.hash}}
{{b.bestProgress}}/{{b.total}}
diff --git a/src/app/player/collections/collection-search/collection-search.component.html b/src/app/player/collections/collection-search/collection-search.component.html index 086b9503f..f878b4995 100644 --- a/src/app/player/collections/collection-search/collection-search.component.html +++ b/src/app/player/collections/collection-search/collection-search.component.html @@ -39,13 +39,13 @@

Search

- {{t.hash}} + {{t.hash}}
{{p.path}} - {{p.hash}} + {{p.hash}} / diff --git a/src/app/player/collections/collection-tree/collection-tree.component.html b/src/app/player/collections/collection-tree/collection-tree.component.html index 263335e9b..cb92857b5 100644 --- a/src/app/player/collections/collection-tree/collection-tree.component.html +++ b/src/app/player/collections/collection-tree/collection-tree.component.html @@ -11,7 +11,7 @@
- {{node.data.name}} {{node.data.hash}} + {{node.data.name}} {{node.data.hash}}
{{node.data.sourceString}} @@ -30,7 +30,7 @@ {{node.data.name}} - {{node.data.hash}} + {{node.data.hash}} {{node.data.progress}}/{{node.data.completionValue}} {{node.data.progressDescription}}
diff --git a/src/app/player/lifetime/lifetime.component.html b/src/app/player/lifetime/lifetime.component.html index 647c3cc0e..fb51f4988 100644 --- a/src/app/player/lifetime/lifetime.component.html +++ b/src/app/player/lifetime/lifetime.component.html @@ -53,7 +53,7 @@

{{a.name}} -
+
[{{a.hash}}]
diff --git a/src/app/player/milestones/milestones.component.html b/src/app/player/milestones/milestones.component.html index 7ff7eea25..f9898cee5 100644 --- a/src/app/player/milestones/milestones.component.html +++ b/src/app/player/milestones/milestones.component.html @@ -16,7 +16,7 @@

This user has blocked access to this information via their Bungie.net privac

-
+
Show hidden milestones
@@ -34,7 +34,7 @@

This user has blocked access to this information via their Bungie.net privac - Restore Hidden

- + + *ngIf="player.characters.length>=1 && player.characters[0].clanMilestones!=null && hiddenMilestones()!.indexOf('1')===-1"> - + diff --git a/src/app/player/triumphs/triumph-seasons/triumph-seasons.component.html b/src/app/player/triumphs/triumph-seasons/triumph-seasons.component.html index 6b51cb149..ce2d65844 100644 --- a/src/app/player/triumphs/triumph-seasons/triumph-seasons.component.html +++ b/src/app/player/triumphs/triumph-seasons/triumph-seasons.component.html @@ -27,7 +27,7 @@

Seasonal Challenges

diff --git a/src/app/uber-list/uber-list-view/uber-list-view.component.html b/src/app/uber-list/uber-list-view/uber-list-view.component.html index e07a202ac..bd237f3c3 100644 --- a/src/app/uber-list/uber-list-view/uber-list-view.component.html +++ b/src/app/uber-list/uber-list-view/uber-list-view.component.html @@ -78,7 +78,7 @@ diff --git a/src/app/vendors/vendors-container/vendors-container.component.html b/src/app/vendors/vendors-container/vendors-container.component.html index b3ed32e89..653cadf8d 100644 --- a/src/app/vendors/vendors-container/vendors-container.component.html +++ b/src/app/vendors/vendors-container/vendors-container.component.html @@ -8,7 +8,7 @@ Date: Sun, 5 Apr 2026 21:37:26 -0400 Subject: [PATCH 2/2] Bump package lock --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2883c7296..2491ba8a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "d2-checklist", - "version": "29.3.0", + "version": "29.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "d2-checklist", - "version": "29.3.0", + "version": "29.4.0", "license": "MIT", "dependencies": { "@angular/animations": "^18.2.14",
- + * diff --git a/src/app/gear/possible-rolls-dialog/possible-rolls-dialog.component.ts b/src/app/gear/possible-rolls-dialog/possible-rolls-dialog.component.ts index ba52a03d1..9d65be551 100644 --- a/src/app/gear/possible-rolls-dialog/possible-rolls-dialog.component.ts +++ b/src/app/gear/possible-rolls-dialog/possible-rolls-dialog.component.ts @@ -5,7 +5,7 @@ import { InventoryItem } from '@app/service/model'; import { NotificationService } from '@app/service/notification.service'; import { ClipboardService } from 'ngx-clipboard'; import { GearComponent } from '../gear/gear.component'; -import { NgIf, NgFor, AsyncPipe } from '@angular/common'; +import { NgIf, NgFor } from '@angular/common'; import { CdkScrollable } from '@angular/cdk/scrolling'; import { GodRollPlugComponent } from '../god-roll-plug/god-roll-plug.component'; @@ -15,7 +15,7 @@ import { GodRollPlugComponent } from '../god-roll-plug/god-roll-plug.component'; templateUrl: './possible-rolls-dialog.component.html', styleUrls: ['../gear/gear.component.scss'], standalone: true, - imports: [MatDialogTitle, NgIf, CdkScrollable, MatDialogContent, NgFor, GodRollPlugComponent, AsyncPipe] + imports: [MatDialogTitle, NgIf, CdkScrollable, MatDialogContent, NgFor, GodRollPlugComponent] }) export class PossibleRollsDialogComponent { diff --git a/src/app/gear/writable-sockets/writable-sockets.component.html b/src/app/gear/writable-sockets/writable-sockets.component.html index 6a9bbf8bf..8b56a8591 100644 --- a/src/app/gear/writable-sockets/writable-sockets.component.html +++ b/src/app/gear/writable-sockets/writable-sockets.component.html @@ -1,5 +1,5 @@ -
Socket Cat: {{socket.socketCategoryHash}} +
Socket Cat: {{socket.socketCategoryHash}}
@@ -7,7 +7,7 @@
@@ -53,13 +53,13 @@

This user has blocked access to this information via their Bungie.net privac matTooltip="Stop hiding milestones that this char has completed"> -
{{char.characterId}}
+
{{char.characterId}}

@@ -68,7 +68,7 @@

This user has blocked access to this information via their Bungie.net privac - {{mileStoneName.key}} + {{mileStoneName.key}}

diff --git a/src/app/player/milestones/milestones.component.ts b/src/app/player/milestones/milestones.component.ts index d615dfd1e..cb7843ed2 100644 --- a/src/app/player/milestones/milestones.component.ts +++ b/src/app/player/milestones/milestones.component.ts @@ -37,7 +37,7 @@ export class MilestonesComponent extends ChildComponent implements OnInit { ngOnInit() { this.state.player.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((p: Player) => { - if (this.debugmode.getValue()) { + if (this.debugmode()) { console.log('new player'); } }); diff --git a/src/app/player/player.component.html b/src/app/player/player.component.html index af55a18e1..ea358279f 100644 --- a/src/app/player/player.component.html +++ b/src/app/player/player.component.html @@ -18,7 +18,7 @@

{{player.profile.userInfo.displayName}} - +

{{faction.name}} Level {{faction.level}} - {{faction.hash}} + {{faction.hash}} {{faction.title}} diff --git a/src/app/player/pursuits/pursuit-list/pursuit-list.component.html b/src/app/player/pursuits/pursuit-list/pursuit-list.component.html index 3b05fb1d4..1b2142431 100644 --- a/src/app/player/pursuits/pursuit-list/pursuit-list.component.html +++ b/src/app/player/pursuits/pursuit-list/pursuit-list.component.html @@ -95,7 +95,7 @@ --> -  [{{g.hash}}] +  [{{g.hash}}]
{{i+1}}. {{step.name}}
{{step.desc}} {{step.hash}}
{{i+1}}. {{step.name}}
{{step.desc}} {{step.hash}}
diff --git a/src/app/player/pursuits/pursuit-list/quest-dialog/quest-dialog.component.ts b/src/app/player/pursuits/pursuit-list/quest-dialog/quest-dialog.component.ts index 3b54fb001..d3f7ffe8e 100644 --- a/src/app/player/pursuits/pursuit-list/quest-dialog/quest-dialog.component.ts +++ b/src/app/player/pursuits/pursuit-list/quest-dialog/quest-dialog.component.ts @@ -3,7 +3,7 @@ import { MatDialogRef, MAT_DIALOG_DATA as MAT_DIALOG_DATA, MatDialogTitle, MatDi import { Questline } from '@app/service/model'; import { ChildComponent } from '@app/shared/child.component'; import { CdkScrollable } from '@angular/cdk/scrolling'; -import { NgFor, NgIf, AsyncPipe } from '@angular/common'; +import { NgFor, NgIf } from '@angular/common'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -11,7 +11,7 @@ import { NgFor, NgIf, AsyncPipe } from '@angular/common'; templateUrl: './quest-dialog.component.html', styleUrls: ['./quest-dialog.component.scss'], standalone: true, - imports: [MatDialogTitle, CdkScrollable, MatDialogContent, NgFor, NgIf, AsyncPipe] + imports: [MatDialogTitle, CdkScrollable, MatDialogContent, NgFor, NgIf] }) export class QuestDialogComponent extends ChildComponent { diff --git a/src/app/player/triumphs/special-triumph-list/special-triumph-list.component.html b/src/app/player/triumphs/special-triumph-list/special-triumph-list.component.html index 7ec00a514..72f9641d7 100644 --- a/src/app/player/triumphs/special-triumph-list/special-triumph-list.component.html +++ b/src/app/player/triumphs/special-triumph-list/special-triumph-list.component.html @@ -72,7 +72,7 @@

{{title$|async}}

- diff --git a/src/app/player/triumphs/triumph-closest/triumph-closest.component.html b/src/app/player/triumphs/triumph-closest/triumph-closest.component.html index a984bb9f3..d545990af 100644 --- a/src/app/player/triumphs/triumph-closest/triumph-closest.component.html +++ b/src/app/player/triumphs/triumph-closest/triumph-closest.component.html @@ -25,7 +25,7 @@

- + {{t.percent}}% diff --git a/src/app/player/triumphs/triumph-seals/triumph-seals.component.html b/src/app/player/triumphs/triumph-seals/triumph-seals.component.html index 5d7a70e9f..9b0886179 100644 --- a/src/app/player/triumphs/triumph-seals/triumph-seals.component.html +++ b/src/app/player/triumphs/triumph-seals/triumph-seals.component.html @@ -12,7 +12,7 @@

Seals
{{s.title}} - {{s.hash}} + {{s.hash}} {{s.progress}} / {{s.completionValue}} @@ -45,7 +45,7 @@

Seals - {{c.hash}} + {{c.hash}} diff --git a/src/app/player/triumphs/triumph-search/triumph-search.component.html b/src/app/player/triumphs/triumph-search/triumph-search.component.html index 172b25fe2..d6e29653b 100644 --- a/src/app/player/triumphs/triumph-search/triumph-search.component.html +++ b/src/app/player/triumphs/triumph-search/triumph-search.component.html @@ -29,7 +29,7 @@

- + - + {{t.percent}}% diff --git a/src/app/player/triumphs/triumph-tracked/triumph-tracked.component.html b/src/app/player/triumphs/triumph-tracked/triumph-tracked.component.html index 1d1274ce9..7d1347418 100644 --- a/src/app/player/triumphs/triumph-tracked/triumph-tracked.component.html +++ b/src/app/player/triumphs/triumph-tracked/triumph-tracked.component.html @@ -13,7 +13,7 @@

Tracked Triumphs

- + {{t.percent}}% diff --git a/src/app/player/triumphs/triumph-tree/triumph-tree.component.html b/src/app/player/triumphs/triumph-tree/triumph-tree.component.html index a50d3ea97..ccb2f2f42 100644 --- a/src/app/player/triumphs/triumph-tree/triumph-tree.component.html +++ b/src/app/player/triumphs/triumph-tree/triumph-tree.component.html @@ -55,7 +55,7 @@

Triumphs - Score: {{player.triumphScore|number : '2.0- - {{node.data.hash}} + {{node.data.hash}} Triumphs - Score: {{player.triumphScore|number : '2.0- - {{node.data.name}} {{node.data.hash}} + {{node.data.name}} {{node.data.hash}} {{node.data.progress}}/{{node.data.completionValue}} {{node.data.pts|number}} / {{node.data.totalPts|number}} diff --git a/src/app/recent-players/recent-players/recent-players.component.html b/src/app/recent-players/recent-players/recent-players.component.html index 393beaf97..df3c62645 100644 --- a/src/app/recent-players/recent-players/recent-players.component.html +++ b/src/app/recent-players/recent-players/recent-players.component.html @@ -1,5 +1,5 @@
- +

Recent Teammates - @@ -62,7 +62,7 @@

Recent Teammates -

{{friend.user.displayName}} - +
Clan: {{clan.name}} diff --git a/src/app/recent-players/recent-players/recent-players.component.ts b/src/app/recent-players/recent-players/recent-players.component.ts index d42f82b2d..97cb7d2a7 100644 --- a/src/app/recent-players/recent-players/recent-players.component.ts +++ b/src/app/recent-players/recent-players/recent-players.component.ts @@ -8,7 +8,7 @@ import { BungieService } from '../../service/bungie.service'; import { Activity, ActivityMode, Const, Player, UserInfo } from '../../service/model'; import { ChildComponent } from '../../shared/child.component'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { NgIf, NgFor, AsyncPipe, DatePipe } from '@angular/common'; +import { NgIf, NgFor, DatePipe } from '@angular/common'; import { MatProgressSpinner } from '@angular/material/progress-spinner'; import { MatAnchor, MatButton } from '@angular/material/button'; import { MatFormField } from '@angular/material/form-field'; @@ -25,7 +25,7 @@ import { FriendStarComponent } from '../../shared/friend-star/friend-star.compon templateUrl: './recent-players.component.html', styleUrls: ['./recent-players.component.scss'], standalone: true, - imports: [NgIf, MatProgressSpinner, RouterLink, NgFor, MatAnchor, MatFormField, MatSelect, FormsModule, MatOption, MatButton, MatIcon, FaIconComponent, FriendStarComponent, AsyncPipe, DatePipe] + imports: [NgIf, MatProgressSpinner, RouterLink, NgFor, MatAnchor, MatFormField, MatSelect, FormsModule, MatOption, MatButton, MatIcon, FaIconComponent, FriendStarComponent, DatePipe] }) export class RecentPlayersComponent extends ChildComponent implements OnInit { activityModes: ActivityMode[]; @@ -61,7 +61,7 @@ export class RecentPlayersComponent extends ChildComponent implements OnInit { } public async history() { - this.loading.next(true); + this.loading.set(true); try { const r = await this.bungieService.getActivityHistory(this.membershipType, this.membershipId, this.characterId, this.selectedMode.type, this.selectedMaxResults); @@ -77,7 +77,7 @@ export class RecentPlayersComponent extends ChildComponent implements OnInit { this.loadNextRow(); } finally { - this.loading.next(false); + this.loading.set(false); } } diff --git a/src/app/service/app-state.service.ts b/src/app/service/app-state.service.ts index d261cb4b0..facff84f4 100644 --- a/src/app/service/app-state.service.ts +++ b/src/app/service/app-state.service.ts @@ -1,40 +1,39 @@ -import { Injectable } from '@angular/core'; +import { Injectable, signal, WritableSignal } from '@angular/core'; import { UserInfo } from '@app/service/model'; -import { BehaviorSubject } from 'rxjs'; import { StorageService } from './storage.service'; @Injectable({ providedIn: 'root' }) export class AppStateService { - public disableAds = new BehaviorSubject(false); - public debugmode = new BehaviorSubject(false); - public favoritesList$ = new BehaviorSubject([]); - public favoritesMap = new BehaviorSubject<{ [id: string]: UserInfo }>({}); - public hiddenMilestones = new BehaviorSubject([]); - public hiddenClanMilestones = new BehaviorSubject([]); + public disableAds: WritableSignal = signal(false); + public debugmode: WritableSignal = signal(false); + public favoritesList$: WritableSignal = signal([]); + public favoritesMap: WritableSignal<{ [id: string]: UserInfo }> = signal({}); + public hiddenMilestones: WritableSignal = signal([]); + public hiddenClanMilestones: WritableSignal = signal([]); constructor(private storageService: StorageService) { - this.disableAds.next(this.storageService.getItem('disableads', false)); - this.debugmode.next(this.storageService.getItem('debugmode', false)); + this.disableAds.set(this.storageService.getItem('disableads', false)); + this.debugmode.set(this.storageService.getItem('debugmode', false)); this.storageService.settingFeed.subscribe(x => { if (x.disableads != null) { - this.disableAds.next(x.disableads); + this.disableAds.set(x.disableads); } if (x.debugmode != null) { - this.debugmode.next(x.debugmode); + this.debugmode.set(x.debugmode); } if (x.friends != null) { - this.favoritesMap.next(x.friends); + this.favoritesMap.set(x.friends); const aFavs: UserInfo[] = []; for (const key of Object.keys(x.friends)) { aFavs.push(x.friends[key]); } - this.favoritesList$.next(aFavs); + this.favoritesList$.set(aFavs); } if (x.hiddenmilestones != null) { - this.hiddenMilestones.next(x.hiddenmilestones); + this.hiddenMilestones.set(x.hiddenmilestones); } if (x.hiddenClanMilestones != null) { - this.hiddenClanMilestones.next(x.hiddenClanMilestones); + this.hiddenClanMilestones.set(x.hiddenClanMilestones); } }); } diff --git a/src/app/service/dim-sync.service.ts b/src/app/service/dim-sync.service.ts index 80428bb7f..c41b4fcc4 100644 --- a/src/app/service/dim-sync.service.ts +++ b/src/app/service/dim-sync.service.ts @@ -1,5 +1,5 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { Injectable, signal} from '@angular/core'; import { AuthTokenRequest, AuthTokenResponse, @@ -9,7 +9,7 @@ import { ProfileUpdateRequest, ProfileUpdateResponse } from '@destinyitemmanager/dim-api-types'; -import { BehaviorSubject, firstValueFrom} from 'rxjs'; +import { firstValueFrom} from 'rxjs'; import { environment } from '../../environments/environment'; import { AuthService } from './auth.service'; import { NotificationService } from './notification.service'; @@ -18,10 +18,9 @@ import { SignedOnUserService } from './signed-on-user.service'; const LOG_CSS = `color: mediumseagreen`; @Injectable({ - providedIn: 'root', -}) + providedIn: 'root' }) export class DimSyncService { - public loading$: BehaviorSubject = new BehaviorSubject(false); + public loading$ = signal(false); constructor( private httpClient: HttpClient, @@ -64,8 +63,7 @@ export class DimSyncService { } const req: AuthTokenRequest = { bungieAccessToken: await this.authService.getKey(), - membershipId: selectedUser.membership.bungieId, - }; + membershipId: selectedUser.membership.bungieId }; const headers = new HttpHeaders().set( 'X-API-Key', @@ -110,9 +108,8 @@ export class DimSyncService { const body: ProfileUpdateRequest = { platformMembershipId: selectedUser!.userInfo.membershipId, destinyVersion: 2, - updates, - }; - this.loading$.next(true); + updates }; + this.loading$.set(true); try { const headers = await this.buildHeaders(); const url = `https://api.destinyitemmanager.com/profile`; @@ -126,13 +123,13 @@ export class DimSyncService { console.dir(x); return false; } finally { - this.loading$.next(false); + this.loading$.set(false); } } async getDimTags(): Promise { const selectedUser = this.signedOnUserService.signedOnUser$.getValue(); - this.loading$.next(true); + this.loading$.set(true); try { console.log('%cGetting DIM tags', LOG_CSS); const headers = await this.buildHeaders(); @@ -146,7 +143,7 @@ export class DimSyncService { console.dir(x); return []; } finally { - this.loading$.next(false); + this.loading$.set(false); } } diff --git a/src/app/service/gear.service.ts b/src/app/service/gear.service.ts index bc3759736..e4050e3c8 100644 --- a/src/app/service/gear.service.ts +++ b/src/app/service/gear.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, signal} from '@angular/core'; import { getHttpErrorMsg, sleep } from '@app/shared/utilities'; import { BehaviorSubject, Observable, Subject } from 'rxjs'; import { debounceTime, tap } from 'rxjs/operators'; @@ -47,7 +47,7 @@ function isGrind(i: InventoryItem): boolean { @Injectable({ providedIn: 'root' }) export class GearService { - public loading: BehaviorSubject = new BehaviorSubject(false); + public loading = signal(false); public _operatingOn$: BehaviorSubject = new BehaviorSubject(null); public operatingOn$: Observable; @@ -220,7 +220,7 @@ export class GearService { public async loadGear(selectedUser: SelectedUser, lastPlayer: Player): Promise { try { - this.loading.next(true); + this.loading.set(true); const player = await this.bungieService.getChars(selectedUser.userInfo.membershipType, selectedUser.userInfo.membershipId, ['Profiles', 'Characters', 'ProfileCurrencies', 'CharacterEquipment', 'CharacterInventories', 'ItemObjectives', @@ -301,7 +301,7 @@ export class GearService { this.preferredStatService.processGear(player); return player; } finally { - this.loading.next(false); + this.loading.set(false); } } @@ -913,7 +913,7 @@ export class GearService { } public async insertFreeSocketForWeaponPerk(item: InventoryItem, socket: InventorySocket, plug: InventoryPlug): Promise { - this.loading.next(true); + this.loading.set(true); try { const success = await this.bungieService.insertFreeSocket(this.signedOnUserService.player$.getValue()!, item, socket, plug.hash); @@ -936,7 +936,7 @@ export class GearService { return false; } finally { - this.loading.next(false); + this.loading.set(false); } } @@ -946,7 +946,7 @@ export class GearService { const newPlug = new InventoryPlug(plug.hash + '', plug.displayProperties.name, plug.displayProperties.description, plug.displayProperties.icon, true, plug.plug?.energyCost, '', true, []); - this.loading.next(true); + this.loading.set(true); try { let success = true; if (!previewOnly) { @@ -970,7 +970,7 @@ export class GearService { return false; } finally { - this.loading.next(false); + this.loading.set(false); } } @@ -1006,7 +1006,7 @@ export class GearService { public async transfer(player: Player, itm: InventoryItem, target: Target, vaultStatus: VaultStatus, progressTracker$?: Subject, tryHard?: boolean): Promise { try { - this.loading.next(true); + this.loading.set(true); // equip something else from our bucket, if we can if (itm.equipped.getValue() == true) { @@ -1136,13 +1136,13 @@ export class GearService { } finally { this.canEquip(itm); - this.loading.next(false); + this.loading.set(false); } } public async setLock(player: Player, itm: InventoryItem, locked: boolean): Promise { try { - this.loading.next(true); + this.loading.set(true); let owner; if (itm.owner.getValue() == player.vault || itm.owner.getValue() == player.shared) { owner = player.characters[0]; @@ -1157,13 +1157,13 @@ export class GearService { return false; } finally { - this.loading.next(false); + this.loading.set(false); } } public async equip(player: Player, itm: InventoryItem): Promise { try { - this.loading.next(true); + this.loading.set(true); const success = await this.bungieService.equip(player.profile.userInfo.membershipType, itm); if (success === true) { const bucket: Bucket = this.bucketService.getBucket(itm.owner.getValue(), itm.inventoryBucket); @@ -1178,7 +1178,7 @@ export class GearService { return false; } finally { - this.loading.next(false); + this.loading.set(false); } } } diff --git a/src/app/service/mark.service.ts b/src/app/service/mark.service.ts index fbe518d78..8c785c04e 100644 --- a/src/app/service/mark.service.ts +++ b/src/app/service/mark.service.ts @@ -1,5 +1,5 @@ import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { Injectable, signal} from '@angular/core'; import { ItemAnnotation, ProfileUpdate, @@ -33,7 +33,7 @@ const LOG_CSS = `color: royalblue`; @Injectable({ providedIn: 'root' }) export class MarkService { // right now we only use this for DIM-sync - public loading$: BehaviorSubject = new BehaviorSubject(false); + public loading$ = signal(false); public currentMarks$: BehaviorSubject = new BehaviorSubject(null); private cleanMarks$: BehaviorSubject = new BehaviorSubject(null); // the original marks loaded from the server // have an observable for dirty that's debounced to once every second that writes updates to server @@ -435,7 +435,7 @@ export class MarkService { } async doInitialDimSync(): Promise { - this.loading$.next(true); + this.loading$.set(true); try { const selectedUser = this.signedOnUserService.signedOnUser$.getValue(); const d2cMarks = await this.load(selectedUser!.userInfo.membershipType, selectedUser!.userInfo.membershipId); @@ -470,7 +470,7 @@ export class MarkService { return true; } finally { - this.loading$.next(false); + this.loading$.set(false); } } diff --git a/src/app/service/streaming.service.ts b/src/app/service/streaming.service.ts index 03c1032a7..b101a25c4 100644 --- a/src/app/service/streaming.service.ts +++ b/src/app/service/streaming.service.ts @@ -1,18 +1,17 @@ import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { Injectable, signal} from '@angular/core'; import { BungieService } from '@app/service/bungie.service'; import { NotificationService } from '@app/service/notification.service'; -import { BehaviorSubject, from, Observable, of } from 'rxjs'; +import { from, Observable, of } from 'rxjs'; import { catchError, concatAll, map, tap } from 'rxjs/operators'; @Injectable({ - providedIn: 'root', -}) + providedIn: 'root' }) export class StreamingService { - public loading: BehaviorSubject = new BehaviorSubject(false); + public loading = signal(false); httpClient: HttpClient; bungieService: BungieService; notificationService: NotificationService; @@ -28,13 +27,13 @@ export class StreamingService { } streamReq(operation: string, url: string): Observable { - this.loading.next(true); + this.loading.set(true); return from(this.bungieService.buildReqOptions()).pipe( map((opt) => this.httpClient.get(url, opt)), concatAll(), map((j) => this.bungieService.parseBungieResponse(j)), catchError(this.handleError(operation, null)), - tap((x) => this.loading.next(false)) + tap((x) => this.loading.set(false)) ); } diff --git a/src/app/settings/settings/settings.component.html b/src/app/settings/settings/settings.component.html index 3826c9956..e6d566a14 100644 --- a/src/app/settings/settings/settings.component.html +++ b/src/app/settings/settings/settings.component.html @@ -17,7 +17,7 @@

Settings

- + {{t.label}} @@ -72,7 +72,7 @@

Settings

Donate
-
+

bug_report You've enabled debug mode. This might do nothing, or it might show extra information diff --git a/src/app/settings/settings/settings.component.ts b/src/app/settings/settings/settings.component.ts index 065465a6f..78ab53e4b 100644 --- a/src/app/settings/settings/settings.component.ts +++ b/src/app/settings/settings/settings.component.ts @@ -11,7 +11,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatFormField } from '@angular/material/form-field'; import { MatSelect } from '@angular/material/select'; import { FormsModule } from '@angular/forms'; -import { NgFor, NgIf, AsyncPipe } from '@angular/common'; +import { NgFor, NgIf } from '@angular/common'; import { MatOption } from '@angular/material/core'; import { MatIcon } from '@angular/material/icon'; import { MatAnchor, MatButton } from '@angular/material/button'; @@ -23,7 +23,7 @@ import { FaIconComponent } from '@fortawesome/angular-fontawesome'; templateUrl: './settings.component.html', styleUrls: ['./settings.component.scss'], standalone: true, - imports: [MatFormField, MatSelect, FormsModule, NgFor, MatOption, NgIf, MatIcon, MatAnchor, FaIconComponent, MatButton, AsyncPipe] + imports: [MatFormField, MatSelect, FormsModule, NgFor, MatOption, NgIf, MatIcon, MatAnchor, FaIconComponent, MatButton] }) export class SettingsComponent extends ChildComponent { diff --git a/src/app/shared/ad-slot/ad-slot.component.html b/src/app/shared/ad-slot/ad-slot.component.html index 013bac23d..64cf6aad7 100644 --- a/src/app/shared/ad-slot/ad-slot.component.html +++ b/src/app/shared/ad-slot/ad-slot.component.html @@ -1,4 +1,4 @@ - + Unknown type, fixme diff --git a/src/app/shared/child.component.ts b/src/app/shared/child.component.ts index b47a2a463..dffb8abcf 100644 --- a/src/app/shared/child.component.ts +++ b/src/app/shared/child.component.ts @@ -1,5 +1,4 @@ -import { Component, DestroyRef, inject } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; +import { Component, DestroyRef, inject, signal } from '@angular/core'; import { AppStateService } from '../service/app-state.service'; import { StorageService } from '../service/storage.service'; @@ -20,7 +19,7 @@ export class ChildComponent { public hiddenMilestones = this.appState.hiddenMilestones; public hiddenClanMilestones = this.appState.hiddenClanMilestones; - public loading = new BehaviorSubject(false); + public loading = signal(false); public dump(dumpMe: any): void { console.log(dumpMe); diff --git a/src/app/shared/friend-star/friend-star.component.html b/src/app/shared/friend-star/friend-star.component.html index b5e987fe8..84bbcf645 100644 --- a/src/app/shared/friend-star/friend-star.component.html +++ b/src/app/shared/friend-star/friend-star.component.html @@ -1,4 +1,4 @@ - + diff --git a/src/app/shared/friend-star/friend-star.component.ts b/src/app/shared/friend-star/friend-star.component.ts index bf31ea16c..ba5fc3818 100644 --- a/src/app/shared/friend-star/friend-star.component.ts +++ b/src/app/shared/friend-star/friend-star.component.ts @@ -1,9 +1,9 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, signal} from '@angular/core'; import { IconService } from '@app/service/icon.service'; import { UserInfo } from '@app/service/model'; import { StorageService } from '@app/service/storage.service'; -import { BehaviorSubject } from 'rxjs'; -import { NgIf, AsyncPipe } from '@angular/common'; +import {} from 'rxjs'; +import { NgIf } from '@angular/common'; import { MatIconButton } from '@angular/material/button'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; @@ -13,10 +13,10 @@ import { FaIconComponent } from '@fortawesome/angular-fontawesome'; templateUrl: './friend-star.component.html', styleUrls: ['./friend-star.component.scss'], standalone: true, - imports: [NgIf, MatIconButton, FaIconComponent, AsyncPipe] + imports: [NgIf, MatIconButton, FaIconComponent] }) export class FriendStarComponent { - public loading: BehaviorSubject = new BehaviorSubject(false); + public loading = signal(false); @Input() title = false; @Input() userInfo!: UserInfo; @@ -28,10 +28,10 @@ export class FriendStarComponent { async toggleFav() { try { - this.loading.next(true); + this.loading.set(true); await this.storageService.toggleFav(this.userInfo, null!); } finally { - this.loading.next(false); + this.loading.set(false); } } } diff --git a/src/app/shared/legendary-lost-sector/legendary-lost-sector.component.html b/src/app/shared/legendary-lost-sector/legendary-lost-sector.component.html index 4dccc18b2..e0262f9e7 100644 --- a/src/app/shared/legendary-lost-sector/legendary-lost-sector.component.html +++ b/src/app/shared/legendary-lost-sector/legendary-lost-sector.component.html @@ -4,7 +4,7 @@ [style.background-image]="'url(//www.bungie.net' + ls.icon + ')'">

{{n.name}} - {{n.hash}} + {{n.hash}}
Location: {{ls.directorLocation}} diff --git a/src/app/shared/legendary-lost-sector/legendary-lost-sector.component.ts b/src/app/shared/legendary-lost-sector/legendary-lost-sector.component.ts index 60a9550fc..c58c1ceea 100644 --- a/src/app/shared/legendary-lost-sector/legendary-lost-sector.component.ts +++ b/src/app/shared/legendary-lost-sector/legendary-lost-sector.component.ts @@ -4,7 +4,7 @@ import { BurnDialogComponent } from '@app/home/burn-dialog/burn-dialog.component import { IconService } from '@app/service/icon.service'; import { LostSector, MilestoneActivity } from '@app/service/model'; import { ChildComponent } from '@app/shared/child.component'; -import { NgIf, NgFor, AsyncPipe } from '@angular/common'; +import { NgIf, NgFor } from '@angular/common'; import { MatListItem, MatListItemIcon, MatListItemLine } from '@angular/material/list'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; @@ -21,7 +21,6 @@ import { FaIconComponent } from '@fortawesome/angular-fontawesome'; MatListItemLine, FaIconComponent, NgFor, - AsyncPipe, ], }) export class LegendaryLostSectorComponent extends ChildComponent { diff --git a/src/app/uber-list/uber-list-builder/uber-list-builder.component.html b/src/app/uber-list/uber-list-builder/uber-list-builder.component.html index 10b76db2a..ea078b99d 100644 --- a/src/app/uber-list/uber-list-builder/uber-list-builder.component.html +++ b/src/app/uber-list/uber-list-builder/uber-list-builder.component.html @@ -101,7 +101,7 @@
Questline: {{q.progress}}
-
{{row.title.hash}} - reward tier{{row.rewardTier}}
+
{{row.title.hash}} - reward tier{{row.rewardTier}}
{{row.classification}}
@@ -113,7 +113,7 @@ - {{r.hash}} + {{r.hash}} @@ -140,7 +140,7 @@
- {{row.title.key}} - reward tier {{row.rewardTier}} + {{row.title.key}} - reward tier {{row.rewardTier}}
{{row.classification}}
@@ -152,7 +152,7 @@ - {{r.hash}} + {{r.hash}}
Questline: {{q.progress}}
-
{{row.title.hash}} - reward tier{{row.rewardTier}}
+
{{row.title.hash}} - reward tier{{row.rewardTier}}
{{row.classification}}
@@ -90,7 +90,7 @@ - {{r.hash}} + {{r.hash}} @@ -113,7 +113,7 @@
- {{row.title.key}} - reward tier {{row.rewardTier}} + {{row.title.key}} - reward tier {{row.rewardTier}}
{{row.classification}}
@@ -125,7 +125,7 @@ - {{r.hash}} + {{r.hash}}