feat(herowars): migrate JSON static imports to HttpClient assets
Replace all TypeScript JSON imports with an HWDataService that loads 6 data files from /assets/files-data/ via HttpClient with shareReplay(1). Update all 9 consumer components to subscribe asynchronously. Remove unused qcm-bpa.json import and dead methods from QcmComponent. Add ADR 0013 documenting the decision.
This commit is contained in:
@@ -14,12 +14,12 @@ import {
|
||||
HWGuildClan,
|
||||
HWMember,
|
||||
} from '@models';
|
||||
|
||||
import guildData from 'src/files-data/hw-guild-data.json'; // page Membres
|
||||
import { HWDataService } from './hw-data.service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class HWClanService {
|
||||
private apiService = inject(ApiService);
|
||||
private _dataService = inject(HWDataService);
|
||||
|
||||
private _apiDomain = '/herowars';
|
||||
|
||||
@@ -87,15 +87,18 @@ export class HWClanService {
|
||||
}
|
||||
}
|
||||
|
||||
loadClan(): HWGuildClan {
|
||||
const guildClan: HWGuildClan = {} as HWGuildClan;
|
||||
Object.assign(guildClan, guildData.clan);
|
||||
guildClan.sumAverages = this._resetActivity();
|
||||
guildClan.sumTotal = this._resetActivity();
|
||||
guildClan.todayAverages = this._resetActivity();
|
||||
guildClan.todayTotal = this._resetActivity();
|
||||
|
||||
return guildClan;
|
||||
loadClan(): Observable<HWGuildClan> {
|
||||
return this._dataService.guildData$.pipe(
|
||||
map((guildData) => {
|
||||
const guildClan: HWGuildClan = {} as HWGuildClan;
|
||||
Object.assign(guildClan, guildData.clan);
|
||||
guildClan.sumAverages = this._resetActivity();
|
||||
guildClan.sumTotal = this._resetActivity();
|
||||
guildClan.todayAverages = this._resetActivity();
|
||||
guildClan.todayTotal = this._resetActivity();
|
||||
return guildClan;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
loadClanStats(clan: HWGuildClan, members: HWMember[]): HWGuildClan {
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { shareReplay } from 'rxjs/operators';
|
||||
|
||||
import { HWGuildData, HWGuildWarSlots, HWWeekStat } from '@models';
|
||||
|
||||
export interface HWGuildStatistics {
|
||||
stat: (HWWeekStat & { id: string })[];
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class HWDataService {
|
||||
private _http = inject(HttpClient);
|
||||
|
||||
readonly guildData$: Observable<HWGuildData> = this._http
|
||||
.get<HWGuildData>('/assets/files-data/hw-guild-data.json')
|
||||
.pipe(shareReplay(1));
|
||||
|
||||
readonly guildStatistics$: Observable<HWGuildStatistics> = this._http
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
.get<HWGuildStatistics>('/assets/files-data/hw-guild-statistics.json')
|
||||
.pipe(shareReplay(1));
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
readonly guildRaids$: Observable<Record<string, Record<string, any>>> = this._http
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
.get<Record<string, Record<string, any>>>('/assets/files-data/hw-guild-raids.json')
|
||||
.pipe(shareReplay(1));
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
readonly guildWarData$: Observable<any> = this._http
|
||||
.get<any>('/assets/files-data/hw-guild-war.json')
|
||||
.pipe(shareReplay(1));
|
||||
|
||||
readonly guildWarInfo$: Observable<any> = this._http
|
||||
.get<any>('/assets/files-data/hw-guild-war-info.json')
|
||||
.pipe(shareReplay(1));
|
||||
/* eslint-enable @typescript-eslint/no-explicit-any */
|
||||
|
||||
readonly guildWarSlots$: Observable<{ slots: HWGuildWarSlots }> = this._http
|
||||
.get<{ slots: HWGuildWarSlots }>('/assets/files-data/hw-guild-war-slots.json')
|
||||
.pipe(shareReplay(1));
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService, UtilitiesService } from '@services';
|
||||
@@ -14,13 +14,12 @@ import {
|
||||
HWMemberPageData,
|
||||
HWMemberStat,
|
||||
} from '@models';
|
||||
|
||||
import guildData from 'src/files-data/hw-guild-data.json'; // page Membres
|
||||
import guildStatistics from 'src/files-data/hw-guild-statistics.json'; // page Overview -> Statistics
|
||||
import { HWDataService } from './hw-data.service';
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class HWMemberService {
|
||||
private _apiService = inject(ApiService);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
private _dataService = inject(HWDataService);
|
||||
|
||||
private _apiDomain = '/herowars';
|
||||
|
||||
@@ -76,83 +75,79 @@ export class HWMemberService {
|
||||
}
|
||||
}
|
||||
|
||||
loadMembers(clan: HWGuildClan): HWMember[] {
|
||||
const guildMembers: HWMember[] = [];
|
||||
const now = new Date();
|
||||
const oneDayInSec = 24 * 60 * 60;
|
||||
const daysToKick = parseInt(guildData.clan.daysToKick);
|
||||
for (const data of Object.entries(guildData.clan.members)) {
|
||||
const member: HWMember = {} as HWMember;
|
||||
Object.assign(member, data[1]);
|
||||
if (guildData.clan.warriors.indexOf(parseInt(member.id)) !== -1) {
|
||||
member.champion = true;
|
||||
} else {
|
||||
member.champion = false;
|
||||
}
|
||||
member.heroes = { power: 0, teams: [] };
|
||||
member.titans = { power: 0, teams: [] };
|
||||
guildMembers.push(member);
|
||||
}
|
||||
guildMembers.map((data: HWMember) => {
|
||||
const last = new Date(parseInt(data.lastLoginTime) * 1000);
|
||||
const exp = new Date(last.getTime() + daysToKick * oneDayInSec * 1000);
|
||||
const diff = Math.floor((exp.getTime() - now.getTime()) / 1000);
|
||||
const daysLeft = Math.floor(diff / oneDayInSec);
|
||||
let timeLeft = diff;
|
||||
if (daysLeft >= 1) {
|
||||
timeLeft = diff - daysLeft * oneDayInSec;
|
||||
}
|
||||
data.inactivity = {
|
||||
daysLeft: daysLeft,
|
||||
timeLeft: timeLeft,
|
||||
dropDelay: `${daysLeft}d, ${this._utilitiesService.secondsToDuration(timeLeft)}`,
|
||||
dropDate: Math.floor(exp.getTime() / 1000),
|
||||
};
|
||||
data.raids = [];
|
||||
data.raidsInfo = {
|
||||
variationAvg: 0,
|
||||
variationSum: 0,
|
||||
};
|
||||
data.stat = {} as HWMemberStat;
|
||||
let index = guildData.membersStat.findIndex((stat) => stat.userId === data.id);
|
||||
if (index !== -1) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
|
||||
const { userId, ...memberStatWithoutUserId } = guildData.membersStat[index] as any;
|
||||
Object.assign(data.stat, memberStatWithoutUserId);
|
||||
}
|
||||
index = guildStatistics.stat.findIndex((stat) => stat.id === data.id);
|
||||
if (index !== -1) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
|
||||
const { id, ...weekStatSource } = guildStatistics.stat[index] as any;
|
||||
const stat: HWWeekStat = {} as HWWeekStat;
|
||||
Object.assign(stat, weekStatSource);
|
||||
data.weekStat = stat;
|
||||
data.adventureSum = guildStatistics.stat[index].adventureStat.reduce(
|
||||
(accumulator, currentValue) => accumulator + currentValue,
|
||||
0,
|
||||
);
|
||||
data.clanGiftsSum = guildStatistics.stat[index].clanGifts.reduce(
|
||||
(accumulator, currentValue) => accumulator + currentValue,
|
||||
0,
|
||||
);
|
||||
data.clanWarSum = guildStatistics.stat[index].clanWarStat.reduce(
|
||||
(accumulator, currentValue) => accumulator + currentValue,
|
||||
0,
|
||||
);
|
||||
} else {
|
||||
data.weekStat = {} as HWWeekStat;
|
||||
data.adventureSum = 0;
|
||||
data.clanGiftsSum = 0;
|
||||
data.clanWarSum = 0;
|
||||
}
|
||||
|
||||
data.score = data.stat.dungeonActivitySum + data.stat.activitySum + data.stat.prestigeSum;
|
||||
data.warGifts = ((clan.giftsCount / 2) * ((data.clanWarSum * 10) / 100)) / 20;
|
||||
data.scoreGifts = 0;
|
||||
data.rewards = 0;
|
||||
return data;
|
||||
});
|
||||
|
||||
return guildMembers;
|
||||
loadMembers(clan: HWGuildClan): Observable<HWMember[]> {
|
||||
return combineLatest([this._dataService.guildData$, this._dataService.guildStatistics$]).pipe(
|
||||
map(([guildData, guildStatistics]) => {
|
||||
const guildMembers: HWMember[] = [];
|
||||
const now = new Date();
|
||||
const oneDayInSec = 24 * 60 * 60;
|
||||
const daysToKick = parseInt(guildData.clan.daysToKick);
|
||||
for (const data of Object.entries(guildData.clan.members)) {
|
||||
const member: HWMember = {} as HWMember;
|
||||
Object.assign(member, data[1]);
|
||||
member.champion = guildData.clan.warriors.indexOf(parseInt(member.id)) !== -1;
|
||||
member.heroes = { power: 0, teams: [] };
|
||||
member.titans = { power: 0, teams: [] };
|
||||
guildMembers.push(member);
|
||||
}
|
||||
guildMembers.map((data: HWMember) => {
|
||||
const last = new Date(parseInt(data.lastLoginTime) * 1000);
|
||||
const exp = new Date(last.getTime() + daysToKick * oneDayInSec * 1000);
|
||||
const diff = Math.floor((exp.getTime() - now.getTime()) / 1000);
|
||||
const daysLeft = Math.floor(diff / oneDayInSec);
|
||||
let timeLeft = diff;
|
||||
if (daysLeft >= 1) {
|
||||
timeLeft = diff - daysLeft * oneDayInSec;
|
||||
}
|
||||
data.inactivity = {
|
||||
daysLeft: daysLeft,
|
||||
timeLeft: timeLeft,
|
||||
dropDelay: `${daysLeft}d, ${this._utilitiesService.secondsToDuration(timeLeft)}`,
|
||||
dropDate: Math.floor(exp.getTime() / 1000),
|
||||
};
|
||||
data.raids = [];
|
||||
data.raidsInfo = { variationAvg: 0, variationSum: 0 };
|
||||
data.stat = {} as HWMemberStat;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let index = guildData.membersStat.findIndex((stat) => (stat as any).userId === data.id);
|
||||
if (index !== -1) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
|
||||
const { userId, ...memberStatWithoutUserId } = guildData.membersStat[index] as any;
|
||||
Object.assign(data.stat, memberStatWithoutUserId);
|
||||
}
|
||||
index = guildStatistics.stat.findIndex((stat) => stat.id === data.id);
|
||||
if (index !== -1) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
|
||||
const { id, ...weekStatSource } = guildStatistics.stat[index] as any;
|
||||
const stat: HWWeekStat = {} as HWWeekStat;
|
||||
Object.assign(stat, weekStatSource);
|
||||
data.weekStat = stat;
|
||||
data.adventureSum = guildStatistics.stat[index].adventureStat.reduce(
|
||||
(acc: number, cur: number) => acc + cur,
|
||||
0,
|
||||
);
|
||||
data.clanGiftsSum = guildStatistics.stat[index].clanGifts.reduce(
|
||||
(acc: number, cur: number) => acc + cur,
|
||||
0,
|
||||
);
|
||||
data.clanWarSum = guildStatistics.stat[index].clanWarStat.reduce(
|
||||
(acc: number, cur: number) => acc + cur,
|
||||
0,
|
||||
);
|
||||
} else {
|
||||
data.weekStat = {} as HWWeekStat;
|
||||
data.adventureSum = 0;
|
||||
data.clanGiftsSum = 0;
|
||||
data.clanWarSum = 0;
|
||||
}
|
||||
data.score = data.stat.dungeonActivitySum + data.stat.activitySum + data.stat.prestigeSum;
|
||||
data.warGifts = ((clan.giftsCount / 2) * ((data.clanWarSum * 10) / 100)) / 20;
|
||||
data.scoreGifts = 0;
|
||||
data.rewards = 0;
|
||||
return data;
|
||||
});
|
||||
return guildMembers;
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
|
||||
export * from './hw-clan.service';
|
||||
export * from './hw-member.service';
|
||||
export * from './hw-data.service';
|
||||
export * from './hw-member.service';
|
||||
|
||||
Reference in New Issue
Block a user