This commit is contained in:
Łukasz Góreczny 2020-12-30 11:49:12 +01:00
commit 3c52e2d65d
16 changed files with 125 additions and 61 deletions

View File

@ -1,6 +1,6 @@
<div [formGroup]="signUpFormGroup" class="container">
<div formGroupName="newAccount" class="container">
<mat-icon matSuffix class="arrow-back" (click)="GoToLoginPage()">arrow_back</mat-icon>
<mat-icon matSuffix class="arrow-back arrow-select" (click)="GoToLoginPage()">arrow_back</mat-icon>
<div class="primary-text header">Create an Account</div>
<mat-form-field class="form-container">

View File

@ -47,10 +47,6 @@ input {
font-size: 20px;
}
.align-to-right {
text-align: right;
}
@media (max-width: 400px) {
.container {
margin-left: 0%;

View File

@ -1,21 +1,15 @@
<div class="container">
<mat-icon matSuffix class="arrow-back" (click)="onArrowBackClick()">arrow_back</mat-icon>
<mat-icon matSuffix class="arrow-back arrow-select" (click)="onArrowBackClick()">arrow_back</mat-icon>
<div class="primary-text header">Select character</div>
<mat-list >
<mat-list>
<mat-divider></mat-divider>
<mat-list-item *ngFor="let character of charactersList">
<mat-icon mat-list-icon>account_circle</mat-icon>
<div mat-line>{{character.name}}</div>
<mat-icon matSuffix class="arrow-forward arrow-select" (click)="onCharacterClick(character.id)">arrow_forward</mat-icon>
<div mat-line> {{character.className}} level: {{character.level}}</div>
<mat-divider></mat-divider>
<mat-list-item> Oweja
<mat-icon matSuffix class="arrow-forward align-to-right" (click)="onCharacterClick()">arrow_forward</mat-icon>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item> James
<mat-icon matSuffix class="arrow-forward align-to-right" (click)="onCharacterClick()">arrow_forward</mat-icon>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item> Legolas
<mat-icon matSuffix class="arrow-forward align-to-right" (click)="onCharacterClick()">arrow_forward</mat-icon>
</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
</div>

View File

@ -1,30 +1,49 @@
import { Component } from '@angular/core';
import {Component, OnInit} from '@angular/core';
import { Router } from '@angular/router';
import {first} from 'rxjs/operators';
import {ClearUserId} from '../../store/actions/app.actions';
import {ErrorResponse} from '../../../types/ErrorResponse';
import {HttpErrorResponse} from '@angular/common/http';
import {Store} from '@ngrx/store';
import {AppState} from '../../store/models/app-state.model';
import {CharacterService} from '../../../services/character.service';
import {CharacterForLoginViewModel} from '../../../types/viewmodels/character-viewmodels/CharacterForLoginViewModel';
import {AddCharacterId} from '../../store/actions/player.action';
@Component({
selector: 'app-select-character',
templateUrl: './select-character.component.html',
styleUrls: ['./select-character.component.css']
})
export class SelectCharacterComponent {
isExpanded = false;
export class SelectCharacterComponent implements OnInit {
charactersList: CharacterForLoginViewModel[];
collapse() {
this.isExpanded = false;
constructor(private router: Router, private store: Store<AppState>, private characterService: CharacterService) {}
ngOnInit() {
this.getUserCharactersList();
}
toggle() {
this.isExpanded = !this.isExpanded;
getUserCharactersList() {
this.store.select(s => s.appStore.userId).pipe(first()).subscribe((userId) => {
this.characterService.getUserCharactersList(userId).pipe(first()).subscribe((charactersList) => {
this.charactersList = charactersList;
}, (error: ErrorResponse | HttpErrorResponse) => {
if (error instanceof HttpErrorResponse) {
error = error.error as ErrorResponse;
}
console.error(error.message);
} );
});
}
constructor(private router: Router) {}
onCharacterClick(){
this.router.navigate(['player'])
onCharacterClick(characterId: number) {
this.store.dispatch(new AddCharacterId({characterId}));
this.router.navigate(['player']);
}
onArrowBackClick(){
this.router.navigate(['login'])
onArrowBackClick() {
this.store.dispatch(new ClearUserId());
this.router.navigate(['login']);
}
}

View File

@ -1,6 +1,6 @@
<div [formGroup]="signInFormGroup" class="container">
<div formGroupName="signIn" class="container">
<mat-icon matSuffix class="arrow-back" (click)="onArrowBackClick()">arrow_back</mat-icon>
<mat-icon matSuffix class="arrow-back arrow-select" (click)="onArrowBackClick()">arrow_back</mat-icon>
<div id="SignInText" class="primary-text header">Sign In</div>
<mat-form-field class="form-container">

View File

@ -9,6 +9,7 @@ import {AppStoreModel} from '../../store/models/app-store.model';
import {select, Store} from '@ngrx/store';
import {AddUserId} from '../../store/actions/app.actions';
import {AppState} from 'src/app/store/models/app-state.model';
import {first} from "rxjs/operators";
@Component({
selector: 'app-sign-in',
@ -43,9 +44,9 @@ export class SignInComponent implements OnDestroy, OnInit {
onLoginButtonClick() {
let role = '';
this.store.select(s => s.appStore.role).subscribe((v) => {
this.store.select(s => s.appStore.role).pipe(first()).subscribe((v) => {
role = v;
}).unsubscribe();
});
this.allSubscriptions.add(
this.userService.tryLogin(
this.signInFormGroup.get('signIn').value['username'],

View File

@ -1,19 +0,0 @@
import {
ActionReducer,
ActionReducerMap,
createFeatureSelector,
createSelector,
MetaReducer
} from '@ngrx/store';
import { environment } from '../../environments/environment';
export interface State {
}
export const reducers: ActionReducerMap<State> = {
};
export const metaReducers: MetaReducer<State>[] = !environment.production ? [] : [];

View File

@ -1,9 +1,9 @@
import {AppStoreModel} from '../models/app-store.model';
import { Action } from '@ngrx/store';
import {Action} from '@ngrx/store';
export enum AppActionTypes {
ADD_USER_ID = '[APP] Add user id',
ADD_ROLE = '[APP] Add role'
ADD_ROLE = '[APP] Add role',
CLEAR_USER_ID = '[APP] Clear user id'
}
export class AddUserId implements Action {
@ -20,4 +20,13 @@ export class AddRole implements Action {
}
}
export type AppAction = AddUserId | AddRole;
export class ClearUserId implements Action {
readonly type = AppActionTypes.CLEAR_USER_ID;
constructor() {
}
}
export type AppAction = AddUserId | AddRole | ClearUserId;

View File

@ -0,0 +1,15 @@
import {Action} from "@ngrx/store";
export enum PlayerActionTypes {
ADD_CHARACTER_ID= '[PLAYER] Add character id'
}
export class AddCharacterId implements Action {
readonly type = PlayerActionTypes.ADD_CHARACTER_ID;
constructor(public payload: {characterId: number}) {
}
}
export type PlayerAction = AddCharacterId;

View File

@ -1,11 +1,15 @@
import {AppStoreModel} from './app-store.model';
import {ActionReducerMap} from '@ngrx/store';
import {AppReducer} from '../reducers/app.reducer';
import {PlayerStoreModel} from './player-store.model';
import {PlayerReducer} from '../reducers/player.reducer';
export interface AppState {
appStore: AppStoreModel;
playerStore: PlayerStoreModel;
}
export const reducers: ActionReducerMap<AppState> = {
appStore: AppReducer,
playerStore: PlayerReducer,
};

View File

@ -0,0 +1,3 @@
export interface PlayerStoreModel {
characterId: number;
}

View File

@ -12,6 +12,8 @@ export function AppReducer(state: AppStoreModel = initialState, action: AppActio
return {...state, userId: action.payload.userId};
case AppActionTypes.ADD_ROLE:
return {...state, role: action.payload.role};
case AppActionTypes.CLEAR_USER_ID:
return {...state, userId: null};
default:
return state;
}

View File

@ -0,0 +1,15 @@
import {PlayerStoreModel} from '../models/player-store.model';
import {PlayerAction, PlayerActionTypes} from '../actions/player.action';
const initialState: PlayerStoreModel = {
characterId: null
};
export function PlayerReducer(state: PlayerStoreModel = initialState, action: PlayerAction) {
switch (action.type) {
case PlayerActionTypes.ADD_CHARACTER_ID:
return {...state, characterId: action.payload.characterId};
default:
return state;
}
}

View File

@ -1,8 +1,9 @@
import {Inject, Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {HttpClient, HttpParams} from '@angular/common/http';
import {Observable, of, throwError} from 'rxjs';
import {ErrorResponse} from '../types/ErrorResponse';
import {Either} from '../types/Either';
import {CharacterForLoginViewModel} from '../types/viewmodels/character-viewmodels/CharacterForLoginViewModel';
import {switchMap, retry} from 'rxjs/operators';
import {LoggedCharactersViewModel} from '../types/viewmodels/character-viewmodels/LoggedCharactersViewModel';
@ -27,4 +28,17 @@ export class CharacterService {
retry(3)
);
}
getUserCharactersList(userId: number): Observable<CharacterForLoginViewModel[]> {
const params = new HttpParams().set('userId', userId.toString())
return this.http.get<Either<CharacterForLoginViewModel[], ErrorResponse>>(this.baseUrl + 'userCharactersList', {params}).pipe(
switchMap(response => {
if (response.isLeft) {
return of(response.left);
} else {
return throwError(response.right);
}
})
);
}
}

View File

@ -73,6 +73,10 @@ mat-divider {
border-top-color: #e9cca7 !important;
}
.arrow-select {
cursor: pointer;
}
html,
body {
height: 100%;

View File

@ -0,0 +1,7 @@
export interface CharacterForLoginViewModel {
id: number;
userId: number;
name: string;
className: string;
level: number;
}