Adding the UI to select a team.

This commit is contained in:
Sergiotarxz 2024-01-13 23:14:14 +01:00
parent e3708066e6
commit 35a65cfa1f
11 changed files with 216 additions and 24 deletions

View File

@ -1,9 +1,17 @@
import AbstractTopBarInterface from '@burguillosinfo/conquer/interface/abstract-top-bar-interface'
import Conquer from '@burguillosinfo/conquer'
import MapNode from '@burguillosinfo/conquer/map-node'
import ConquerUser from '@burguillosinfo/conquer/user'
export default class NodeView extends AbstractTopBarInterface {
private node: MapNode;
private user: ConquerUser;
private view: HTMLElement | null = null;
public getNode(): MapNode {
return this.node;
}
private getNodeNameH2(): HTMLElement {
const element = this.getMainNode().querySelector('h2.node-name');
if (!(element instanceof HTMLElement)) {
@ -12,6 +20,15 @@ export default class NodeView extends AbstractTopBarInterface {
return element;
}
private getView(): HTMLElement {
if (this.view === null) {
const view = this.getNodeFromTemplateId('conquer-view-node-template')
this.view = view;
}
return this.view;
}
private getNodeDescriptionParagraph(): HTMLElement {
const element = this.getMainNode().querySelector('p.node-description');
if (!(element instanceof HTMLElement)) {
@ -24,7 +41,14 @@ export default class NodeView extends AbstractTopBarInterface {
super()
this.node = node;
}
public async run() {
const user = await ConquerUser.getSelfUser();
if (user === null) {
this.runCallbacks('close');
return;
}
this.user = user;
const mainNode = this.getMainNode()
this.runCallbacks('update-nodes');
try {
@ -32,15 +56,36 @@ export default class NodeView extends AbstractTopBarInterface {
} catch (error) {
this.runCallbacks('close');
}
const view = this.getNodeFromTemplateId('conquer-view-node-template')
mainNode.append(view)
mainNode.append(this.getView())
this.getNodeNameH2().innerText = this.node.getName();
this.getNodeDescriptionParagraph().innerText = this.node.getDescription()
+ "\n"
+ (this.node.isNear()
? 'Estas cerca y puedes interactuar con este sitio.'
: 'Estás demasiado lejos para hacer nada aquí.');
view.classList.remove('conquer-display-none')
if (this.node.isNear()) {
await this.runIfNear();
}
this.getView().classList.remove('conquer-display-none')
mainNode.classList.remove('conquer-display-none')
}
private async runIfNear(): Promise<void> {
const team = await this.user.getTeam();
if (team === null) {
const paragraphNoTeam = document.createElement('p');
paragraphNoTeam.innerText = 'Parece que no has seleccionado equipo aun,'
+ ' pulsa el botón de seleccionar equipo para comenzar tu aventura,'
+ ' si quieres cambiar de equipo en el futuro puedes hacerlo sin problemas.';
this.getView().append(paragraphNoTeam);
}
const selectTeamButton = document.createElement('button');
selectTeamButton.innerText = 'Seleccionar equipo';
selectTeamButton.addEventListener('click', () => {
this.runCallbacks('open-select-team');
this.runCallbacks('close');
});
this.getView().append(selectTeamButton);
}
}

View File

@ -0,0 +1,57 @@
import Conquer from '@burguillosinfo/conquer'
import ConquerUser from '@burguillosinfo/conquer/user'
import AbstractTopBarInterface from '@burguillosinfo/conquer/interface/abstract-top-bar-interface'
import MapNode from '@burguillosinfo/conquer/map-node'
import ConquerTeam from '@burguillosinfo/conquer/team';
export default class SelectTeamUI extends AbstractTopBarInterface {
private node: MapNode;
private user: ConquerUser;
private form: HTMLElement | null = null;
constructor(node: MapNode) {
super();
this.node = node;
}
public async run(): Promise<void> {
const user = await ConquerUser.getSelfUser()
if (user === null) {
this.runCallbacks('close')
return
}
this.user = user
await this.populateTeams();
this.getForm().classList.remove('conquer-display-none');
this.getMainNode().append(this.getForm());
this.getMainNode().classList.remove('conquer-display-none');
}
private async populateTeams() {
const teams = await ConquerTeam.getTeams();
for (const team of teams) {
this.populateTeam(team);
}
}
private populateTeam(team: ConquerTeam) {
const teamDiv = this.getNodeFromTemplateId('conquer-team-to-select-template')
const nameParagraph = teamDiv.querySelector('p.conquer-name');
const descriptionParagraph = teamDiv.querySelector('p.conquer-description');
if (!(nameParagraph instanceof HTMLParagraphElement) || !(descriptionParagraph instanceof HTMLParagraphElement)) {
Conquer.fail('Select team name inclusive or description container are not correctly defined in template.');
}
nameParagraph.innerText = team.getName();
descriptionParagraph.innerText = team.getDescription();
nameParagraph.style.color = team.getColor();
this.getForm().append(teamDiv);
}
private getForm(): HTMLElement {
if (this.form === null) {
const form = this.getNodeFromTemplateId('conquer-select-team-list-template')
this.form = form;
}
return this.form;
}
}

View File

@ -13,15 +13,6 @@ export default class SelfPlayerUI extends AbstractTopBarInterface {
this.isExplorerModeEnabled = isExplorerModeEnabled;
}
protected generateNodes(): HTMLElement[] {
const player = this.getNodeFromTemplateId('conquer-interface-with-top-bar-template')
return [player]
}
public generateInterfaceElementCentered(): HTMLElement {
return this.getNodeFromTemplateId('conquer-interface-element-padded-template')
}
public async run(): Promise<void> {
const selfPlayerNode = this.getMainNode()
const user = await ConquerUser.getSelfUser()

View File

@ -8,6 +8,7 @@ import Stroke from 'ol/style/Stroke'
import InterfaceManager from '@burguillosinfo/conquer/interface-manager'
import NodeView from '@burguillosinfo/conquer/interface/node-view'
import JsonSerializer from '@burguillosinfo/conquer/serializer';
import SelectTeamUI from '@burguillosinfo/conquer/interface/select-team';
@JsonObject()
export default class MapNode {
@ -58,10 +59,21 @@ export default class MapNode {
viewNodeInterface.on('update-nodes', () => {
this.runCallbacks('update-nodes');
});
viewNodeInterface.on('open-select-team', () => {
this.openSelectTeam(interfaceManager);
});
interfaceManager.push(viewNodeInterface);
this.runCallbacks('click');
}
public openSelectTeam(interfaceManager: InterfaceManager): void {
const selectTeamUI = new SelectTeamUI(this);
selectTeamUI.on('close', () => {
interfaceManager.remove(selectTeamUI);
});
interfaceManager.push(selectTeamUI);
}
public on(eventName: string, callback: () => void): void {
if (this.callbacks[eventName] === undefined) {
this.callbacks[eventName] = []

View File

@ -1,5 +1,6 @@
import JsonSerializer from '@burguillosinfo/conquer/serializer';
import { JsonObject, JsonProperty } from 'typescript-json-serializer';
import Conquer from '@burguillosinfo/conquer'
@JsonObject()
export default class ConquerTeam {
@ -37,6 +38,35 @@ export default class ConquerTeam {
this.color = color;
}
public static async getTeams(): Promise<ConquerTeam[]> {
const urlTeam = new URL('/conquer/teams', window.location.protocol + '//' + window.location.hostname + ':' + window.location.port)
try {
const response = await fetch(urlTeam)
if (response.status !== 200) {
throw new Error('Invalid response fetching teams.')
}
const teamData = await response.json()
const teams = JsonSerializer.deserialize(teamData, ConquerTeam);
if (teams === undefined || teams === null) {
Conquer.fail('Teams cannot be null, server error.');
}
if (!(teams instanceof Array)) {
throw new Error('Unable to parse team.');
}
const teamsSanitized: ConquerTeam[] = [];
for (const team of teams) {
if (!(team instanceof ConquerTeam)) {
console.error('Received null team from server, fix this error.');
continue;
}
teamsSanitized.push(team);
}
return teamsSanitized;
} catch (error) {
console.error(error)
throw new Error('Unable to fetch Teams.');
}
}
public static async getTeam(uuid: string): Promise<ConquerTeam> {
const urlTeam = new URL('/conquer/team/' + uuid, window.location.protocol + '//' + window.location.hostname + ':' + window.location.port)
try {

View File

@ -96,6 +96,7 @@ sub startup ($self) {
$r->post('/conquer/user/coordinates')->to('UserConquer#setCoordinates');
$r->get('/conquer/team/<uuid>')->to('ConquerTeam#get');
$r->put('/conquer/team')->to('ConquerTeam#put');
$r->get('/conquer/teams')->to('ConquerTeam#getAll');
$r->put('/conquer/node')->to('ConquerNode#create');
$r->get('/conquer/node/near')->to('ConquerNode#nearbyNodes');
$r->get('/conquer/node/<uuid>')->to('ConquerNode#get');

View File

@ -14,6 +14,22 @@ use JSON;
use BurguillosInfo::Schema;
sub getAll ($self) {
my $user = $self->current_user;
if ( !defined $user ) {
return $self->render(
status => 401,
json => {
error => 'You must be logged to fetch teams.',
}
);
}
my $uuid = $self->param('uuid');
my $resultset = BurguillosInfo::Schema->Schema->resultset('ConquerTeam');
my @teams = $resultset->search({});
return $self->render( json => [ map { $_->serialize } @teams ] );
}
sub get ($self) {
my $user = $self->current_user;
if ( !defined $user ) {
@ -40,7 +56,7 @@ sub get ($self) {
);
}
my $team = $teams[0];
return $self->render( json => $team );
return $self->render( json => $team->serialize );
}
sub getSelfTeam ($self) {

View File

@ -9,6 +9,13 @@ body {
min-height: 100%;
width: 100%;
height: 100%; }
body div.conquer-team-to-select {
padding: 5px;
border-radius: 5px;
background: beige;
border: solid black; }
body div.conquer-team-to-select button {
height: 60px; }
body p.conquer-register-error, body p.conquer-login-error, body p.conquer-login-success, body p.conquer-error {
color: red;
margin: 3px;
@ -42,6 +49,8 @@ body {
padding-right: 30px;
display: flex;
justify-content: center; }
body div.conquer-interface-element-padded.conquer-display-block {
display: block; }
body div.conquer-interface-element-padded.conquer-display-none {
display: none; }
body div.create-node-slide {
@ -90,7 +99,8 @@ body {
height: calc(100% - 22px);
margin: 5px;
margin-top: 10px;
margin-bottom: 10px; }
margin-bottom: 10px;
overflow-y: scroll; }
body div.conquer-top-bar {
display: flex;
width: calc(100% - 20px);

View File

@ -17,6 +17,15 @@ html {
}
body {
div.conquer-team-to-select {
padding: 5px;
border-radius: 5px;
background: beige;
border: solid black;
button {
height: 60px;
}
}
p.conquer-register-error, p.conquer-login-error, p.conquer-login-success,p.conquer-error {
color: red;
margin: 3px;
@ -55,6 +64,9 @@ body {
padding-right: 30px;
display: flex;
justify-content: center;
&.conquer-display-block {
display: block;
}
&.conquer-display-none {
display: none;
}
@ -111,6 +123,7 @@ body {
margin: 5px;
margin-top: 10px;
margin-bottom: 10px;
overflow-y: scroll;
}
div.conquer-top-bar {
display: flex;

File diff suppressed because one or more lines are too long

View File

@ -16,12 +16,18 @@
%= include 'conquer/_login-template';
%= include 'conquer/_register-template';
%= include 'conquer/_new-team-form-creation-template';
<div id="conquer-view-node-template" class="conquer-display-none conquer-interface-element-padded">
<div>
<h1>Vista de nodo.</h1>
<h2 class="node-name"></h2>
<p class="node-description"></p>
</div>
<div id="conquer-select-team-list-template" class="conquer-display-none conquer-interface-element-padded conquer-display-block">
<h1>Encuentra tu equipo ideal.</h1>
</div>
<div id="conquer-team-to-select-template" class="conquer-team-to-select conquer-display-none">
<p class="conquer-name"></p>
<p class="conquer-description"></p>
<button class="conquer-submit">Elegir este equipo.</button>
</div>
<div id="conquer-view-node-template" class="conquer-display-none conquer-interface-element-padded conquer-display-block">
<h1>Vista de nodo.</h1>
<h2 class="node-name"></h2>
<p class="node-description"></p>
</div>
<div class="conquer-container">