Skip to content

Commit

Permalink
feat(items): change item order (drag-drop)
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveVanOpstal committed Dec 16, 2016
1 parent 9639efe commit 84aa55d
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 34 deletions.
14 changes: 14 additions & 0 deletions src/client/build/build.css
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,20 @@ lb-item-slot {
height: 50px;
}

lb-items lb-item-slot .dropzone {
display: inline-block;
height: 45px;
margin: 2.5px 0;
}

lb-items lb-item-slot.dragging .dropzone {
background-color: #ddd;
}

lb-items lb-item-slot.dragging .dropzone.draghover {
background-color: cadetblue;
}

/* lb-preview */

lb-preview {
Expand Down
48 changes: 42 additions & 6 deletions src/client/build/items/item-slot.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,42 @@ import {Component, EventEmitter, OnInit, Output} from '@angular/core';
import {LolApiService} from '../../services/lolapi.service';
import {Item} from '../item';

import {ItemComponent} from './item.component';

@Component({
selector: 'lb-item-slot',
template: `
<template ngFor let-item [ngForOf]="items">
<lb-item [item]="item"
[ngClass]="{disabled: item.disabled}"
(contextmenu)="rightClicked(item)">
<div class="dropzone"
[style.width]="lbItem.offset + 'px'"
[ngClass]="{draghover: draghover}"
(dragenter)="draghover=true"
(dragleave)="draghover=false"
(dragover)="dragover()"
(drop)="drop(item)">
</div>
<lb-item #lbItem
[item]="item"
[ngClass]="{disabled: item.disabled, dragging: dragging}"
(contextmenu)="rightClicked(item)"
draggable="true"
(dragstart)="dragstart(item)"
(dragend)="dragend()">
</lb-item>
</template>`
})

export class ItemSlotComponent implements OnInit {
@Output() itemRemoved: EventEmitter<Item> = new EventEmitter<Item>();
@Output() itemDragStart: EventEmitter<Item> = new EventEmitter<Item>();
@Output() itemDragEnd: EventEmitter<any> = new EventEmitter<any>();
@Output() itemDrop: EventEmitter<Item> = new EventEmitter<Item>();
items = Array<Item>();

lbItem: ItemComponent;
dragging = false;
draghover = false;

private allItems: any;

constructor(private lolApi: LolApiService) {}
Expand All @@ -36,12 +57,27 @@ export class ItemSlotComponent implements OnInit {
}

rightClicked(item: Item): boolean {
this.removeItem(item);
this.itemRemoved.emit(item);
return false; // stop context menu from appearing
}

removeItem(item: Item) {
this.itemRemoved.emit(item);
dragstart(item: Item) {
this.dragging = true;
this.itemDragStart.emit(item);
}

dragover() {
return false; // allow drop
}

dragend() {
this.dragging = false;
this.itemDragEnd.emit(null);
}

drop(item: Item) {
this.dragging = false;
this.itemDrop.emit(item);
}

private compatibleWithItem(subject: Item): boolean {
Expand Down
12 changes: 6 additions & 6 deletions src/client/build/items/item.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component, DoCheck, ElementRef, Input} from '@angular/core';
import {Component, DoCheck, Input} from '@angular/core';

import {TimeScale} from '../graph/scales';
import {Item} from '../item';
Expand All @@ -14,21 +14,21 @@ import {Item} from '../item';
export class ItemComponent implements DoCheck {
@Input() item: Item;
itemPrev: Item;
offset: number;
private xScaleTime = new TimeScale([0, 1380]);

constructor(private el: ElementRef) {
constructor() {
this.xScaleTime.create();
}

ngDoCheck() {
if (!this.item) {
return;
}
let offset = this.xScaleTime.get()(this.item.time);
if (offset > 0) {
offset += 60;
this.offset = this.xScaleTime.get()(this.item.time);
if (this.offset > 0) {
this.offset += 60;
}
this.el.nativeElement.setAttribute('style', 'left: ' + offset + 'px');
this.itemPrev = this.item;
}
}
94 changes: 72 additions & 22 deletions src/client/build/items/items.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,22 @@ import {ItemSlotComponent} from './item-slot.component';
selector: 'lb-items',
template: `
<template ngFor let-i [ngForOf]="[0,1,2,3,4,5]">
<lb-item-slot (itemRemoved)="removeItem(i, $event)"></lb-item-slot>
<lb-item-slot [ngClass]="{dragging: dragging}"
(itemRemoved)="removeItem($event)"
(itemDragStart)="itemDragStart($event)"
(itemDragEnd)="itemDragEnd()"
(itemDrop)="itemDrop($event)">
</lb-item-slot>
</template>`
})

export class ItemsComponent implements OnInit {
@ViewChildren(ItemSlotComponent) children: QueryList<ItemSlotComponent>;
items = Array<Item>();

dragging = false;
dragged: Item;

private samples: Samples;

constructor(private stats: StatsService, private lolApi: LolApiService) {}
Expand All @@ -35,53 +44,94 @@ export class ItemsComponent implements OnInit {
this.update();
}

removeItem(slotId: number, item: Item) {
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();
}
}

itemDragStart(item: Item) {
this.dragged = item;
this.dragging = true;
}

itemDragEnd() {
this.dragging = false;
}

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

private getItemIndex(id: number, time: number): number|undefined {
for (let index in this.items) {
let itemCurrent = this.items[index];
if (item.id === itemCurrent.id && item.time === itemCurrent.time) {
this.items.splice(parseInt(index, 10), 1);
break;
let item = this.items[index];
if (id === item.id && time === item.time) {
return parseInt(index, 10);
}
}
this.update();
}

private update() {
let result = [];
result = this.updateTimes(this.items);
let result = this.clone(this.items);
result = this.updateBundles(result);
result = this.updateTimes(result);
this.updateOriginalItems(result);
this.updateSlots(result);
this.updatePickedItems(result);
}

private updateBundles(items: Array<Item>): Array<Item> {
let result = items;
for (let index = 0; index < result.length - 1; index++) {
let itemCurrent = result[index];
let itemNext = result[index + 1];

if (itemCurrent.id === itemNext.id && itemCurrent.bundle < itemCurrent.stacks) {
itemCurrent.bundle++;
result.splice(index + 1, 1);
index--;
}
}
return result;
}

private updateTimes(items: Array<Item>): Array<Item> {
let result = items;
if (!this.samples) {
return;
}
let goldOffset = 0;
for (let item of result) {
let itemGold = (item.gold.total * item.bundle);
item.time = this.getTime(
this.samples.gold, goldOffset + item.gold.total, settings.gameTime,
this.samples.gold, goldOffset + itemGold, settings.gameTime,
settings.matchServer.sampleSize);
goldOffset += item.gold.total;
goldOffset += itemGold;
}
return result;
}

private updateBundles(items: Array<Item>): Array<Item> {
let result = this.clone(items);
for (let index = 0; index < result.length - 1; index++) {
let itemCurrent = result[index];
let itemNext = result[index + 1];

if (itemCurrent.id === itemNext.id && itemCurrent.bundle < itemCurrent.stacks) {
itemCurrent.bundle++;
result.splice(index + 1, 1);
index--;
private updateOriginalItems(items: Array<Item>) {
for (let index in items) {
let i = parseInt(index, 10);
for (let index2 = 0; index2 < items[i].bundle; index2 += 1) {
this.items[i + index2].time = items[i].time;
}
}
return result;
}

private updateSlots(items: Array<Item>): void {
Expand Down

0 comments on commit 84aa55d

Please sign in to comment.