Archive commit

This commit is contained in:
Erik McClure
2019-08-28 21:15:02 -07:00
commit 735845746e
1435 changed files with 140724 additions and 0 deletions
@@ -0,0 +1,36 @@
.sr-only(#ariaAnnounce aria-live="assertive")
.character-select.input-group
input.form-control.text-center(
#nameInput
type="text"
[(ngModel)]="pony.name"
[maxlength]="maxNameLength"
placeholder="Name of your character"
aria-label="Name of your character")
.input-group-append
button.btn.btn-default(*ngIf="newButton" (click)="createNew()" [disabled]="!canNew" aria-label="Create New character")
| new
button.btn.btn-default(*ngIf="editButton" (click)="edit()" [disabled]="!canEdit" aria-label="Edit character")
| edit
.dropdown(dropdown #dropdown="ag-dropdown" (isOpenChange)="onToggle($event)" [focusOnOpen]="false")
button.btn.btn-default.dropdown-toggle.br-0(
[ngClass]="removeButton ? 'btn-no-round' : 'btn-no-round-left'"
[disabled]="!hasPonies || joining" dropdownToggle aria-label="Select character")
character-list.dropdown-menu(
*dropdownMenu (close)="dropdown.close()" (selectCharacter)="select($event)" (newCharacter)="createNew()"
(previewCharacter)="preview.emit($event)" [canNew]="!newButton && canNew")
button.btn.btn-danger.remove-button(
*ngIf="removeButton && !removing" (click)="remove()" [disabled]="!canRemove"
tooltip="Delete pony" aria-label="Delete pony")
fa-icon([icon]="deleteIcon" [fixedWidth]="true")
button.btn.btn-danger.cancel-remove-button(
*ngIf="removing" (click)="cancelRemove()"
tooltip="Cancel delete" aria-label="Cancel delete")
fa-icon([icon]="removeIcon" [fixedWidth]="true")
button.btn.btn-success(
*ngIf="removing" (click)="confirmRemove()" [disabled]="!canRemove"
tooltip="Confirm delete" aria-label="Confirm delete")
fa-icon([icon]="confirmIcon" [fixedWidth]="true")
@@ -0,0 +1,14 @@
@import '../../../../styles/partials/variables';
.character-select {
max-width: 400px;
margin: auto;
z-index: 200;
}
character-list {
@include media-breakpoint-down(sm) {
left: auto;
right: 0;
}
}
@@ -0,0 +1,128 @@
import { Component, Input, EventEmitter, Output, ViewChild, ElementRef } from '@angular/core';
import { Router } from '@angular/router';
import { PonyObject } from '../../../common/interfaces';
import { PLAYER_NAME_MAX_LENGTH } from '../../../common/constants';
import { VERSION_ERROR } from '../../../common/errors';
import { GameService } from '../../services/gameService';
import { Model, createDefaultPonyObject } from '../../services/model';
import { Dropdown } from '../directives/dropdown';
import { faSpinner, faTrash, faTimes, faCheck } from '../../../client/icons';
import { focusElementAfterTimeout } from '../../../client/htmlUtils';
import { delay } from '../../../common/utils';
import { isMobile } from '../../../client/data';
@Component({
selector: 'character-select',
templateUrl: 'character-select.pug',
styleUrls: ['character-select.scss'],
})
export class CharacterSelect {
readonly maxNameLength = PLAYER_NAME_MAX_LENGTH;
readonly spinnerIcon = faSpinner;
readonly deleteIcon = faTrash;
readonly removeIcon = faTimes;
readonly confirmIcon = faCheck;
@Input() newButton = false;
@Input() editButton = false;
@Input() removeButton = false;
@Input() error?: string;
@Output() errorChange = new EventEmitter<string | undefined>();
@Output() change = new EventEmitter<PonyObject>();
@Output() preview = new EventEmitter<PonyObject | undefined>();
@ViewChild('nameInput', { static: true }) nameInput!: ElementRef;
@ViewChild('ariaAnnounce', { static: true }) ariaAnnounce!: ElementRef;
@ViewChild('dropdown', { static: true }) dropdown!: Dropdown;
removing = false;
private locked = false; // TEMP: move to model
constructor(
private element: ElementRef,
private router: Router,
private model: Model,
private gameService: GameService,
) {
}
get joining() {
return this.gameService.joining;
}
get pony() {
return this.model.pony;
}
get canNew() {
return !this.joining && this.model.account && this.model.account.characterCount < this.model.characterLimit;
}
get canEdit() {
return !this.joining;
}
get canRemove() {
return !this.joining && !this.locked && !this.model.pending && !!this.pony
&& !!this.pony.id && this.error !== VERSION_ERROR;
}
get hasPonies() {
return !!this.model.ponies.length;
}
select(pony: PonyObject) {
if (pony) {
this.removing = false;
this.model.selectPony(pony);
this.change.emit(pony);
this.preview.emit(undefined);
}
this.dropdown.close();
this.focusName();
}
createNew() {
if (this.canNew) {
this.removing = false;
this.model.selectPony(createDefaultPonyObject());
this.change.emit(this.pony);
this.router.navigate(['/character']);
this.focusName();
}
}
edit() {
if (this.canEdit) {
this.removing = false;
this.router.navigate(['/character']);
}
}
remove() {
if (this.canRemove) {
this.removing = true;
focusElementAfterTimeout(this.element.nativeElement, '.cancel-remove-button');
}
}
cancelRemove() {
this.removing = false;
focusElementAfterTimeout(this.element.nativeElement, '.remove-button');
}
confirmRemove() {
if (this.canRemove) {
this.setError(undefined);
this.removing = false;
this.locked = true;
this.model.removePony(this.pony)
.then(() => this.change.emit(this.pony))
.catch((e: Error) => this.setError(e.message))
.then(() => this.ariaAnnounce.nativeElement.textContent = 'Character removed')
.then(() => delay(2000))
.then(() => this.locked = false)
.then(() => this.focusName());
}
}
onToggle(show: boolean) {
if (!show) {
this.preview.emit(undefined);
}
}
private focusName() {
if (!isMobile) {
this.nameInput.nativeElement.focus();
}
}
private setError(error: string | undefined) {
this.error = error;
this.errorChange.emit(error);
}
}