Skip to content

Commit

Permalink
Merge pull request #3 from baloise-incubator/feat/draggable-inventory…
Browse files Browse the repository at this point in the history
…-and-such

make items draggable and support multiple items
  • Loading branch information
alexsoeres authored Oct 20, 2023
2 parents 26184f7 + 729b775 commit 7cddf82
Show file tree
Hide file tree
Showing 34 changed files with 399 additions and 42 deletions.
4 changes: 3 additions & 1 deletion angular-frontend/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
</bal-card>
<div *ngIf="client.connected && inventories" class="columns">
<div class="column is-9">
<app-inventory *ngFor="let inventory of inventories" [inventory]="inventory" (itemCreated)="onItemCreated($event, inventory)"></app-inventory>
<div class="inventories-container">
<app-inventory class="p-medium inventory-container" *ngFor="let inventory of inventories" [inventory]="inventory" (itemCreated)="onItemCreated($event, inventory)" (hoverOverItem)="onHoverOverItem($event)" (exitItem)="onExitItem($event)" (moveItem)="onItemMoved($event)"></app-inventory>
</div>
<app-game [client]="client" [currentUser]="currentUser"></app-game>
</div>
<div class="column is-3">
Expand Down
9 changes: 9 additions & 0 deletions angular-frontend/src/app/app.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.inventories-container {
display:flex;
align-content: space-evenly;
}

.inventory-container {
display:block;
width:270px;
}
70 changes: 62 additions & 8 deletions angular-frontend/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import { Component, OnDestroy, HostListener } from '@angular/core';
import {Component, OnDestroy, HostListener} from '@angular/core';
import { Client } from '@stomp/stompjs';
import {Button, Credentials, Cursor, Stock, User, Inventory, Character, Item} from "../model";
import {
Credentials,
Cursor,
User,
Inventory,
Character,
Item,
ItemBase,
ItemLockMessage,
ItemTransferMessage
} from "../model";
import { HttpService } from 'src/http.service';
import {CreateItemEvent} from "../events";
import store from "../store";

