Skip to content

Commit

Permalink
feat(services): add PickedItemService
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveVanOpstal committed Jun 18, 2017
1 parent 2723173 commit 2a6b806
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 52 deletions.
2 changes: 1 addition & 1 deletion src/client/build/build.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {ShopComponent} from './shop/shop.component';
<!--<lb-abilities></lb-abilities>
<lb-masteries></lb-masteries>-->
<lb-items (itemSelected)="shop.selectItem($event)" #items></lb-items>
<lb-shop (itemPicked)="items.addItem($event)" #shop></lb-shop>
<lb-shop #shop></lb-shop>
<lb-loading [loading]="loading"></lb-loading>
<lb-retry [error]="error" (retry)="ngOnInit()"></lb-retry>`
})
Expand Down
4 changes: 2 additions & 2 deletions src/client/build/build.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';

import {StatsService} from '../services/stats.service';
import {PickedItemsService, StatsService} from '../services';
import {SharedModule} from '../shared/shared.module';

import {AbilitiesComponent} from './abilities/abilities.component';
Expand All @@ -12,7 +12,7 @@ import {MasteriesModule} from './masteries/masteries.module';
import {ShopModule} from './shop/shop.module';

@NgModule({
providers: [StatsService],
providers: [StatsService, PickedItemsService],
declarations: [BuildComponent, AbilitiesComponent],
imports: [CommonModule, SharedModule, GraphModule, ItemsModule, MasteriesModule, ShopModule],
exports: [BuildComponent]
Expand Down
2 changes: 1 addition & 1 deletion src/client/build/items/item-slot.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export class ItemSlotComponent implements OnInit, DoCheck {

private buildsFrom(subject: Item, item: Item): boolean {
let from = subject.from;
if (!from) {
if (!from || !this.allItems) {
return false;
}

Expand Down
63 changes: 21 additions & 42 deletions src/client/build/items/items.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,14 @@ export class ItemsComponent implements OnInit {
private samples: Samples;
private allItems: any;

constructor(private stats: StatsService, private lolApi: LolApiService) {}
constructor(
private stats: StatsService, private lolApi: LolApiService,
private pickedItems: PickedItemsService) {
pickedItems.items.subscribe(items => {
this.items = items;
this.update();
});
}

ngOnInit() {
this.lolApi.getItems().subscribe(res => {
Expand All @@ -43,28 +50,8 @@ export class ItemsComponent implements OnInit {
});
}

addItem(item: Item) {
item.bundle = 1;
this.items.push({...item});
this.update();
}

removeItem(item: Item) {
let index = this.getItemIndex(item.id, item.time);
if (index !== undefined) {
this.items.splice(index, 1);
this.update();
}
}

switchItem(source: Item, target: Item) {
let indexSource = this.getItemIndex(source.id, source.time);
let indexTarget = this.getItemIndex(target.id, target.time);
if (indexSource && indexSource !== indexTarget) {
this.items.splice(indexSource, 1);
this.items.splice(indexSource < indexTarget ? indexTarget - 1 : indexTarget, 0, source);
this.update();
}
this.pickedItems.remove(item);
}

itemDragStart(item: Item) {
Expand All @@ -78,16 +65,7 @@ export class ItemsComponent implements OnInit {

itemDrop(item: Item) {
this.dragging = false;
this.switchItem(this.dragged, item);
}

private getItemIndex(id: string, time: number): number|undefined {
for (let index in this.items) {
let item = this.items[index];
if (id === item.id && time === item.time) {
return parseInt(index, 10);
}
}
this.pickedItems.move(this.dragged, item);
}

private update() {
Expand All @@ -101,10 +79,15 @@ export class ItemsComponent implements OnInit {
}

private updateBundles(items: Array<Item>): Array<Item> {
for (let item of items) {
if (!item.bundle) {
item.bundle = 1;
}
}

for (let index = 0; index < items.length - 1; index++) {
let itemCurrent = items[index];
let itemNext = items[index + 1];

if (itemCurrent.id === itemNext.id && itemCurrent.bundle < itemCurrent.stacks) {
itemCurrent.bundle++;
items.splice(index + 1, 1);
Expand Down Expand Up @@ -165,6 +148,9 @@ export class ItemsComponent implements OnInit {
}

private updateSlots(items: Array<Item>): void {
if (!items) {
return;
}
this.children.forEach((slot: ItemSlotComponent) => {
slot.items = [];
});
Expand All @@ -190,7 +176,7 @@ export class ItemsComponent implements OnInit {
}

private getItemsFrom(baseItem: Item): Array<string> {
if (!baseItem.from || !baseItem.from.length) {
if (!baseItem.from || !baseItem.from.length || !this.allItems) {
return [];
}
let items: Array<Item> = baseItem.from.map((id: string) => {
Expand Down Expand Up @@ -255,13 +241,6 @@ export class ItemsComponent implements OnInit {
if (!lastSlotItem || !lastSlotItem.contains.length) {
return false;
}
return this.contains(lastSlotItem, item);
}

private contains(item, item2): boolean {
return item.contains.find((containedItem: Item) => {
return this.getItemIndex(containedItem.id, containedItem.time) ===
this.getItemIndex(item2.id, item2.time);
}) !== undefined;
return this.pickedItems.contains(lastSlotItem, item);
}
}
10 changes: 5 additions & 5 deletions src/client/build/shop/shop.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {Component, EventEmitter, OnInit, Output, ViewChild} from '@angular/core';
import {Component, OnInit, ViewChild} from '@angular/core';

import {LolApiService} from '../../services/lolapi.service';
import {LolApiService, PickedItemsService} from '../../services';
import {Item} from '../item';

import {PreviewComponent} from './preview/preview.component';

@Component({
Expand Down Expand Up @@ -59,7 +60,6 @@ import {PreviewComponent} from './preview/preview.component';
})

export class ShopComponent implements OnInit {
@Output() itemPicked: EventEmitter<Item> = new EventEmitter<Item>();
@ViewChild(PreviewComponent) preview: PreviewComponent;

loading: boolean = true;
Expand All @@ -72,7 +72,7 @@ export class ShopComponent implements OnInit {
tree: Array<Item> = [];
private originalItems: Array<Item> = [];

constructor(private lolApi: LolApiService) {}
constructor(private lolApi: LolApiService, private pickedItems: PickedItemsService) {}

ngOnInit() {
this.loading = true;
Expand Down Expand Up @@ -107,7 +107,7 @@ export class ShopComponent implements OnInit {
}

pickItem(item: Item) {
this.itemPicked.emit(item);
this.pickedItems.add(item);
return false; // stop context menu from appearing
}

Expand Down
2 changes: 1 addition & 1 deletion src/client/services/lolapi.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {async, inject, TestBed} from '@angular/core/testing';
import {Router} from '@angular/router';

import {settings} from '../../../config/settings';
import {Endpoint, LolApiService} from '../services';
import {Endpoint, LolApiService} from '../services/lolapi.service';
import {TestModule} from '../testing';

describe('LolApiService', () => {
Expand Down
139 changes: 139 additions & 0 deletions src/client/services/picked-items.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import {Location} from '@angular/common';
import {Injectable} from '@angular/core';
import {DefaultUrlSerializer, UrlTree} from '@angular/router';
import {Subject} from 'rxjs';

import {Item} from '../build/item';

import {LolApiService} from './lolapi.service';

const availableChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-';

@Injectable()
export class PickedItemsService {
items = new Subject<Array<Item>>();
private originalItems = new Array<Item>();
private itemIds = new Array<Item>();
private serializer = new DefaultUrlSerializer();

constructor(lolapi: LolApiService, private location: Location) {
lolapi.getItems().subscribe((items) => {
this.originalItems = items.data;
let urlTree = this.getUrlTree();
this.itemIds = this.decodeItems(urlTree.queryParams['q']);
this.update();
});
}

add(item: Item) {
this.itemIds.push(item);
this.update();
}

remove(item: Item) {
let index = this.getItemIndex(item.id, item.time);
if (index !== undefined) {
this.itemIds.splice(index, 1);
this.update();
}
}

move(source: Item, target: Item) {
let indexSource = this.getItemIndex(source.id, source.time);
let indexTarget = this.getItemIndex(target.id, target.time);
if (indexSource && indexSource !== indexTarget) {
this.itemIds.splice(indexSource, 1);
this.itemIds.splice(indexSource < indexTarget ? indexTarget - 1 : indexTarget, 0, source);
}
}

contains(container: Item, item: Item): boolean {
return container.contains.find((containedItem: Item) => {
return this.getItemIndex(containedItem.id, containedItem.time) ===
this.getItemIndex(item.id, item.time);
}) !== undefined;
}

private update() {
this.updateQuery(this.itemIds);
this.items.next(this.itemIds);
}

private updateQuery(items: Array<Item>) {
let urlTree = this.getUrlTree();
urlTree.queryParams['q'] = this.encodeItems(items);
let url = this.serializer.serialize(urlTree);
this.location.replaceState(url);
}

private getUrlTree(): UrlTree {
return this.serializer.parse(this.location.path(false));
}

private encodeItems(items: Array<Item>): string {
return this.encodeItemIds(this.itemsToIds(items));
}

private encodeItemIds(itemIds: Array<number>): string {
let encode = '';
for (let id of itemIds) {
encode += this.encodeItem(id);
}
return encode;
}

private encodeItem(id: number): string {
let msbLocation = Math.floor(id / 64);
let msb = availableChars.at(msbLocation);
let lsbLocation = id - (msbLocation * 64);
let lsb = availableChars.at(lsbLocation);
return msb + lsb;
}

private decodeItems(query: string): Array<Item> {
return this.idsToItems(this.decodeItemIds(query));
}

private decodeItemIds(query: string): Array<number> {
let result = new Array<number>();
if (!query) {
return result;
}
for (let i = 0; i < query.length / 2; i++) {
result.push(this.decodeItem(query.substr(i * 2, 2)));
}
return result;
}

private decodeItem(query: string): number {
let msb = availableChars.indexOf(query.at(0));
let lsb = availableChars.indexOf(query.at(1));
return (msb * 64) + lsb;
}

private itemsToIds(items: Array<Item>): Array<number> {
return items.map((item) => {
return parseInt(item.id, 10);
});
}

private idsToItems(itemIds: Array<number>): Array<Item> {
let result = new Array<Item>();
for (let id of itemIds) {
let resultItem = this.originalItems[id];
if (resultItem) {
result.push(resultItem);
}
}
return result;
}

private getItemIndex(id: string, time: number): number|undefined {
for (let index in this.itemIds) {
let item = this.itemIds[index];
if (id === item.id && (time === item.time || time === -1)) {
return parseInt(index, 10);
}
}
}
}

0 comments on commit 2a6b806

Please sign in to comment.