SES-115 #44
@ -26,6 +26,7 @@ import { StoreDevtoolsModule } from '@ngrx/store-devtools';
|
|||||||
import {environment} from '../environments/environment';
|
import {environment} from '../environments/environment';
|
||||||
import {SessionCompanionIconsModule} from './shared/sc-icons/session-companion-icons.module';
|
import {SessionCompanionIconsModule} from './shared/sc-icons/session-companion-icons.module';
|
||||||
import {reducers} from './store/models/app-state.model';
|
import {reducers} from './store/models/app-state.model';
|
||||||
|
import {CharacterService} from "../services/character.service";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -61,7 +62,8 @@ BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
|
|||||||
})
|
})
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
UserService
|
UserService,
|
||||||
|
CharacterService
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<div [formGroup]="signUpFormGroup" class="container">
|
<div [formGroup]="signUpFormGroup" class="container">
|
||||||
<div formGroupName="newAccount" 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>
|
<div class="primary-text header">Create an Account</div>
|
||||||
|
|
||||||
<mat-form-field class="form-container">
|
<mat-form-field class="form-container">
|
||||||
|
@ -47,10 +47,6 @@ input {
|
|||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.align-to-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 400px) {
|
@media (max-width: 400px) {
|
||||||
.container {
|
.container {
|
||||||
margin-left: 0%;
|
margin-left: 0%;
|
||||||
|
@ -1,21 +1,15 @@
|
|||||||
<div class="container">
|
<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>
|
<div class="primary-text header">Select character</div>
|
||||||
<mat-list >
|
<mat-list>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<mat-list-item> Oweja
|
<mat-list-item *ngFor="let character of charactersList">
|
||||||
<mat-icon matSuffix class="arrow-forward align-to-right" (click)="onCharacterClick()">arrow_forward</mat-icon>
|
<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>
|
</mat-list-item>
|
||||||
<mat-divider></mat-divider>
|
</mat-list>
|
||||||
<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>
|
</div>
|
||||||
|
|
||||||
|
@ -1,30 +1,49 @@
|
|||||||
import { Component } from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
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({
|
@Component({
|
||||||
selector: 'app-select-character',
|
selector: 'app-select-character',
|
||||||
templateUrl: './select-character.component.html',
|
templateUrl: './select-character.component.html',
|
||||||
styleUrls: ['./select-character.component.css']
|
styleUrls: ['./select-character.component.css']
|
||||||
})
|
})
|
||||||
export class SelectCharacterComponent {
|
export class SelectCharacterComponent implements OnInit {
|
||||||
isExpanded = false;
|
charactersList: CharacterForLoginViewModel[];
|
||||||
|
|
||||||
collapse() {
|
constructor(private router: Router, private store: Store<AppState>, private characterService: CharacterService) {}
|
||||||
this.isExpanded = false;
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.getUserCharactersList();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle() {
|
getUserCharactersList() {
|
||||||
this.isExpanded = !this.isExpanded;
|
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(characterId: number){
|
||||||
|
this.store.dispatch(new AddCharacterId({characterId}))
|
||||||
onCharacterClick(){
|
|
||||||
this.router.navigate(['player'])
|
this.router.navigate(['player'])
|
||||||
}
|
}
|
||||||
|
|
||||||
onArrowBackClick(){
|
onArrowBackClick(){
|
||||||
|
this.store.dispatch(new ClearUserId())
|
||||||
this.router.navigate(['login'])
|
this.router.navigate(['login'])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<div [formGroup]="signInFormGroup" class="container">
|
<div [formGroup]="signInFormGroup" class="container">
|
||||||
<div formGroupName="signIn" 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>
|
<div id="SignInText" class="primary-text header">Sign In</div>
|
||||||
|
|
||||||
<mat-form-field class="form-container">
|
<mat-form-field class="form-container">
|
||||||
|
@ -9,6 +9,7 @@ import {AppStoreModel} from '../../store/models/app-store.model';
|
|||||||
import {select, Store} from '@ngrx/store';
|
import {select, Store} from '@ngrx/store';
|
||||||
import {AddUserId} from '../../store/actions/app.actions';
|
import {AddUserId} from '../../store/actions/app.actions';
|
||||||
import {AppState} from 'src/app/store/models/app-state.model';
|
import {AppState} from 'src/app/store/models/app-state.model';
|
||||||
|
import {first} from "rxjs/operators";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-sign-in',
|
selector: 'app-sign-in',
|
||||||
@ -43,9 +44,9 @@ export class SignInComponent implements OnDestroy, OnInit {
|
|||||||
|
|
||||||
onLoginButtonClick() {
|
onLoginButtonClick() {
|
||||||
let role = '';
|
let role = '';
|
||||||
this.store.select(s => s.appStore.role).subscribe((v) => {
|
this.store.select(s => s.appStore.role).pipe(first()).subscribe((v) => {
|
||||||
role = v;
|
role = v;
|
||||||
}).unsubscribe();
|
});
|
||||||
this.allSubscriptions.add(
|
this.allSubscriptions.add(
|
||||||
this.userService.tryLogin(
|
this.userService.tryLogin(
|
||||||
this.signInFormGroup.get('signIn').value['username'],
|
this.signInFormGroup.get('signIn').value['username'],
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import {AppStoreModel} from '../models/app-store.model';
|
import {Action} from '@ngrx/store';
|
||||||
import { Action } from '@ngrx/store';
|
|
||||||
|
|
||||||
export enum AppActionTypes {
|
export enum AppActionTypes {
|
||||||
ADD_USER_ID = '[APP] Add user id',
|
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 {
|
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;
|
||||||
|
@ -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;
|
@ -1,11 +1,15 @@
|
|||||||
import {AppStoreModel} from './app-store.model';
|
import {AppStoreModel} from './app-store.model';
|
||||||
import {ActionReducerMap} from '@ngrx/store';
|
import {ActionReducerMap} from '@ngrx/store';
|
||||||
import {AppReducer} from '../reducers/app.reducer';
|
import {AppReducer} from '../reducers/app.reducer';
|
||||||
|
import {PlayerStoreModel} from "./player-store.model";
|
||||||
|
import {PlayerReducer} from "../reducers/player.reducer";
|
||||||
|
|
||||||
export interface AppState {
|
export interface AppState {
|
||||||
appStore: AppStoreModel;
|
appStore: AppStoreModel;
|
||||||
|
playerStore: PlayerStoreModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const reducers: ActionReducerMap<AppState> = {
|
export const reducers: ActionReducerMap<AppState> = {
|
||||||
appStore: AppReducer,
|
appStore: AppReducer,
|
||||||
|
playerStore: PlayerReducer,
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
export interface PlayerStoreModel {
|
||||||
|
characterId: number;
|
||||||
|
}
|
@ -12,6 +12,8 @@ export function AppReducer(state: AppStoreModel = initialState, action: AppActio
|
|||||||
return {...state, userId: action.payload.userId};
|
return {...state, userId: action.payload.userId};
|
||||||
case AppActionTypes.ADD_ROLE:
|
case AppActionTypes.ADD_ROLE:
|
||||||
return {...state, role: action.payload.role};
|
return {...state, role: action.payload.role};
|
||||||
|
case AppActionTypes.CLEAR_USER_ID:
|
||||||
|
return {...state, userId: null};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
import {Inject, Injectable} from '@angular/core';
|
||||||
|
import {HttpClient, HttpParams} from '@angular/common/http';
|
||||||
|
import {Observable, of, throwError} from 'rxjs';
|
||||||
|
import {ErrorResponse} from '../types/ErrorResponse';
|
||||||
|
import {Either} from '../types/Either';
|
||||||
|
import {switchMap} from 'rxjs/operators';
|
||||||
|
import {CharacterForLoginViewModel} from "../types/viewmodels/character-viewmodels/CharacterForLoginViewModel";
|
||||||
|
|
||||||
|
Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class CharacterService {
|
||||||
|
private baseUrl = 'api/character/';
|
||||||
|
constructor(private http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
|
||||||
|
this.baseUrl = baseUrl + this.baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -73,6 +73,10 @@ mat-divider {
|
|||||||
border-top-color: #e9cca7 !important;
|
border-top-color: #e9cca7 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.arrow-select {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
export interface CharacterForLoginViewModel {
|
||||||
|
id: number;
|
||||||
|
userId: number;
|
||||||
|
name: string;
|
||||||
|
className: string;
|
||||||
|
level: number;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user