@Component({
selector: 'app-root',
Expand All @@ -14,10 +25,17 @@ export class AppComponent implements OnDestroy {
client: Client;
httpService: HttpService;
users: User[] = [];
currentUser = "";
cursors: Cursor[] = [];
inventories?: Inventory[];

get currentUser(): string {
return store.currentUser;
}

set currentUser(currentUser: string) {
store.currentUser = currentUser;
}

constructor() {
this.httpService = new HttpService();
this.client = new Client();
Expand All @@ -29,7 +47,7 @@ export class AppComponent implements OnDestroy {

openWebSocketConnection(credentials : Credentials) {
this.client.configure({
debug: (msg) => console.log(msg),
debug: (msg) => console.debug(msg),
webSocketFactory: () => this.httpService.getWebSocket(credentials)
})

Expand All @@ -39,6 +57,8 @@ export class AppComponent implements OnDestroy {
this.client.subscribe("/topic/cursor", (payload => this.updateCursors(JSON.parse(payload.body))));
this.client.subscribe("/app/inventory", (payload => this.updateInventory(JSON.parse(payload.body))));
this.client.subscribe("/topic/inventory", (payload => this.updateInventory(JSON.parse(payload.body))));
this.client.subscribe("/topic/itembases", (payload => this.updateItemBases(JSON.parse(payload.body))))
this.client.subscribe("/app/itembases", (payload => this.updateItemBases(JSON.parse(payload.body))))
};

this.client.onWebSocketError = (error) => {
Expand Down Expand Up @@ -118,10 +138,10 @@ export class AppComponent implements OnDestroy {
return;
}

var newExceptEx = newItems.filter(x => !exInventory.items!.find(y => x.id === y.id))
var exExceptNew = exInventory.items.filter(x => !newItems!.find(y => x.id === y.id))
var toUpdate = exInventory.items
.map(exItem => ({ exItem, newItem: newItems!.find(x => exInventory.id === x.id) }))
const newExceptEx = newItems.filter(x => !exInventory.items!.find(y => x.id === y.id))
const exExceptNew = exInventory.items.filter(x => !newItems!.find(y => x.id === y.id))
const toUpdate = exInventory.items
.map(exItem => ({ exItem, newItem: newItems!.find(x => exItem.id === x.id) }))
.filter(x => !!x.newItem)

for (const newItem of newExceptEx) {
Expand All @@ -132,6 +152,7 @@ export class AppComponent implements OnDestroy {
}
for (const items of toUpdate) {
items.exItem.name = items.newItem!.name
items.exItem.userLock = items.newItem!.userLock;
}
}

Expand All @@ -142,4 +163,37 @@ export class AppComponent implements OnDestroy {
});
}

private updateItemBases(itemBase: ItemBase[]) {
store.itemBases = itemBase;
}

onHoverOverItem(item: Item) {
if (!item.userLock) {
this.client?.publish({
destination: "/app/itemlock", body: JSON.stringify({
id: item.id,
lock: true
} as ItemLockMessage)
});
console.log("lock pls")
}
}
onExitItem(item: Item) {
if (item.userLock === this.currentUser) {
this.client?.publish({
destination: "/app/itemlock", body: JSON.stringify({
id: item.id,
lock: false
} as ItemLockMessage)
});
console.log("unlock pls")
}
}

onItemMoved(event: ItemTransferMessage) {
console.log("moved");
this.client?.publish({
destination: "/app/itemtransfer", body: JSON.stringify(event)
});
}
}
3 changes: 2 additions & 1 deletion angular-frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { StockComponent } from './components/stock/stock.component';
import { UserBarComponent } from './components/user-bar/user-bar.component';
import { GameComponent } from './components/game/game.component';
import { balIconAccount, balIconSend, balIconStarShape, balIconStarFull, balIconWeb, balIconX} from '@baloise/design-system-icons'
import { ItemBaseSelectionComponent } from './components/item-base-selection/item-base-selection.component'

@NgModule({
declarations: [AppComponent, CheckInComponent, InventoryComponent, InventoryItemComponent, ChatComponent, GameComponent, StockComponent, UserBarComponent],
declarations: [AppComponent, CheckInComponent, InventoryComponent, InventoryItemComponent, ChatComponent, GameComponent, StockComponent, UserBarComponent, ItemBaseSelectionComponent],
imports: [
BrowserModule,
// Provide all components and value accessors to the app module.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<div class="inventory-item" (dragstart)="onDragStart($event)" draggable="true">
{{item.name}}
</div>
<div class="inventory-item" [ngClass]="item.userLock ? 'locked-item' : ''" [draggable]="item.userLock === currentUser" (dragstart)="onDragStart($event)">
<img [alt]="item" [src]="'assets/items/' + item.name + '.png'"/>
</div>
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
.inventory-item {
width:90px;
height:90px;
border-radius:3px;
background-color: limegreen;
margin:5px;
width:50px;
height:50px;
border-radius:9px;
background-color: white;
margin:3px;
box-shadow: 0 0 5px lightgray;
}

.locked-item {
background-color:lightgray;
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import {Component, Input} from '@angular/core';
import {Component, Input, OnInit} from '@angular/core';
import {Item} from "../../../model";
import store from "../../../store";

@Component({
selector: 'app-inventory-item',
templateUrl: './inventory-item.component.html',
styleUrls: ['./inventory-item.component.scss']
})
export class InventoryItemComponent {
export class InventoryItemComponent implements OnInit {
@Input()
item!: Item;
item!: Item
get currentUser(): string {
return store.currentUser;
}

onDragStart(event: DragEvent) {
event.dataTransfer?.clearData()
event.dataTransfer?.setData("application/json", JSON.stringify( {
target: this.item
}))
event.dataTransfer?.setData("application/json", JSON.stringify(this.item))
}

ngOnInit(): void {
console.log("hey?")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
</bal-card-title>
<bal-card-content>
<div class="inventory-grid" (drop)="onDrop($event)" (dragenter)="onDragEnter($event)" (dragover)="onDragOver($event)">
<app-inventory-item [item]="item" *ngFor="let item of inventory.items"></app-inventory-item>
<bal-button square="" inverted="" icon="plus" (click)="temporaryCreate()"></bal-button>
<app-inventory-item [item]="item" (mouseenter)="onHoverOverItem(item)" (mouseleave)="onExitItem(item)" *ngFor="let item of inventory.items"></app-inventory-item>
<div class="inventory-add-button">
<bal-button square="" inverted="" icon="plus" (click)="onCreateNew()"></bal-button>
</div>
</div>
</bal-card-content>
</bal-card>
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,15 @@
flex-wrap: wrap;
}
.inventory {
width:348px;
}
.inventory-add-button {
width:50px;
height:50px;
border-radius:9px;
background-color: white;
margin:3px;
box-shadow: 0 0 5px lightgray;
display:flex;
justify-content: center;
align-items: center;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {Inventory} from "../../../model";
import {Inventory, Item, ItemBase, ItemTransferMessage} from "../../../model";
import {CreateItemEvent} from "../../../events";
import {BalModalService} from "@baloise/design-system-components-angular";
import {ItemBaseSelectionComponent} from "../item-base-selection/item-base-selection.component";

@Component({
selector: 'app-inventory',
Expand All @@ -13,22 +15,48 @@ export class InventoryComponent implements OnInit {
inventory!: Inventory

@Output()
moveRequested = new EventEmitter<string>
itemCreated = new EventEmitter<CreateItemEvent>

@Output()
itemCreated = new EventEmitter<CreateItemEvent>
hoverOverItem = new EventEmitter<Item>;

@Output()
exitItem = new EventEmitter<Item>;

@Output()
moveItem = new EventEmitter<ItemTransferMessage>

constructor(private modalService: BalModalService) {}

ngOnInit(): void {
console.log(this.inventory)
}

//todo: do propurle
temporaryCreate() {
this.itemCreated.emit({ name: 'gold' })
async onCreateNew() {
const modal = await this.modalService.create({
component: ItemBaseSelectionComponent,
componentProps: {
onSelected: (base: ItemBase) => {
modal.dismiss();
this.createItemFromSelectedItemBase(base)
}
}
})
await modal.present();
}

createItemFromSelectedItemBase(base: ItemBase) {
this.itemCreated.emit({ name: base.name })
}

onDrop(event: DragEvent) {
console.log("drop", event.dataTransfer?.getData("application/json"));
if (event.dataTransfer) {
const data = JSON.parse(event.dataTransfer.getData("application/json")) as Item
this.moveItem.emit({
id: data.id,
targetInventoryId: this.inventory.id
})
}
}

onDragOver(event: DragEvent) {
Expand All @@ -40,4 +68,12 @@ export class InventoryComponent implements OnInit {
event.preventDefault();
console.log("enter");
}

onHoverOverItem(item: Item) {
this.hoverOverItem.emit(item);
}

onExitItem(item: Item) {
this.exitItem.emit(item)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="item-base-container">
<div *ngFor="let base of itemBases" class="item-base-group" (click)="onItemClicked(base)">
<div class="item-base">
<img [alt]="base.label" [src]="'assets/items/' + base.name + '.png'"/>
</div>
<div class="item-base-label">{{base.label}}</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.item-base {
width:50px;
height:50px;
border-radius:9px;
background-color: white;
margin:3px;
box-shadow: 0 0 5px lightgray;
}

.item-base-container {
display: flex;
justify-content: space-evenly;
flex-wrap:wrap;
}

.item-base-group {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 150px;
padding:10px;
margin-bottom: 10px;
border-radius:9px;
cursor: grab;
}

.item-base-group:hover {
background-color:lightgray;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {Component, Input} from '@angular/core';
import store from "../../../store";
import {ItemBase} from "../../../model";

@Component({
selector: 'app-item-base-selection',
templateUrl: './item-base-selection.component.html',
styleUrls: ['./item-base-selection.component.scss']
})
export class ItemBaseSelectionComponent {

@Input()
onSelected?: (base: ItemBase) => void;

get itemBases() {
return store.itemBases;
}

onItemClicked(base: ItemBase) {
this.onSelected && this.onSelected(base);
}
}
Binary file added angular-frontend/src/assets/items/diamond.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added angular-frontend/src/assets/items/gold_bar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added angular-frontend/src/assets/items/gold_coin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added angular-frontend/src/assets/items/gold_ore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added angular-frontend/src/assets/items/items.afphoto
Binary file not shown.
Binary file added angular-frontend/src/assets/items/longsword.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added angular-frontend/src/assets/items/shield.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added angular-frontend/src/assets/items/shortsword.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 7cddf82

Please sign in to comment.