From 81c8488a370f95f16356b4815eba9c658b24b8c2 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 18 Nov 2024 15:58:18 +0000 Subject: [PATCH] - Updates to work with the new strucutre --- src/app/core/models/plan.model.ts | 41 ++---- src/app/core/services/plan.service.ts | 10 +- src/app/core/services/pokemon.service.ts | 58 +++++++- .../plan/plan-game/plan-game.component.ts | 8 +- .../plan-pokemon/plan-pokemon.component.ts | 137 ++++++++++++------ src/app/features/plan/plan.component.ts | 4 +- 6 files changed, 180 insertions(+), 78 deletions(-) diff --git a/src/app/core/models/plan.model.ts b/src/app/core/models/plan.model.ts index 8a6b683..3bb379d 100644 --- a/src/app/core/models/plan.model.ts +++ b/src/app/core/models/plan.model.ts @@ -1,29 +1,14 @@ export interface GamePlan { - game_name: string; - game_id: number; - pokemon: PlanPokemon[]; - } - - export interface PlanPokemon { - pfic: string; - name: string; - form_name?: string; - catch_count: number; - evolve_to: EvolutionTarget[]; - breed_for: BreedingTarget[]; - } - - export interface EvolutionTarget { - pfic: string; - name: string; - form_name?: string; - method: string; - count: number; - } - - export interface BreedingTarget { - pfic: string; - name: string; - form_name?: string; - count: number; - } \ No newline at end of file + game_name: string; + pokemon: Record; +} + +export interface PokemonFamilyEntry { + representative: string; + catch_count: number; + evolve_to: string[]; + breed_for: string[]; + Any?: number; + Male?: number; + Female?: number; +} \ No newline at end of file diff --git a/src/app/core/services/plan.service.ts b/src/app/core/services/plan.service.ts index 7b37f48..5ae8b0b 100644 --- a/src/app/core/services/plan.service.ts +++ b/src/app/core/services/plan.service.ts @@ -30,8 +30,10 @@ export class PlanService { } private recalculateAffectedGames(pfic: string) { + return // This would need to check all games for the affected Pokemon // and update their totals accordingly + /* this.getPlan().pipe(take(1)).subscribe(games => { games.forEach(game => { const affectedPokemon = game.pokemon.find(p => @@ -47,10 +49,16 @@ export class PlanService { } }); }); + */ } private calculateGameTotal(game: GamePlan): number { - return game.pokemon.reduce((total, pokemon) => total + pokemon.catch_count, 0); + var sum = 0; + for(const family in game.pokemon) + { + sum += game.pokemon[family].catch_count; + } + return sum } } \ No newline at end of file diff --git a/src/app/core/services/pokemon.service.ts b/src/app/core/services/pokemon.service.ts index 9e4aa9d..2bfc1f3 100644 --- a/src/app/core/services/pokemon.service.ts +++ b/src/app/core/services/pokemon.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { concatMap, map, Observable, pipe, shareReplay, tap } from 'rxjs'; +import { catchError, concatMap, map, Observable, pipe, shareReplay, tap } from 'rxjs'; import { Pokemon, PokemonEncounter } from '../models/pokemon.model'; import { environment } from '../../../environments/environment.development'; import { comparePfics } from '../utils/pfic-utils'; @@ -165,9 +165,56 @@ export class PokemonService { return this.caughtPokemon.has(pfic); } - getPokemonFromPFIC(pfic:string): Pokemon { - return this.pokemonFormMap.get(pfic) as Pokemon + getPokemonFromPFIC(pfic: string): Observable { + // Check the cache for the PFIC + const cachedPokemon = this.pokemonFormMap.get(pfic); + if (cachedPokemon) { + // Return the cached Pokémon as an Observable + return new Observable((observer) => { + observer.next(cachedPokemon); + observer.complete(); + }); + } + + // If not in cache, fetch from the server + return this.http.get(`${this.apiUrl}/pokemon/${pfic}/details`).pipe( + map(data => { + const pkmn = { + PFIC: data.pfic, + Name: data.data.name, + Form: data.data.form_name, + NationalDex: data.data.national_dex, + Generation: data.data.generation, + StorableInHome: data.data.storable_in_home, + IsBabyForm: data.data.is_baby_form, + Encounters: data.data.encounters || [], + MarkIcon: "", + MarkName: data.data.mark, + Image: "", + IsDefault: data.data.is_default || false, + IsGenderRelevant: data.data.gender_relevant, + IsCaught: this.caughtPokemon.has(data.pfic) + } as Pokemon; + pkmn.MarkIcon = this.getMarkImgName(pkmn.MarkName) + pkmn.Image = this.getPokemonImageUrl(pkmn) + return pkmn; + }), + tap((pokemon) => { + // Cache the result for future requests + this.pokemonFormMap.set(pfic, pokemon); + }), + map((pokemon) => pokemon), // Map the server response directly to the output + shareReplay(1), // Cache the HTTP result for future subscribers + catchError((error): Observable => { + console.error(`Error fetching Pokémon with PFIC ${pfic}:`, error); + return new Observable((observer) => { + observer.next(null); + observer.complete(); + }); + }) + ); } + updateCaughtStatus(pfic: string, caught: boolean) { if (caught) { @@ -177,7 +224,10 @@ export class PokemonService { } } - getPokemonImageUrl(data: Pokemon): string { + getPokemonImageUrl(data: Pokemon | null): string { + if (data === null) { + return ""; + } if (data.IsGenderRelevant) { return `/assets/images/pokemon/${data.PFIC}.png`; } diff --git a/src/app/features/plan/plan-game/plan-game.component.ts b/src/app/features/plan/plan-game/plan-game.component.ts index 1b84538..ba37d20 100644 --- a/src/app/features/plan/plan-game/plan-game.component.ts +++ b/src/app/features/plan/plan-game/plan-game.component.ts @@ -73,7 +73,13 @@ export class PlanGameComponent { @Output() gameSelect = new EventEmitter(); getTotalCatchCount(): number { - return this.game.pokemon.reduce((sum, pokemon) => sum + pokemon.catch_count, 0); + var sum = 0; + for(const family in this.game.pokemon) + { + sum += this.game.pokemon[family].catch_count; + } + return sum + //return this.game.pokemon.values().reduce((sum, pokemon) => sum + pokemon.catch_count, 0); } getGameBoxArt(): string { diff --git a/src/app/features/plan/plan-pokemon/plan-pokemon.component.ts b/src/app/features/plan/plan-pokemon/plan-pokemon.component.ts index 0aad31a..ad0ec91 100644 --- a/src/app/features/plan/plan-pokemon/plan-pokemon.component.ts +++ b/src/app/features/plan/plan-pokemon/plan-pokemon.component.ts @@ -1,12 +1,13 @@ -import { Component, Input, Output, EventEmitter } from '@angular/core'; +import { Component, Input, Output, EventEmitter, ChangeDetectorRef } from '@angular/core'; import { CommonModule } from '@angular/common'; import { MatExpansionModule } from '@angular/material/expansion'; import { MatIconModule } from '@angular/material/icon'; import { MatChipsModule } from '@angular/material/chips'; import { MatTooltipModule } from '@angular/material/tooltip'; -import { PlanPokemon } from '../../../core/models/plan.model'; +import { PokemonFamilyEntry } from '../../../core/models/plan.model'; import { LazyImgDirective } from '../../../shared/directives/lazy-img.directive'; import { PokemonService } from '../../../core/services/pokemon.service'; +import { Pokemon } from '../../../core/models/pokemon.model'; // Define an interface for the status update event interface PokemonStatusEvent { @@ -35,58 +36,58 @@ interface PokemonStatusEvent {
- {{ pokemon.name }} - - ({{ pokemon.form_name }}) + {{ this.representative_pokemon?.Name }} + + ({{ this.representative_pokemon?.Form }})
- {{ pokemon.catch_count }} + {{ pokemon_family.catch_count }}
- +

Evolution Targets

- {{ target.name }} - ({{ target.form_name }}) + {{ target.Name }} + ({{ target.Form }})
- {{ target.method }} - Need: {{ target.count }} + Method _PLACEDHOLDER_ + Need: {{ 1 }}
@@ -94,30 +95,30 @@ interface PokemonStatusEvent {
- +

Breeding Targets

- {{ target.name }} - ({{ target.form_name }}) + {{ target.Name }} + ({{ target.Form }})
Breed - Need: {{ target.count }} + Need: {{ 1 }}
@@ -252,13 +253,61 @@ interface PokemonStatusEvent { `] }) export class PlanPokemonComponent { - @Input() pokemon!: PlanPokemon; + @Input() pokemon_family!: PokemonFamilyEntry; @Output() statusUpdate = new EventEmitter(); - constructor(public pokemonService: PokemonService) {} + representative_pokemon: Pokemon | null = null; + evolve_to: Pokemon[] = []; + breed_for: Pokemon[] = []; + + constructor( + public pokemonService: PokemonService, + private cdr: ChangeDetectorRef + ) {} + + ngOnInit() { + this.pokemonService.getPokemonFromPFIC(this.pokemon_family.representative).subscribe({ + next: (pokemon) => { + this.representative_pokemon = pokemon + }, + error: (error) => { + console.error('Error loading Pokemon:', error); + this.cdr.markForCheck(); + } + }); + + for(const target of this.pokemon_family.evolve_to) { + this.pokemonService.getPokemonFromPFIC(target).subscribe({ + next: (pokemon) => { + if(pokemon) { + this.evolve_to.push(pokemon) + } + }, + error: (error) => { + console.error('Error loading Pokemon:', error); + this.cdr.markForCheck(); + } + }); + } + + for(const target of this.pokemon_family.breed_for) { + this.pokemonService.getPokemonFromPFIC(target).subscribe({ + next: (pokemon) => { + if(pokemon) { + this.breed_for.push(pokemon) + } + }, + error: (error) => { + console.error('Error loading Pokemon:', error); + this.cdr.markForCheck(); + } + }); + } + + } get hasTargets(): boolean { - return this.pokemon.evolve_to.length > 0 || this.pokemon.breed_for.length > 0; + return this.pokemon_family.evolve_to.length > 0 || this.pokemon_family.breed_for.length > 0; } isTargetCompleted(pfic: string): boolean { @@ -271,14 +320,14 @@ export class PlanPokemonComponent { let evolveCount = 0; // Calculate breeding needs - if (this.pokemon.breed_for.length > 0) { + if (this.pokemon_family.breed_for.length > 0) { breedCount = 1; // We only need one for breeding, regardless of how many we breed } // Calculate evolution needs - this.pokemon.evolve_to.forEach(target => { - if (!this.isTargetCompleted(target.pfic)) { - evolveCount += target.count; + this.pokemon_family.evolve_to.forEach(target => { + if (!this.isTargetCompleted(target)) { + evolveCount += 1; } }); @@ -287,23 +336,27 @@ export class PlanPokemonComponent { updateCatchCount() { const newCount = this.calculateTotalNeeded(); - if (newCount !== this.pokemon.catch_count) { - this.pokemon.catch_count = newCount; + if (newCount !== this.pokemon_family.catch_count) { + this.pokemon_family.catch_count = newCount; if (newCount === 0) { // Emit event to move to completed section this.statusUpdate.emit({ - pfic: this.pokemon.pfic, + pfic: this.pokemon_family.representative, caught: true, completed: true }); - } else if (newCount > 0 && this.pokemon.catch_count === 0) { + } else if (newCount > 0 && this.pokemon_family.catch_count === 0) { // Emit event to move back to active section this.statusUpdate.emit({ - pfic: this.pokemon.pfic, + pfic: this.pokemon_family.representative, caught: false, completed: false }); } } } + + getRepresentativePokemon() { + return this.pokemonService.getPokemonFromPFIC(this.pokemon_family.representative) + } } \ No newline at end of file diff --git a/src/app/features/plan/plan.component.ts b/src/app/features/plan/plan.component.ts index dcef26b..b95ade9 100644 --- a/src/app/features/plan/plan.component.ts +++ b/src/app/features/plan/plan.component.ts @@ -36,8 +36,8 @@ import { PlanPokemonComponent } from "./plan-pokemon/plan-pokemon.component";

{{ selectedGame.game_name }} - Pokémon to Catch