diff --git a/src/app/core/models/plan.model.ts b/src/app/core/models/plan.model.ts index 4c2802f..b51bfd6 100644 --- a/src/app/core/models/plan.model.ts +++ b/src/app/core/models/plan.model.ts @@ -7,6 +7,7 @@ export interface PokemonFamilyEntry { family_pfic?: string; representative: string; catch_count: number; + caught_count: number; evolve_to: string[]; breed_for: string[]; Any?: number; diff --git a/src/app/core/services/plan.service.ts b/src/app/core/services/plan.service.ts index 5ae8b0b..447f5d8 100644 --- a/src/app/core/services/plan.service.ts +++ b/src/app/core/services/plan.service.ts @@ -1,55 +1,37 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { Observable, Subject, take } from 'rxjs'; +import { map, Observable, pipe, shareReplay, Subject, take, tap } from 'rxjs'; import { environment } from '../../../environments/environment.development'; -import { GamePlan } from '../models/plan.model'; +import { GamePlan, PokemonFamilyEntry } from '../models/plan.model'; +import { PokemonService } from './pokemon.service'; @Injectable({ providedIn: 'root' }) export class PlanService { - private caughtPokemon = new Set(); private gameUpdates = new Subject<{gameId: number, total: number}>(); gameUpdates$ = this.gameUpdates.asObservable(); - constructor(private http: HttpClient) {} + private gamePlanCache: Observable<(GamePlan[])> | null = null; + private gamePlan: GamePlan[] = []; - getPlan(): Observable { - return this.http.get(`${environment.apiUrl}/plan`); - } + constructor( + private http: HttpClient, + private pokemonService: PokemonService + ) {} - updateCaughtStatus(pfic: string, caught: boolean) { - if (caught) { - this.caughtPokemon.add(pfic); - } else { - this.caughtPokemon.delete(pfic); + getPlan(): Observable { + if (this.gamePlanCache) { + return this.gamePlanCache; } - // Trigger recalculation of affected games - this.recalculateAffectedGames(pfic); - } - - 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 => - p.pfic === pfic || - p.evolve_to.some(e => e.pfic === pfic) || - p.breed_for.some(b => b.pfic === pfic) - ); - if (affectedPokemon) { - this.gameUpdates.next({ - gameId: game.game_id, - total: this.calculateGameTotal(game) - }); - } - }); - }); - */ + this.gamePlanCache = this.http.get(`${environment.apiUrl}/plan`).pipe( + tap(game_plan => { + this.gamePlan = game_plan as GamePlan[]; + }), + shareReplay(1) + ); + return this.gamePlanCache; } private calculateGameTotal(game: GamePlan): number { @@ -61,4 +43,27 @@ export class PlanService { return sum } + updateCaughtCount(family: PokemonFamilyEntry) { + for(const plan of this.gamePlan) { + if(family.family_pfic && family.family_pfic in plan.pokemon) { + let pokemon_family = plan.pokemon[family.family_pfic] + let count = 0; + + for( const pfic of pokemon_family.evolve_to) { + if (this.pokemonService.isTargetCompleted(pfic)) { + count += 1; + } + } + + for( const pfic of pokemon_family.breed_for) { + if (this.pokemonService.isTargetCompleted(pfic)) { + count += 1; + } + } + + pokemon_family.caught_count = count; + } + } + } + } \ No newline at end of file diff --git a/src/app/features/plan/plan-pokemon-details/plan-pokemon-details.component.ts b/src/app/features/plan/plan-pokemon-details/plan-pokemon-details.component.ts index 972e5a7..2305af2 100644 --- a/src/app/features/plan/plan-pokemon-details/plan-pokemon-details.component.ts +++ b/src/app/features/plan/plan-pokemon-details/plan-pokemon-details.component.ts @@ -5,7 +5,12 @@ import { Pokemon } from '../../../core/models/pokemon.model'; import { PokemonService } from '../../../core/services/pokemon.service'; import { MatChipsModule } from '@angular/material/chips'; import { MatTabsModule } from '@angular/material/tabs'; +import { PlanService } from '../../../core/services/plan.service'; +export interface PokemonCaughtStatusUpdate { + pokemon: Pokemon; + familyEntry: PokemonFamilyEntry; +} @Component({ selector: 'app-plan-pokemon-details', @@ -32,6 +37,14 @@ template: ` class="target-image" [class.grayscale]="isTargetCompleted(target.PFIC)" > +
+ +
{{ target.Name }} @@ -123,15 +136,30 @@ styles: [` font-size: 0.9em; } +.pokeball-icon { + width: 20px; + height: 20px; + object-fit: contain; + cursor: pointer; + transition: filter 0.3s ease; + } + +.pokeball-icon.grayscale { + filter: grayscale(100%); +} + `] }) export class PlanPokemonDetailsComponent { @Input() pokemon_family!: PokemonFamilyEntry; + @Output() pokemonCaughtStatusUpdated = new EventEmitter(); + evolve_to: Pokemon[] = []; breed_for: Pokemon[] = []; constructor( - public pokemonService: PokemonService + public pokemonService: PokemonService, + private planService: PlanService ) {} ngOnInit() { @@ -224,4 +252,15 @@ export class PlanPokemonDetailsComponent { isTargetCompleted(pfic: string): boolean { return this.pokemonService.isTargetCompleted(pfic); } + + onPokeballClick(event: MouseEvent, target: Pokemon) { + event.stopPropagation(); + if (target) { + this.pokemonService.toggleCatch(target.PFIC).subscribe( + plan => { + this.planService.updateCaughtCount(this.pokemon_family); + } + ); + } + } } \ No newline at end of file diff --git a/src/app/features/plan/plan-pokemon/plan-pokemonV2.component.ts b/src/app/features/plan/plan-pokemon/plan-pokemonV2.component.ts index 43424d5..c7fd82e 100644 --- a/src/app/features/plan/plan-pokemon/plan-pokemonV2.component.ts +++ b/src/app/features/plan/plan-pokemon/plan-pokemonV2.component.ts @@ -40,7 +40,6 @@ interface PokemonStatusEvent { [src]="pokemonService.getPokemonImageUrl(this.representative_pokemon)" [alt]="this.representative_pokemon?.Name" class="pokemon-thumbnail" - [class.grayscale]="pokemon_family.catch_count === 0" >
@@ -62,11 +61,10 @@ interface PokemonStatusEvent {
- {{ this.catch_count }} + {{ this.pokemon_family.catch_count - this.pokemon_family.caught_count }}
@@ -178,7 +176,6 @@ export class PlanPokemonV2Component { ngOnInit() { this.representative_pokemon = null; - this.catch_count = this.pokemon_family.catch_count; this.handlePokemonFamilyChange(this.pokemon_family); }