work
This commit is contained in:
@@ -9,15 +9,15 @@ import {
|
||||
PlayerService,
|
||||
StateService,
|
||||
} from './utils';
|
||||
import { LoginApiService, initializeLoginSvc } from '../frontcraft/services/login-api';
|
||||
import { ApiService, initializeLoginSvc } from '../frontcraft/services/login-api';
|
||||
|
||||
const DATA_SERVICES = [
|
||||
{provide: LoginApiService, useClass: LoginApiService},
|
||||
{provide: ApiService, useClass: ApiService},
|
||||
{provide: CookieService, useClass: CookieService},
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: initializeLoginSvc,
|
||||
deps: [LoginApiService, CookieService],
|
||||
deps: [ApiService, CookieService],
|
||||
multi: true
|
||||
}
|
||||
];
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ApiService } from '../../../frontcraft/services/login-api';
|
||||
import { ShoutMessage } from '../../../../../../backend/Components/Shoutbox/Interface';
|
||||
|
||||
@Component({
|
||||
selector: 'chat',
|
||||
template: `
|
||||
<nb-chat title="Shoutbox" size="large" status="primary">
|
||||
<nb-chat-message *ngFor="let msg of messages"
|
||||
[type]="text"
|
||||
[message]="msg.message"
|
||||
[sender]="msg.sender"
|
||||
[date]="msg.date">
|
||||
</nb-chat-message>
|
||||
<nb-chat-form (send)="submit($event)" [dropFiles]="false">
|
||||
</nb-chat-form>
|
||||
</nb-chat>
|
||||
`,
|
||||
styles: [`
|
||||
nb-chat {
|
||||
width: 600px;
|
||||
margin: 0.5rem 0 2rem 2rem;
|
||||
}`],
|
||||
})
|
||||
export class ChatComponent {
|
||||
|
||||
messages : ShoutMessage[] = []
|
||||
history
|
||||
|
||||
constructor(
|
||||
private api: ApiService
|
||||
) {}
|
||||
|
||||
submit(event){
|
||||
this.sendMessage({
|
||||
date: ""+Date.now(),
|
||||
message: event.message,
|
||||
sender: this.api.getCurrentUser().username
|
||||
})
|
||||
}
|
||||
|
||||
sendMessage : (msg:ShoutMessage)=>Promise<void>
|
||||
}
|
||||
@@ -3,16 +3,27 @@
|
||||
<a (click)="toggleSidebar()" href="#" class="sidebar-toggle">
|
||||
<nb-icon icon="menu-2-outline"></nb-icon>
|
||||
</a>
|
||||
<a class="logo" href="#" (click)="navigateHome()">Frontcraft</a>
|
||||
<a class="logo" href="#" (click)="navigateHome()">{{title}}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header-container">
|
||||
<nb-actions size="small">
|
||||
|
||||
<nb-action class="control-item" icon="message-square-outline"></nb-action>
|
||||
<nb-action class="control-item" icon="bell-outline"></nb-action>
|
||||
|
||||
<nb-action
|
||||
*ngIf="!newmessage"
|
||||
icon="message-square-outline"
|
||||
(click)="openChat()">
|
||||
</nb-action>
|
||||
<nb-action
|
||||
*ngIf="newmessage"
|
||||
icon="message-square-outline"
|
||||
badgeText="new"
|
||||
badgePosition="top right"
|
||||
badgeStatus="info"
|
||||
(click)="openChat()">
|
||||
</nb-action>
|
||||
|
||||
<nb-action class="user-action">
|
||||
<nb-user [nbContextMenu]="userMenu"
|
||||
[onlyPicture]="false"
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { NbMediaBreakpointsService, NbMenuService, NbSidebarService, NbThemeService, NbContextMenuComponent, NbMenuItem } from '@nebular/theme';
|
||||
import { NbMediaBreakpointsService, NbSidebarService, NbThemeService, NbMenuItem, NbDialogService } from '@nebular/theme';
|
||||
|
||||
import { LayoutService } from '../../../@core/utils';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { LoginApiService } from '../../../frontcraft/services/login-api';
|
||||
import { ApiService } from '../../../frontcraft/services/login-api';
|
||||
import { User } from '../../../../../../backend/Types/Types';
|
||||
import { Router } from '@angular/router';
|
||||
import { ChatComponent } from './chat.component';
|
||||
import { ShoutMessage } from '../../../../../../backend/Components/Shoutbox/Interface';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-header',
|
||||
@@ -15,8 +18,8 @@ import { User } from '../../../../../../backend/Types/Types';
|
||||
export class HeaderComponent implements OnInit, OnDestroy {
|
||||
|
||||
private destroy$: Subject<void> = new Subject<void>();
|
||||
userPictureOnly: boolean = false;
|
||||
user: User;
|
||||
title = "Loading ... ";
|
||||
|
||||
themes = [
|
||||
{
|
||||
@@ -38,37 +41,46 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
];
|
||||
|
||||
currentTheme = 'dark';
|
||||
|
||||
userMenu : NbMenuItem[] = [ { title: 'Log out', link: '/auth/logout' } ];
|
||||
|
||||
sendMessage: any = console.log
|
||||
chatwindow: ChatComponent
|
||||
chatlog: ShoutMessage[] = []
|
||||
newmessage = false
|
||||
lastmessage = "asdasd"
|
||||
|
||||
constructor(private sidebarService: NbSidebarService,
|
||||
private menuService: NbMenuService,
|
||||
private router: Router,
|
||||
private themeService: NbThemeService,
|
||||
private layoutService: LayoutService,
|
||||
private breakpointService: NbMediaBreakpointsService,
|
||||
private loginService: LoginApiService,
|
||||
private api: ApiService,
|
||||
private dialogService : NbDialogService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.currentTheme = this.themeService.currentTheme;
|
||||
|
||||
this.user = this.loginService.getCurrentUser()
|
||||
this.user = this.api.getCurrentUser()
|
||||
if(this.user)
|
||||
this.userMenu.unshift({ title: 'Profile', link: '/frontcraft/user/'+this.user.username });
|
||||
|
||||
/*
|
||||
this.userService.getUsers()
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((users: any) => this.user = users.lee);
|
||||
*/
|
||||
|
||||
const { xl } = this.breakpointService.getBreakpointsMap();
|
||||
this.themeService.onMediaQueryChange()
|
||||
.pipe(
|
||||
map(([, currentBreakpoint]) => currentBreakpoint.width < xl),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((isLessThanXl: boolean) => this.userPictureOnly = isLessThanXl);
|
||||
this.api.get('GuildManager').getGuildInfo().then(info => {
|
||||
this.title = info.name
|
||||
})
|
||||
|
||||
this.api.connectShoutbox((msg) => {
|
||||
this.chatlog.push(msg)
|
||||
if(msg.message != this.lastmessage)
|
||||
this.newmessage = true
|
||||
if(this.chatwindow) this.chatwindow.messages.push(msg)
|
||||
}).then(sendMsg => {
|
||||
this.sendMessage = (msg) => {
|
||||
sendMsg(msg)
|
||||
this.lastmessage = msg.message
|
||||
}
|
||||
this.api.get('Shoutbox').getFeed().then(log => {this.chatlog = log})
|
||||
})
|
||||
|
||||
this.themeService.onThemeChange()
|
||||
.pipe(
|
||||
@@ -78,6 +90,20 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
.subscribe(themeName => this.currentTheme = themeName);
|
||||
}
|
||||
|
||||
openChat(){
|
||||
this.newmessage = false
|
||||
const ref = this.dialogService.open(ChatComponent, {
|
||||
context: {
|
||||
sendMessage: this.sendMessage,
|
||||
}
|
||||
});
|
||||
ref.onClose.subscribe(()=>{
|
||||
this.chatwindow = null
|
||||
})
|
||||
this.chatwindow = ref.componentRef.instance
|
||||
this.chatwindow.messages.push(...this.chatlog)
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
@@ -95,11 +121,11 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.loginService.logout()
|
||||
this.api.logout()
|
||||
}
|
||||
|
||||
navigateHome() {
|
||||
this.menuService.navigateHome();
|
||||
this.router.navigateByUrl('/')
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ import {
|
||||
NbSelectModule,
|
||||
NbIconModule,
|
||||
NbThemeModule,
|
||||
NbDialogModule,
|
||||
NbChatModule,
|
||||
NbCardModule,
|
||||
} from '@nebular/theme';
|
||||
import { NbEvaIconsModule } from '@nebular/eva-icons';
|
||||
import { NbSecurityModule } from '@nebular/security';
|
||||
@@ -39,6 +42,7 @@ import { DEFAULT_THEME } from './styles/theme.default';
|
||||
import { COSMIC_THEME } from './styles/theme.cosmic';
|
||||
import { CORPORATE_THEME } from './styles/theme.corporate';
|
||||
import { DARK_THEME } from './styles/theme.dark';
|
||||
import { ChatComponent } from './components/header/chat.component';
|
||||
|
||||
const NB_MODULES = [
|
||||
NbLayoutModule,
|
||||
@@ -53,6 +57,9 @@ const NB_MODULES = [
|
||||
NbSelectModule,
|
||||
NbIconModule,
|
||||
NbEvaIconsModule,
|
||||
NbChatModule,
|
||||
NbCardModule,
|
||||
NbDialogModule.forChild()
|
||||
];
|
||||
const COMPONENTS = [
|
||||
HeaderComponent,
|
||||
@@ -62,7 +69,8 @@ const COMPONENTS = [
|
||||
OneColumnLayoutComponent,
|
||||
ThreeColumnsLayoutComponent,
|
||||
TwoColumnsLayoutComponent,
|
||||
OneColumnNoSidebarLayoutComponent
|
||||
OneColumnNoSidebarLayoutComponent,
|
||||
ChatComponent
|
||||
];
|
||||
const PIPES = [
|
||||
CapitalizePipe,
|
||||
@@ -76,6 +84,9 @@ const PIPES = [
|
||||
imports: [CommonModule, ...NB_MODULES],
|
||||
exports: [CommonModule, ...PIPES, ...COMPONENTS],
|
||||
declarations: [...COMPONENTS, ...PIPES],
|
||||
entryComponents: [
|
||||
ChatComponent
|
||||
]
|
||||
})
|
||||
export class ThemeModule {
|
||||
static forRoot(): ModuleWithProviders {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { AnalyticsService } from './@core/utils/analytics.service';
|
||||
import { LoginApiService } from './frontcraft/services/login-api';
|
||||
import { ApiService } from './frontcraft/services/login-api';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-app',
|
||||
@@ -13,7 +13,7 @@ import { LoginApiService } from './frontcraft/services/login-api';
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
|
||||
constructor(private loginSvc: LoginApiService, private analytics: AnalyticsService) {
|
||||
constructor(private loginSvc: ApiService, private analytics: AnalyticsService) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { CoreModule } from './@core/core.module';
|
||||
import { ThemeModule } from './@theme/theme.module';
|
||||
@@ -20,6 +20,8 @@ import {
|
||||
NbToastrModule,
|
||||
NbWindowModule,
|
||||
} from '@nebular/theme';
|
||||
import { ApiService, initializeLoginSvc } from './frontcraft/services/login-api';
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
@@ -42,7 +44,13 @@ import {
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
providers: [
|
||||
|
||||
ApiService,
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
deps: [CookieService],
|
||||
multi: true,
|
||||
useFactory: initializeLoginSvc
|
||||
},
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { LoginApiService } from '../services/login-api';
|
||||
import { ApiService } from '../services/login-api';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
@@ -13,7 +13,7 @@ import { Router } from '@angular/router';
|
||||
|
||||
export class AuthComponent implements OnInit{
|
||||
constructor(
|
||||
private loginSvc : LoginApiService,
|
||||
private loginSvc : ApiService,
|
||||
private router: Router
|
||||
){}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<form (ngSubmit)="login()" #form="ngForm" aria-labelledby="title">
|
||||
|
||||
<div class="form-control-group">
|
||||
<label class="label" for="input-email">Email address:</label>
|
||||
<label class="label" for="input-email">Username:</label>
|
||||
<input nbInput
|
||||
fullWidth
|
||||
[(ngModel)]="user.name"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { LoginApiService } from '../../services/login-api';
|
||||
import { ApiService } from '../../services/login-api';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
@@ -21,7 +21,7 @@ export class MyLoginComponent implements OnInit{
|
||||
|
||||
constructor(
|
||||
private router : Router,
|
||||
private loginApi : LoginApiService
|
||||
private loginApi : ApiService
|
||||
){}
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { LoginApiService } from '../../services/login-api';
|
||||
import { ApiService } from '../../services/login-api';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
@@ -9,11 +9,11 @@ import { Router } from '@angular/router';
|
||||
export class LogoutComponent implements OnInit{
|
||||
|
||||
constructor(
|
||||
private loginApi : LoginApiService
|
||||
private api : ApiService
|
||||
){}
|
||||
|
||||
ngOnInit(){
|
||||
this.loginApi.logout()
|
||||
this.api.logout()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,21 +2,6 @@
|
||||
|
||||
<form (ngSubmit)="onSubmit()" #form="ngForm" aria-labelledby="title">
|
||||
|
||||
<div class="form-control-group">
|
||||
<label class="label" for="input-email">Email address:</label>
|
||||
<input nbInput
|
||||
fullWidth
|
||||
[(ngModel)]="user.email"
|
||||
#email="ngModel"
|
||||
name="name"
|
||||
id="input-email"
|
||||
pattern=".+"
|
||||
placeholder="Email Address"
|
||||
fieldSize="giant"
|
||||
autofocus
|
||||
[required]="true">
|
||||
</div>
|
||||
|
||||
<div class="form-control-group">
|
||||
<label class="label" for="input-username">Username:</label>
|
||||
<input nbInput
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { LoginApiService, hash } from '../../services/login-api';
|
||||
import { ApiService as ApiService, hash } from '../../services/login-api';
|
||||
import { Router } from '@angular/router';
|
||||
import { _Rank, _Class, Class, User } from '../../../../../../backend/Types/Types'
|
||||
import { specs } from '../../../../../../backend/Types/PlayerSpecs'
|
||||
import { race } from 'rxjs';
|
||||
|
||||
|
||||
@Component({
|
||||
@@ -20,7 +21,6 @@ export class RegisterComponent implements OnInit{
|
||||
spec : "Arms"
|
||||
}
|
||||
|
||||
|
||||
ranks = _Rank
|
||||
classes = _Class
|
||||
selectedClass : Class = "Warrior"
|
||||
@@ -30,11 +30,11 @@ export class RegisterComponent implements OnInit{
|
||||
|
||||
constructor(
|
||||
private router : Router,
|
||||
private loginApi : LoginApiService
|
||||
private api : ApiService
|
||||
){}
|
||||
|
||||
ngOnInit(){
|
||||
this.loginApi.checkLogin().then(loggedin => {
|
||||
this.api.checkLogin().then(loggedin => {
|
||||
if(loggedin){
|
||||
this.router.navigateByUrl("/")
|
||||
}
|
||||
@@ -60,27 +60,27 @@ export class RegisterComponent implements OnInit{
|
||||
this.character = {}
|
||||
|
||||
try{
|
||||
const usr = await this.loginApi.getUnprivilegedSocket().Authenticator.createUser(user)
|
||||
const usr = await this.api.get('UserManager').createUser(user)
|
||||
}catch(e){
|
||||
alert("Error creating user"+e)
|
||||
return
|
||||
}
|
||||
|
||||
try{
|
||||
await this.loginApi.login(user.username, pw)
|
||||
await this.loginApi.getFeature('createCharacter').then(async feature => {
|
||||
if(!feature) return
|
||||
const specid = await this.loginApi.getUnprivilegedSocket().CharacterManager.getSpecId(char['class'], char['spec'])
|
||||
await feature.createCharacter(this.loginApi.getAuth().token.value, {
|
||||
charactername: char.name,
|
||||
specid: specid,
|
||||
userid: this.loginApi.getAuth().user.id!
|
||||
})
|
||||
await this.api.login(user.username, pw)
|
||||
|
||||
const characterManager = this.api.get('CharacterManager')
|
||||
|
||||
const specid = await characterManager.getSpecId(char['class'], char['spec'])
|
||||
await characterManager.createCharacter(this.api.getAuth().token.value, {
|
||||
charactername: char.name,
|
||||
specid: specid,
|
||||
userid: this.api.getAuth().user.id!,
|
||||
race: 'Human'
|
||||
})
|
||||
}catch(e){
|
||||
alert("Error creating character"+e)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,23 @@
|
||||
<nb-card
|
||||
class = "col-12 col-xl-9"
|
||||
status="control">
|
||||
<nb-card-header [ngStyle]="{'color': color}" style="text-transform: capitalize;">
|
||||
{{char.charactername}}
|
||||
</nb-card-header>
|
||||
<nb-card-body>
|
||||
{{char.race}}<br />
|
||||
{{char.specname}} {{char.class}}<br />
|
||||
Owned by <a [routerLink]="'/frontcraft/user/'+char.username"> {{char.username}} ({{char.rank}})</a>
|
||||
<br/><br />
|
||||
<span *ngFor="let token of tokens">
|
||||
[ {{token.level}} ]
|
||||
<a [ngStyle]="{'color':token.quality=='Epic'?'#a335ee':'#ff8000'}"
|
||||
target="_blank"
|
||||
[href]="token.url">
|
||||
<img style="min-width: 25px; width: 2.25vw; max-width: 50px"
|
||||
[src]="'https://wow.zamimg.com/images/wow/icons/large/'+token.iconname+'.jpg'" />
|
||||
{{token.itemname}}
|
||||
</a><br />
|
||||
</span>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { LoginApiService } from '../../services/login-api';
|
||||
import { ApiService as ApiService } from '../../services/login-api';
|
||||
import { Spec, User, Character } from '../../../../../../backend/Types/Types';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
|
||||
@@ -12,22 +12,24 @@ export class FrontcraftCharacterComponent implements OnInit{
|
||||
|
||||
char : (Character & User & Spec) = {} as any
|
||||
color : string
|
||||
tokens
|
||||
|
||||
constructor(
|
||||
private login: LoginApiService,
|
||||
private api: ApiService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
){}
|
||||
|
||||
async ngOnInit(){
|
||||
const param = this.route.snapshot.paramMap.get('name');
|
||||
this.login.getUnprivilegedSocket()
|
||||
.CharacterManager
|
||||
this.api.get('CharacterManager')
|
||||
.getCharacterByName(param)
|
||||
.then((char) => {
|
||||
if(char){
|
||||
this.color = getClassColor(char.class)
|
||||
this.char = char
|
||||
this.api.get('ItemManager').getTokens(this.char).then(tokens => {
|
||||
this.tokens = tokens
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<nb-card class="col-12 col-xl-9">
|
||||
<nb-card-body>
|
||||
|
||||
<div echarts [options]="options" class="echart" (chartClick)="onChartClick($event)"></div>
|
||||
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
|
||||
|
||||
|
||||
|
||||
<nb-card class="col-12 col-xl-9">
|
||||
<nb-card-body>
|
||||
<input type="text" nbInput [(ngModel)]="search" (change)="changeSearch()" placeholder="Search" fullWidth="true" />
|
||||
<table class="col-12">
|
||||
<tr *ngFor="let character of displayedcharacters">
|
||||
<td>
|
||||
<a style="text-transform: capitalize;" [routerLink]="'/frontcraft/character/'+character.charactername" [ngStyle]="{'color': character.color}">
|
||||
{{character.charactername}} <span *ngIf="character.alt">(Alt)</span>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{{character.race}}
|
||||
</td>
|
||||
<td>
|
||||
{{character.specname}}
|
||||
</td>
|
||||
<td>
|
||||
{{character.class}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
@@ -0,0 +1,123 @@
|
||||
import { Component, OnInit, AfterViewInit, OnDestroy } from '@angular/core';
|
||||
import { NbThemeService } from '@nebular/theme';
|
||||
import { ApiService } from '../../services/login-api';
|
||||
import { _Class } from '../../../../../../backend/Types/Types';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'characters',
|
||||
templateUrl: './characters.component.html',
|
||||
})
|
||||
export class FrontcraftCharactersComponent implements AfterViewInit, OnDestroy{
|
||||
options: any = {};
|
||||
themeSubscription: any;
|
||||
search = ""
|
||||
|
||||
allcharacters = []
|
||||
displayedcharacters = []
|
||||
|
||||
constructor(private theme: NbThemeService, private api:ApiService) {
|
||||
}
|
||||
|
||||
changeSearch(){
|
||||
if(!this.search || this.search == "")
|
||||
this.displayedcharacters = this.allcharacters
|
||||
else{
|
||||
const searchterm = this.search.toLocaleLowerCase()
|
||||
this.displayedcharacters = this.allcharacters.filter(char =>
|
||||
char.charactername.toLowerCase().includes(searchterm) ||
|
||||
char.class.toLowerCase().includes(searchterm) ||
|
||||
char.specname.toLowerCase().includes(searchterm) ||
|
||||
char.race.toLowerCase().includes(searchterm)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
onChartClick(event){
|
||||
this.search = event.name
|
||||
this.changeSearch()
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.themeSubscription = this.theme.getJsTheme().subscribe(async config => {
|
||||
const data = {}
|
||||
|
||||
await this.api.get('CharacterManager').getCharacters().then(chars => {
|
||||
chars.forEach(char => {
|
||||
char['color'] = getClassColor(char.class)
|
||||
})
|
||||
this.allcharacters = chars
|
||||
this.displayedcharacters = chars
|
||||
this.search=""
|
||||
})
|
||||
|
||||
await Promise.all(_Class.map(async cls => {
|
||||
const c = await this.api.get('CharacterManager').getHeadCount(cls)
|
||||
data[cls] = c
|
||||
}))
|
||||
|
||||
const echarts: any = config.variables.echarts;
|
||||
this.options = {
|
||||
backgroundColor: echarts.bg,
|
||||
color: [
|
||||
"#FFF569",
|
||||
"#C79C6E",
|
||||
"#FFFFFF",
|
||||
"#40C7EB",
|
||||
"#A9D271",
|
||||
"#F58CBA",
|
||||
"#FF7D0A",
|
||||
"#8787ED"
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{b} : {c} ({d}%)',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Classes',
|
||||
type: 'pie',
|
||||
radius: '80%',
|
||||
center: ['50%', '50%'],
|
||||
data: [
|
||||
{ value: data['Rogue'], name: 'Rogue' },
|
||||
{ value: data['Warrior'], name: 'Warrior' },
|
||||
{ value: data['Priest'], name: 'Priest' },
|
||||
{ value: data['Mage'], name: 'Mage' },
|
||||
{ value: data['Hunter'], name: 'Hunter' },
|
||||
{ value: data['Paladin'], name: 'Paladin' },
|
||||
{ value: data['Druid'], name: 'Druid' },
|
||||
{ value: data['Warlock'], name: 'Warlock' },
|
||||
],
|
||||
itemStyle: {
|
||||
emphasis: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: echarts.itemHoverShadowColor,
|
||||
},
|
||||
},
|
||||
label: {
|
||||
normal: {
|
||||
textStyle: {
|
||||
color: echarts.textColor,
|
||||
},
|
||||
},
|
||||
},
|
||||
labelLine: {
|
||||
normal: {
|
||||
lineStyle: {
|
||||
color: echarts.axisLineColor,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.themeSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
<nb-card>
|
||||
<nb-card-body>
|
||||
|
||||
<label class="search-label" for="search">Search:</label>
|
||||
<input nbInput [nbFilterInput]="dataSource" id="search" class="search-input">
|
||||
|
||||
<table [nbTreeGrid]="dataSource" [nbSort]="dataSource" (sort)="updateSort($event)">
|
||||
|
||||
<tr nbTreeGridHeaderRow *nbTreeGridHeaderRowDef="allColumns"></tr>
|
||||
<tr nbTreeGridRow *nbTreeGridRowDef="let row; columns: allColumns"></tr>
|
||||
|
||||
<ng-container [nbTreeGridColumnDef]="customColumn">
|
||||
<th nbTreeGridHeaderCell [nbSortHeader]="getSortDirection(customColumn)" *nbTreeGridHeaderCellDef>
|
||||
{{customColumn}}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let row">
|
||||
<nb-tree-grid-row-toggle
|
||||
*ngIf="row.children && row.children.length">
|
||||
</nb-tree-grid-row-toggle>
|
||||
|
||||
{{row.data[customColumn]}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngFor="let column of defaultColumns; let index = index"
|
||||
[nbTreeGridColumnDef]="column"
|
||||
[showOn]="getShowOn(index)">
|
||||
<th nbTreeGridHeaderCell [nbSortHeader]="getSortDirection(column)" *nbTreeGridHeaderCellDef>
|
||||
{{column}}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let row">{{row.data[column] || '-'}}</td>
|
||||
</ng-container>
|
||||
</table>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
@@ -1,42 +0,0 @@
|
||||
button[nbTreeGridRowToggle] {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.search-label {
|
||||
display: block;
|
||||
}
|
||||
.search-input {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nb-column-name {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 400px) {
|
||||
.nb-column-name,
|
||||
.nb-column-size {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 500px) {
|
||||
.nb-column-name,
|
||||
.nb-column-size,
|
||||
.nb-column-kind {
|
||||
width: 33.333%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
.nb-column-name {
|
||||
width: 31%;
|
||||
}
|
||||
.nb-column-size,
|
||||
.nb-column-kind,
|
||||
.nb-column-items {
|
||||
width: 23%;
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { NbSortDirection, NbSortRequest, NbTreeGridDataSourceBuilder, NbTreeGridDataSource } from '@nebular/theme';
|
||||
|
||||
interface TreeNode<T> {
|
||||
data: T;
|
||||
children?: TreeNode<T>[];
|
||||
expanded?: boolean;
|
||||
}
|
||||
|
||||
interface Row {
|
||||
name: string,
|
||||
character: any,
|
||||
SRC: any,
|
||||
}
|
||||
|
||||
type TreeType = TreeNode<Row>
|
||||
|
||||
@Component({
|
||||
selector: 'dashboard',
|
||||
templateUrl: './dashboard.component.html',
|
||||
styleUrls: ['./tree-grid-shared.scss', './dashboard.component.scss'],
|
||||
})
|
||||
export class FrontcraftDashboardComponent{
|
||||
customColumn = 'name';
|
||||
defaultColumns = [ 'character', 'SRC'/*, 'Profile'*/ ];
|
||||
allColumns = [ this.customColumn, ...this.defaultColumns ];
|
||||
|
||||
dataSource: NbTreeGridDataSource<TreeType>;
|
||||
|
||||
sortColumn: string;
|
||||
sortDirection: NbSortDirection = NbSortDirection.NONE;
|
||||
|
||||
constructor(private dataSourceBuilder: NbTreeGridDataSourceBuilder<TreeType>) {
|
||||
this.dataSource = this.dataSourceBuilder.create(this.data);
|
||||
}
|
||||
|
||||
updateSort(sortRequest: NbSortRequest): void {
|
||||
this.sortColumn = sortRequest.column;
|
||||
this.sortDirection = sortRequest.direction;
|
||||
}
|
||||
|
||||
getSortDirection(column: string): NbSortDirection {
|
||||
if (this.sortColumn === column) {
|
||||
return this.sortDirection;
|
||||
}
|
||||
return NbSortDirection.NONE;
|
||||
}
|
||||
|
||||
private data: TreeType[] = [
|
||||
{
|
||||
data: {name: 'a', character: 2, SRC: 0},
|
||||
children: [
|
||||
{data: {name: 'a', character: 'Warrior', SRC: 'Arms'}}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
getShowOn(index: number) {
|
||||
const minWithForMultipleColumns = 400;
|
||||
const nextColumnStep = 100;
|
||||
return minWithForMultipleColumns + (nextColumnStep * index);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
::ng-deep {
|
||||
body {
|
||||
min-height: 20rem;
|
||||
}
|
||||
|
||||
.nb-tree-grid-header-cell,
|
||||
.nb-tree-grid-header-cell button {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, AfterContentChecked, OnInit } from '@angular/core';
|
||||
import { Component, AfterContentChecked, OnInit, AfterContentInit } from '@angular/core';
|
||||
import { NbMenuItem } from '@nebular/theme';
|
||||
import { LoginApiService } from '../services/login-api';
|
||||
import { ApiService } from '../services/login-api';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
@@ -9,35 +9,35 @@ import { Router } from '@angular/router';
|
||||
|
||||
<ngx-one-column-layout>
|
||||
<nb-menu [items]="menu"></nb-menu>
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
<router-outlet ></router-outlet>
|
||||
</ngx-one-column-layout>
|
||||
`,
|
||||
})
|
||||
export class PagesLayoutComponent implements OnInit{
|
||||
export class PagesLayoutComponent implements AfterContentInit{
|
||||
menu:NbMenuItem[] = [{
|
||||
icon: 'people-outline',
|
||||
title: 'People',
|
||||
link: '/frontcraft/people'
|
||||
icon: 'image',
|
||||
title: 'Raids',
|
||||
link: '/frontcraft/raids',
|
||||
},{
|
||||
icon: 'clock-outline',
|
||||
title: 'Raids'
|
||||
icon: 'people',
|
||||
title: 'Characters',
|
||||
link: '/frontcraft/characters',
|
||||
},{
|
||||
icon: 'clock-outline',
|
||||
title: 'character',
|
||||
link: '/frontcraft/character/a'
|
||||
icon: 'shopping-cart',
|
||||
title: 'Token Shop',
|
||||
link: '/frontcraft/shop',
|
||||
},{
|
||||
icon: 'clock-outline',
|
||||
title: 'user',
|
||||
link: '/frontcraft/user/a'
|
||||
icon: 'book-open-outline',
|
||||
title: 'Loot Rules',
|
||||
link: '/frontcraft/rules',
|
||||
}]
|
||||
|
||||
constructor(
|
||||
private loginSvc : LoginApiService,
|
||||
private loginSvc : ApiService,
|
||||
private router : Router
|
||||
){}
|
||||
|
||||
ngOnInit() : void {
|
||||
ngAfterContentInit() : void {
|
||||
this.loginSvc.checkLogin().then(loggedin => {
|
||||
if(!loggedin){
|
||||
this.router.navigateByUrl("/auth")
|
||||
|
||||
@@ -1,35 +1,55 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { FrontcraftDashboardComponent } from './dashboard/dashboard.component';
|
||||
import { PagesLayoutComponent } from './pages-layout.component';
|
||||
import { FrontcraftCharacterComponent } from './character/character.component';
|
||||
import { FrontcraftUserComponent } from './user/user.component';
|
||||
import { FrontcraftPeopleComponent } from './people/people.component';
|
||||
import { FrontcraftRaidsComponent } from './raids/raids.component';
|
||||
import { FrontcraftRaidComponent } from './raid/raid.component';
|
||||
import { FrontcraftArchiveComponent } from './raid/archive.component';
|
||||
import { FrontcraftShopComponent } from './shop/shop.component';
|
||||
import { FrontcraftRulesComponent } from './rules/rules.component';
|
||||
import { FrontcraftCharactersComponent } from './characters/characters.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: PagesLayoutComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'people',
|
||||
component: FrontcraftPeopleComponent
|
||||
},
|
||||
{
|
||||
path: 'user/:name',
|
||||
component: FrontcraftUserComponent
|
||||
},
|
||||
{
|
||||
path: 'raid/:id',
|
||||
component: FrontcraftRaidComponent
|
||||
},
|
||||
{
|
||||
path: 'archive/:id',
|
||||
component: FrontcraftArchiveComponent
|
||||
},
|
||||
{
|
||||
path: 'raids',
|
||||
component: FrontcraftRaidsComponent
|
||||
},
|
||||
{
|
||||
path: 'character/:name',
|
||||
component: FrontcraftCharacterComponent
|
||||
},
|
||||
{
|
||||
path: 'dashboard',
|
||||
component: FrontcraftDashboardComponent,
|
||||
path: 'characters',
|
||||
component: FrontcraftCharactersComponent,
|
||||
},
|
||||
{
|
||||
path: 'shop',
|
||||
component: FrontcraftShopComponent
|
||||
},
|
||||
{
|
||||
path: 'rules',
|
||||
component: FrontcraftRulesComponent
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
redirectTo: 'dashboard'
|
||||
redirectTo: 'raids'
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import {
|
||||
NbAlertModule,
|
||||
NbButtonModule,
|
||||
@@ -10,10 +9,16 @@ import {
|
||||
NbInputModule,
|
||||
NbMenuModule,
|
||||
NbCardModule,
|
||||
NbTreeGridModule
|
||||
NbTreeGridModule,
|
||||
NbListModule,
|
||||
NbTabsetModule,
|
||||
NbIconModule,
|
||||
NbWindowModule,
|
||||
NbPopoverModule,
|
||||
NbDatepickerModule,
|
||||
NbSelectModule
|
||||
} from '@nebular/theme';
|
||||
import { MyAuthRoutingModule } from './pages-routing.module';
|
||||
import { FrontcraftDashboardComponent } from './dashboard/dashboard.component';
|
||||
import { PagesLayoutComponent } from './pages-layout.component';
|
||||
import { ThemeModule } from '../../@theme/theme.module';
|
||||
import { DashboardModule } from '../../demo_pages/dashboard/dashboard.module';
|
||||
@@ -21,7 +26,17 @@ import { ECommerceModule } from '../../demo_pages/e-commerce/e-commerce.module';
|
||||
import { MiscellaneousModule } from '../../demo_pages/miscellaneous/miscellaneous.module';
|
||||
import { FrontcraftCharacterComponent } from './character/character.component';
|
||||
import { FrontcraftUserComponent } from './user/user.component';
|
||||
import { FrontcraftPeopleComponent } from './people/people.component';
|
||||
import { FrontcraftRaidsComponent } from './raids/raids.component';
|
||||
import { FrontcraftCreateRaidsComponent } from './raids/createraid.compontent';
|
||||
import { FrontcraftRaidComponent } from './raid/raid.component';
|
||||
import { FrontcraftArchiveComponent } from './raid/archive.component';
|
||||
import { NbEvaIconsModule } from '@nebular/eva-icons';
|
||||
import { FrontcraftCharacerpickerComponent } from './raid/characterpicker.component';
|
||||
import { FrontcraftShopComponent, FrontcraftBuyTokenComponent } from './shop/shop.component';
|
||||
import { FrontcraftRulesComponent } from './rules/rules.component';
|
||||
import { FrontcraftItemSelectComponent } from './shop/itemselector.component';
|
||||
import { NgxEchartsModule } from 'ngx-echarts';
|
||||
import { FrontcraftCharactersComponent } from './characters/characters.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
@@ -35,21 +50,43 @@ import { FrontcraftPeopleComponent } from './people/people.component';
|
||||
NbInputModule,
|
||||
NbButtonModule,
|
||||
NbCheckboxModule,
|
||||
NbTabsetModule,
|
||||
ThemeModule,
|
||||
NbMenuModule,
|
||||
DashboardModule,
|
||||
ECommerceModule,
|
||||
MiscellaneousModule,
|
||||
NbCardModule,
|
||||
|
||||
NbListModule,
|
||||
NbIconModule,
|
||||
NbEvaIconsModule,
|
||||
NbPopoverModule,
|
||||
NbDatepickerModule,
|
||||
NbSelectModule,
|
||||
NgxEchartsModule,
|
||||
NbWindowModule.forChild(),
|
||||
],
|
||||
declarations: [
|
||||
FrontcraftPeopleComponent,
|
||||
FrontcraftItemSelectComponent,
|
||||
FrontcraftRaidComponent,
|
||||
FrontcraftRaidsComponent,
|
||||
FrontcraftUserComponent,
|
||||
FrontcraftCharacterComponent,
|
||||
PagesLayoutComponent,
|
||||
FrontcraftDashboardComponent
|
||||
FrontcraftCharactersComponent,
|
||||
FrontcraftCharacerpickerComponent,
|
||||
FrontcraftArchiveComponent,
|
||||
FrontcraftShopComponent,
|
||||
FrontcraftRulesComponent,
|
||||
FrontcraftCreateRaidsComponent,
|
||||
FrontcraftBuyTokenComponent,
|
||||
],
|
||||
entryComponents: [
|
||||
FrontcraftItemSelectComponent,
|
||||
FrontcraftCharacerpickerComponent,
|
||||
FrontcraftCreateRaidsComponent,
|
||||
FrontcraftBuyTokenComponent,
|
||||
]
|
||||
})
|
||||
export class FrontcraftPagesModule {
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<nb-card>
|
||||
<nb-card-body>
|
||||
|
||||
<label class="search-label" for="search">Search:</label>
|
||||
<input nbInput [nbFilterInput]="dataSource" id="search" class="search-input">
|
||||
|
||||
<table [nbTreeGrid]="dataSource" [nbSort]="dataSource" (sort)="updateSort($event)">
|
||||
|
||||
<tr nbTreeGridHeaderRow *nbTreeGridHeaderRowDef="allColumns"></tr>
|
||||
<tr nbTreeGridRow *nbTreeGridRowDef="let row; columns: allColumns"></tr>
|
||||
|
||||
<ng-container [nbTreeGridColumnDef]="customColumn">
|
||||
<th nbTreeGridHeaderCell [nbSortHeader]="getSortDirection(customColumn)" *nbTreeGridHeaderCellDef>
|
||||
{{customColumn}}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let row">
|
||||
<nb-tree-grid-row-toggle
|
||||
*ngIf="row.children && row.children.length">
|
||||
</nb-tree-grid-row-toggle>
|
||||
<span style="text-transform: capitalize;">
|
||||
{{row.data[customColumn]}}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngFor="let column of defaultColumns; let index = index"
|
||||
[nbTreeGridColumnDef]="column"
|
||||
[showOn]="getShowOn(index)">
|
||||
<th nbTreeGridHeaderCell [nbSortHeader]="getSortDirection(column)" *nbTreeGridHeaderCellDef>
|
||||
{{column}}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let row">{{row.data[column] || '-'}}</td>
|
||||
</ng-container>
|
||||
</table>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
@@ -1,42 +0,0 @@
|
||||
button[nbTreeGridRowToggle] {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.search-label {
|
||||
display: block;
|
||||
}
|
||||
.search-input {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nb-column-name {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 400px) {
|
||||
.nb-column-name,
|
||||
.nb-column-size {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 500px) {
|
||||
.nb-column-name,
|
||||
.nb-column-size,
|
||||
.nb-column-kind {
|
||||
width: 33.333%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
.nb-column-name {
|
||||
width: 31%;
|
||||
}
|
||||
.nb-column-size,
|
||||
.nb-column-kind,
|
||||
.nb-column-items {
|
||||
width: 23%;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { NbSortDirection, NbSortRequest, NbTreeGridDataSourceBuilder, NbTreeGridDataSource } from '@nebular/theme';
|
||||
|
||||
interface TreeNode<T> {
|
||||
data: T;
|
||||
children?: TreeNode<T>[];
|
||||
expanded?: boolean;
|
||||
}
|
||||
|
||||
interface Row {
|
||||
name: string,
|
||||
character: any,
|
||||
SRC: any,
|
||||
kind: 'Character' | 'Account'
|
||||
}
|
||||
|
||||
type TreeType = TreeNode<Row>
|
||||
|
||||
@Component({
|
||||
selector: 'people-component',
|
||||
templateUrl: './people.component.html',
|
||||
styleUrls: ['./tree-grid-shared.scss', './people.component.scss'],
|
||||
})
|
||||
export class FrontcraftPeopleComponent{
|
||||
customColumn = 'name';
|
||||
defaultColumns = [ 'character', 'SRC'/*, 'Profile'*/ ];
|
||||
allColumns = [ this.customColumn, ...this.defaultColumns ];
|
||||
|
||||
dataSource: NbTreeGridDataSource<TreeType>;
|
||||
|
||||
sortColumn: string;
|
||||
sortDirection: NbSortDirection = NbSortDirection.NONE;
|
||||
|
||||
constructor(private dataSourceBuilder: NbTreeGridDataSourceBuilder<TreeType>) {
|
||||
this.dataSource = this.dataSourceBuilder.create(this.data);
|
||||
}
|
||||
|
||||
updateSort(sortRequest: NbSortRequest): void {
|
||||
this.sortColumn = sortRequest.column;
|
||||
this.sortDirection = sortRequest.direction;
|
||||
}
|
||||
|
||||
getSortDirection(column: string): NbSortDirection {
|
||||
if (this.sortColumn === column) {
|
||||
return this.sortDirection;
|
||||
}
|
||||
return NbSortDirection.NONE;
|
||||
}
|
||||
|
||||
private data: TreeType[] = [
|
||||
{
|
||||
data: {name: 'a', character: 2, SRC: 0, kind: 'Account'},
|
||||
children: [
|
||||
{data: {name: 'a', character: 'Warrior', SRC: 'Arms', kind: 'Character'}}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
getShowOn(index: number) {
|
||||
const minWithForMultipleColumns = 400;
|
||||
const nextColumnStep = 100;
|
||||
return minWithForMultipleColumns + (nextColumnStep * index);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
::ng-deep {
|
||||
body {
|
||||
min-height: 20rem;
|
||||
}
|
||||
|
||||
.nb-tree-grid-header-cell,
|
||||
.nb-tree-grid-header-cell button {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ApiService as ApiService } from '../../services/login-api';
|
||||
import { RaidData } from '../../../../../../backend/Types/Types';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
|
||||
@Component({
|
||||
selector: 'archive',
|
||||
templateUrl: './raid.component.html',
|
||||
})
|
||||
export class FrontcraftArchiveComponent implements OnInit{
|
||||
|
||||
canSignup = false
|
||||
isSignedup = false
|
||||
canManage = false
|
||||
mySignup
|
||||
|
||||
raid: RaidData = <any>{
|
||||
participants:{
|
||||
Druid: [],
|
||||
Hunter: [],
|
||||
Mage: [],
|
||||
Paladin: [],
|
||||
Priest: [],
|
||||
Rogue: [],
|
||||
Shaman: [],
|
||||
Warlock: [],
|
||||
Warrior: [],
|
||||
},
|
||||
tokens:{}
|
||||
}
|
||||
|
||||
constructor(
|
||||
private api: ApiService,
|
||||
private route: ActivatedRoute,
|
||||
){
|
||||
}
|
||||
|
||||
async ngOnInit(){
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
refresh = async () => {
|
||||
const param = this.route.snapshot.paramMap.get('id');
|
||||
|
||||
const raidManager = this.api.get('RaidManager')
|
||||
const raiddata = await raidManager.getArchiveRaid(parseInt(param))
|
||||
this.raid = raiddata
|
||||
|
||||
Object.values(raiddata.participants).flat().forEach(p => {
|
||||
p['color'] = getClassColor(p.class)
|
||||
})
|
||||
|
||||
const matchingSignup = Object.values(raiddata.participants).flat().find(char => char.userid === this.api.getCurrentUser()!.id!)
|
||||
if(matchingSignup){
|
||||
this.isSignedup = true
|
||||
this.mySignup = matchingSignup
|
||||
this.mySignup.status = matchingSignup['benched']?'Bench':matchingSignup['late']?'Late':'Attending'
|
||||
}else{
|
||||
this.isSignedup = false
|
||||
this.mySignup = null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<nb-card class="col-12 col-xl-9">
|
||||
<nb-card-header>
|
||||
Pick Character
|
||||
</nb-card-header>
|
||||
<nb-card-body>
|
||||
<div *ngFor="let character of characters">
|
||||
<button
|
||||
(click)="signup(character, false)"
|
||||
nbButton
|
||||
outline
|
||||
status="success"
|
||||
size="tiny">
|
||||
<nb-icon icon="checkmark-outline"></nb-icon>
|
||||
</button>
|
||||
|
||||
<button
|
||||
(click)="signup(character, true)"
|
||||
nbButton
|
||||
outline
|
||||
status="warning"
|
||||
size="tiny">
|
||||
<nb-icon icon="clock-outline"></nb-icon>
|
||||
</button>
|
||||
<span [ngStyle]="{'color': character.color}">
|
||||
{{character.charactername}}
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
@@ -0,0 +1,44 @@
|
||||
import { OnInit, Component } from '@angular/core';
|
||||
import { NbWindowRef, NbToastrService, NbDialogRef } from '@nebular/theme';
|
||||
import { RaidData, Character } from '../../../../../../backend/Types/Types';
|
||||
import { ApiService } from '../../services/login-api';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
|
||||
@Component({
|
||||
selector: 'characterpicker',
|
||||
templateUrl: './characterpicker.component.html',
|
||||
})
|
||||
export class FrontcraftCharacerpickerComponent implements OnInit{
|
||||
|
||||
raid : RaidData
|
||||
characters: Character[]
|
||||
|
||||
constructor(
|
||||
protected dialogRef: NbDialogRef<FrontcraftCharacerpickerComponent>,
|
||||
private api : ApiService,
|
||||
private toast : NbToastrService
|
||||
){}
|
||||
|
||||
signup = async (character: Character, late: boolean) => {
|
||||
const auth = this.api.getAuth()
|
||||
const signup = this.api.get('signup')
|
||||
if(!signup) return
|
||||
|
||||
await signup.sign(auth.token.value, character, this.raid, late)
|
||||
this.toast.show('Signup', 'Success', { status: 'success' })
|
||||
this.dialogRef.close()
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
const usr = this.api.getCurrentUser()
|
||||
this.api.get('CharacterManager')
|
||||
.getCharactersOfUser(usr.username)
|
||||
.then(chars => {
|
||||
chars.forEach(char => {
|
||||
char['color'] = getClassColor(char.class)
|
||||
})
|
||||
this.characters = chars
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<nb-card class="col-12 col-xl-9">
|
||||
<nb-card-body>
|
||||
<nb-tabset>
|
||||
<nb-tab tabTitle="Info">
|
||||
<h1>{{raid.title}}</h1>
|
||||
<p>
|
||||
{{raid.signupcount}} / {{raid.size}} signups
|
||||
</p>
|
||||
<p>
|
||||
{{raid.description}}
|
||||
</p>
|
||||
<div *ngIf="canSignup">
|
||||
<div *ngIf="isSignedup">
|
||||
|
||||
<p>
|
||||
You are signed as: {{mySignup.charactername}} ({{mySignup.race}} {{mySignup.specname}} {{mySignup.class}})<br />
|
||||
Status: {{mySignup.status}}
|
||||
</p>
|
||||
|
||||
<button
|
||||
(click)="unsign()"
|
||||
nbButton
|
||||
outline
|
||||
status="danger"
|
||||
size="medium">
|
||||
unsign
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="!isSignedup">
|
||||
<button
|
||||
(click)="signup()"
|
||||
nbButton
|
||||
outline
|
||||
status="success"
|
||||
size="medium">
|
||||
signup
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nb-tab>
|
||||
|
||||
<nb-tab tabTitle="Signups"
|
||||
[badgeText]="raid.signupcount"
|
||||
badgePosition="top right"
|
||||
[badgeStatus]="raid.signupcount<40?'warning':'success'">
|
||||
<div class="row">
|
||||
<ng-container *ngFor="let group of raid.participants | keyvalue">
|
||||
<nb-card
|
||||
class="col-12 col-md-6 col-xl-4"
|
||||
*ngIf="group.value.length > 0">
|
||||
<nb-card-header>{{group.key}} ({{group.value.length}})</nb-card-header>
|
||||
<nb-card-body>
|
||||
<div *ngFor="let participant of group.value">
|
||||
<button
|
||||
(click)="setBench(participant)"
|
||||
*ngIf="manageRaid"
|
||||
nbButton
|
||||
outline
|
||||
status="warning"
|
||||
size="tiny">
|
||||
B
|
||||
</button>
|
||||
<a [ngStyle]="{'color': participant.color}" style="text-transform: capitalize;"
|
||||
[routerLink]="'/frontcraft/character/'+participant.charactername">
|
||||
{{ participant.charactername }}
|
||||
</a>
|
||||
</div>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
|
||||
</ng-container>
|
||||
</div>
|
||||
</nb-tab>
|
||||
<nb-tab tabTitle="Reserves">
|
||||
<nb-list>
|
||||
<nb-list-item *ngFor="let item of raid.tokens | keyvalue">
|
||||
|
||||
<a [ngStyle]="{'color':item.value[0].quality=='Epic'?'#a335ee':'#ff8000'}"
|
||||
target="_blank"
|
||||
[href]="item.value[0].url">
|
||||
<img style="min-width: 25px; width: 2.25vw; max-width: 50px"
|
||||
[src]="'https://wow.zamimg.com/images/wow/icons/large/'+item.value[0].iconname+'.jpg'" />
|
||||
|
||||
{{item.key}}
|
||||
</a><br />
|
||||
<div class="row">
|
||||
<div *ngFor="let token of item.value" class="col-12 col-md-6 col-xl-4">
|
||||
[ {{token.level}} ]
|
||||
<span style="text-transform: capitalize;" [ngStyle]="{'color':token.level>=10?'#ff8000':token.level>=8?'#a335ee':token.level>=6?'#0070dd':token.level>=4?'#1eff00':token.level>=2?'#ffffff':'#9d9d9d'}">
|
||||
{{token.charactername}}
|
||||
</span><br />
|
||||
</div>
|
||||
</div>
|
||||
</nb-list-item>
|
||||
</nb-list>
|
||||
</nb-tab>
|
||||
<nb-tab tabTitle="Admin" *ngIf="manageRaid">
|
||||
<button
|
||||
(click)="startRaid(raid)"
|
||||
nbButton
|
||||
outline
|
||||
status="success"
|
||||
size="medium">
|
||||
start
|
||||
</button>
|
||||
|
||||
<button
|
||||
(click)="archiveRaid(raid)"
|
||||
nbButton
|
||||
outline
|
||||
status="danger"
|
||||
size="medium">
|
||||
archive
|
||||
</button>
|
||||
</nb-tab>
|
||||
</nb-tabset>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ApiService as ApiService } from '../../services/login-api';
|
||||
import { RaidData, Raid, Signup } from '../../../../../../backend/Types/Types';
|
||||
import { NbWindowService, NbToastrService, NbDialogService } from '@nebular/theme';
|
||||
import { FrontcraftCharacerpickerComponent } from './characterpicker.component';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
|
||||
@Component({
|
||||
selector: 'raid',
|
||||
templateUrl: './raid.component.html',
|
||||
})
|
||||
export class FrontcraftRaidComponent implements OnInit{
|
||||
|
||||
canSignup = false
|
||||
isSignedup = false
|
||||
manageRaid
|
||||
mySignup
|
||||
|
||||
raid: RaidData = <any>{
|
||||
participants:{
|
||||
Druid: [],
|
||||
Hunter: [],
|
||||
Mage: [],
|
||||
Paladin: [],
|
||||
Priest: [],
|
||||
Rogue: [],
|
||||
Shaman: [],
|
||||
Warlock: [],
|
||||
Warrior: [],
|
||||
},
|
||||
tokens:{}
|
||||
}
|
||||
|
||||
constructor(
|
||||
private api: ApiService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private dialogService : NbDialogService,
|
||||
private toast: NbToastrService
|
||||
){
|
||||
window['r'] = this
|
||||
}
|
||||
|
||||
async ngOnInit(){
|
||||
this.manageRaid = this.api.get('manageRaid')
|
||||
|
||||
const signupFeature = this.api.get('signup')
|
||||
if(signupFeature){
|
||||
this.canSignup = true
|
||||
}
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
signup = async () => {
|
||||
const signupFeature = this.api.get('signup')
|
||||
if(!signupFeature) return
|
||||
|
||||
this.dialogService.open(FrontcraftCharacerpickerComponent, {
|
||||
closeOnBackdropClick: true,
|
||||
closeOnEsc: true,
|
||||
context: {
|
||||
'raid': this.raid,
|
||||
}
|
||||
}).onClose.subscribe(()=>{
|
||||
this.refresh()
|
||||
});
|
||||
}
|
||||
|
||||
async archiveRaid(raid:Raid){
|
||||
await this.manageRaid!.archiveRaid(raid)
|
||||
this.toast.show('Raid archived', 'Success', { status: 'success' })
|
||||
this.router.navigateByUrl('/frontcraft/archive/'+raid.id)
|
||||
}
|
||||
|
||||
async startRaid(raid:Raid){
|
||||
await this.manageRaid!.startRaid(raid)
|
||||
this.toast.show('Raid started', 'Success', { status: 'success' })
|
||||
this.router.navigateByUrl('/frontcraft/archive/'+raid.id)
|
||||
}
|
||||
|
||||
unsign = async () => {
|
||||
const signupFeature = this.api.get('signup')
|
||||
if(!signupFeature) return
|
||||
|
||||
await signupFeature.unsign(this.api.getAuth().token.value, this.mySignup, this.raid)
|
||||
this.toast.show('Success', 'Unsigned', { status: 'success' })
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
refresh = async () => {
|
||||
const param = this.route.snapshot.paramMap.get('id');
|
||||
|
||||
const raidManager = this.api.get('RaidManager')
|
||||
const raiddata = await raidManager.getRaidData(<any>{
|
||||
id: param
|
||||
})
|
||||
this.raid = raiddata
|
||||
|
||||
Object.values(raiddata.participants).flat().forEach(p => {
|
||||
p['color'] = getClassColor(p.class)
|
||||
})
|
||||
const user = this.api.getCurrentUser()
|
||||
const matchingSignup = Object.values(raiddata.participants).flat().find(char => user && char.userid === user.id!)
|
||||
if(matchingSignup){
|
||||
this.isSignedup = true
|
||||
this.mySignup = matchingSignup
|
||||
this.mySignup.status = matchingSignup['benched']?'Bench':matchingSignup['late']?'Late':'Attending'
|
||||
}else{
|
||||
this.isSignedup = false
|
||||
this.mySignup = null
|
||||
}
|
||||
}
|
||||
|
||||
setBench(signup:Signup){
|
||||
this.manageRaid.setBenched({
|
||||
characterid: signup.characterid,
|
||||
raidid: signup.raidid,
|
||||
late: false,
|
||||
benched: !signup.benched
|
||||
}).then(_ => this.refresh())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
|
||||
<nb-card class="col-12 col-xl-9">
|
||||
<nb-card-header>
|
||||
Create Raid
|
||||
</nb-card-header>
|
||||
<nb-select [(selected)]="template" placeholder="copy from" (selectedChange)="onTemplateSelect()">
|
||||
<nb-option *ngFor="let template of templates" [value]="template">{{template.title}} {{template.start| date : 'd MMMM'}}</nb-option>
|
||||
</nb-select>
|
||||
|
||||
<input type="text" nbInput [(ngModel)]="title" placeholder="Title" fullWidth="true">
|
||||
<input type="number" nbInput [(ngModel)]="size" placeholder="size" fullWidth="true">
|
||||
<textarea nbInput fullWidth [(ngModel)]="description" placeholder="description" fullWidth="true"></textarea>
|
||||
<input [nbDatepicker]="datepicker" [(ngModel)]="startdate">
|
||||
<nb-datepicker #datepicker></nb-datepicker>
|
||||
|
||||
<input type="number" nbInput [(ngModel)]="hour" placeholder="hour" fullWidth="true">
|
||||
<input type="number" nbInput [(ngModel)]="minute" placeholder="minute" fullWidth="true">
|
||||
|
||||
<button
|
||||
(click)="submit()"
|
||||
nbButton
|
||||
outline
|
||||
status="success"
|
||||
size="medium">
|
||||
submit
|
||||
</button>
|
||||
</nb-card>
|
||||
@@ -0,0 +1,59 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApiService } from '../../services/login-api';
|
||||
import { Raid, RaidData } from '../../../../../../backend/Types/Types';
|
||||
import { NbWindowRef, NbDialogRef } from '@nebular/theme';
|
||||
|
||||
const ONE_MINUTE = 60000
|
||||
const ONE_HOUR = 60 * ONE_MINUTE
|
||||
|
||||
@Component({
|
||||
selector: 'createraid',
|
||||
templateUrl: 'createraid.component.html',
|
||||
})
|
||||
export class FrontcraftCreateRaidsComponent implements OnInit {
|
||||
|
||||
templates :RaidData[]
|
||||
template :RaidData
|
||||
|
||||
title = ""
|
||||
startdate = new Date()
|
||||
hour = 20
|
||||
minute = 0
|
||||
size = 40
|
||||
description = ""
|
||||
|
||||
constructor(
|
||||
protected dialogRef: NbDialogRef<FrontcraftCreateRaidsComponent>,
|
||||
private api: ApiService
|
||||
) {}
|
||||
|
||||
loadNext(cardData) {
|
||||
}
|
||||
|
||||
onTemplateSelect(){
|
||||
const templateDate = new Date(this.template.start)
|
||||
this.title = this.template.title
|
||||
this.hour = templateDate.getHours()
|
||||
this.minute = templateDate.getMinutes()
|
||||
this.description = this.template.description
|
||||
this.startdate = new Date(parseInt(this.template.start) - templateDate.getHours()*ONE_HOUR - templateDate.getMinutes()*ONE_MINUTE)
|
||||
}
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
}
|
||||
|
||||
async submit(){
|
||||
const raid = <Raid>{
|
||||
description: this.description,
|
||||
size: this.size,
|
||||
start: ""+new Date(this.startdate.getTime() + this.hour*ONE_HOUR + this.minute*ONE_MINUTE).getTime(),
|
||||
title: this.title,
|
||||
}
|
||||
const manage = this.api.get('manageRaid')
|
||||
if(!manage) return
|
||||
|
||||
await manage.createRaid(raid)
|
||||
this.dialogRef.close()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<nb-card class="col-12 col-xl-9">
|
||||
<nb-card-header>
|
||||
Upcoming raids
|
||||
<nb-icon
|
||||
style="color:orange"
|
||||
*ngIf="manageRaid"
|
||||
(click)="create()"
|
||||
icon="plus-square-outline"></nb-icon>
|
||||
</nb-card-header>
|
||||
<nb-list
|
||||
nbInfiniteList
|
||||
listenWindowScroll
|
||||
[threshold]="500">
|
||||
<nb-list-item *ngFor="let raid of raids" [routerLink]="'/frontcraft/raid/'+raid.id">
|
||||
<b>{{raid.title}}</b><br>
|
||||
{{raid.signupcount}} / {{raid.size}}<br>
|
||||
{{raid.start | date : 'EEEE d MMMM @ HH:mm'}}<br>
|
||||
{{raid.description}}<br>
|
||||
</nb-list-item>
|
||||
</nb-list>
|
||||
</nb-card>
|
||||
|
||||
<nb-card class="col-12 col-xl-9">
|
||||
<nb-card-header>Previous raids</nb-card-header>
|
||||
<nb-list
|
||||
nbInfiniteList
|
||||
listenWindowScroll
|
||||
[threshold]="500">
|
||||
<nb-list-item *ngFor="let raid of oldraids" [routerLink]="'/frontcraft/archive/'+raid.id">
|
||||
<b>{{raid.title}}</b><br>
|
||||
{{raid.signupcount}} / {{raid.size}}<br>
|
||||
{{raid.start | date : 'EEEE d MMMM @ HH:mm'}}<br>
|
||||
{{raid.description}}<br>
|
||||
</nb-list-item>
|
||||
</nb-list>
|
||||
</nb-card>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.infinite-cards {
|
||||
nb-card {
|
||||
&.own-scroll {
|
||||
height: 50vh;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApiService } from '../../services/login-api';
|
||||
import { NbWindowService, NbDialogService } from '@nebular/theme';
|
||||
import { FrontcraftCreateRaidsComponent } from './createraid.compontent';
|
||||
|
||||
@Component({
|
||||
selector: 'raids',
|
||||
templateUrl: 'raids.component.html',
|
||||
styleUrls: ['raids.component.scss'],
|
||||
})
|
||||
export class FrontcraftRaidsComponent implements OnInit{
|
||||
|
||||
|
||||
manageRaid
|
||||
raids = []
|
||||
oldraids = []
|
||||
pageSize = 10;
|
||||
|
||||
constructor(
|
||||
private api: ApiService,
|
||||
private dialogService: NbDialogService
|
||||
) {
|
||||
this.manageRaid = this.api.get('manageRaid')
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.api.get('RaidManager').getRaids().then(raids => {
|
||||
this.raids = raids
|
||||
})
|
||||
|
||||
const raidManager = this.api.get('RaidManager')
|
||||
raidManager.getPastRaids(10).then(raiddata => {
|
||||
this.oldraids = raiddata
|
||||
})
|
||||
}
|
||||
|
||||
create(){
|
||||
this.dialogService.open(FrontcraftCreateRaidsComponent, {
|
||||
closeOnBackdropClick: true,
|
||||
closeOnEsc: true,
|
||||
context: {
|
||||
templates: this.oldraids
|
||||
}
|
||||
}).onClose.subscribe(()=>{
|
||||
this.refresh()
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<nb-card class="col-12 col-xl-9">
|
||||
<nb-card-body>
|
||||
<nb-tabset>
|
||||
<nb-tab tabTitle="Info">
|
||||
Smart text here
|
||||
</nb-tab>
|
||||
<nb-tab *ngIf="managePriorities" tabTitle="priorities">
|
||||
<nb-list>
|
||||
<nb-list-item *ngFor="let item of rules | keyvalue">
|
||||
<a [ngStyle]="{'color':item.value[0].quality=='Epic'?'#a335ee':'#ff8000'}"
|
||||
target="_blank"
|
||||
[href]="item.value[0].url">
|
||||
<img style="min-width: 25px; width: 2.25vw; max-width: 50px"
|
||||
[src]="'https://wow.zamimg.com/images/wow/icons/large/'+item.value[0].iconname+'.jpg'" />
|
||||
|
||||
{{item.key}}
|
||||
</a><br />
|
||||
|
||||
<span *ngFor="let rule of item.value" [nbPopover]="templateRef" nbPopoverTrigger="hover">
|
||||
<ng-template #templateRef>
|
||||
<span style="color:white">{{rule.description}}</span>
|
||||
</ng-template>
|
||||
+{{rule.modifier}} {{rule.race}} <span [ngStyle]="{'color':rule.color}">{{rule.specname}} {{rule.class}}</span> <br />
|
||||
</span>
|
||||
</nb-list-item>
|
||||
</nb-list>
|
||||
</nb-tab>
|
||||
</nb-tabset>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApiService as ApiService } from '../../services/login-api';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
|
||||
@Component({
|
||||
selector: 'rules',
|
||||
templateUrl: './rules.component.html',
|
||||
})
|
||||
export class FrontcraftRulesComponent implements OnInit{
|
||||
|
||||
managePriorities
|
||||
rules = {}
|
||||
|
||||
constructor(
|
||||
private api: ApiService,
|
||||
){
|
||||
}
|
||||
|
||||
async ngOnInit(){
|
||||
this.api.get('ItemManager').getAllPriorities().then(prios => prios.forEach(prio => {
|
||||
if(!this.rules[prio.itemname]){
|
||||
this.rules[prio.itemname] = []
|
||||
}
|
||||
prio['color'] = getClassColor(prio.class) || '#FFFFFF'
|
||||
this.rules[prio.itemname].push(prio)
|
||||
}))
|
||||
|
||||
const managePriorities = this.api.get('managePriorities')
|
||||
this.managePriorities = managePriorities
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
|
||||
<input type="text" nbInput [(ngModel)]="search" (change)="changeSearch()" placeholder="Search" fullWidth="true">
|
||||
<nb-list
|
||||
nbInfiniteList
|
||||
listenWindowScroll>
|
||||
<nb-list-item *ngFor="let item of displayedItems">
|
||||
<button
|
||||
(click)="select(item)"
|
||||
nbButton
|
||||
outline
|
||||
status="info"
|
||||
size="tiny">
|
||||
select
|
||||
</button>
|
||||
|
||||
<a target="_blank" [href]="item.url">
|
||||
<span [ngStyle]="{'color':item.quality=='Epic'?'#a335ee':'#ff8000'}">
|
||||
<img style="min-width: 20px; width: 2.25vw; max-width: 35px"
|
||||
[src]="'https://wow.zamimg.com/images/wow/icons/large/'+item.iconname+'.jpg'" />
|
||||
|
||||
{{item.itemname}}
|
||||
</span>
|
||||
</a>
|
||||
</nb-list-item>
|
||||
</nb-list>
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApiService } from '../../services/login-api';
|
||||
import { Item } from '../../../../../../backend/Types/Types';
|
||||
|
||||
@Component({
|
||||
selector: 'itemselect',
|
||||
templateUrl: './itemselect.component.html',
|
||||
})
|
||||
export class FrontcraftItemSelectComponent implements OnInit{
|
||||
|
||||
selected: Item
|
||||
search: string
|
||||
items: any[]
|
||||
displayedItems: any[]
|
||||
|
||||
callbacks = []
|
||||
|
||||
constructor(
|
||||
private api: ApiService,
|
||||
){
|
||||
}
|
||||
|
||||
async ngOnInit(){
|
||||
this.api.get('ItemManager').getItems().then(items => {
|
||||
this.items = items
|
||||
this.displayedItems = items
|
||||
})
|
||||
}
|
||||
|
||||
changeSearch(){
|
||||
if(!this.search || this.search == "")
|
||||
this.displayedItems = this.items
|
||||
else
|
||||
this.displayedItems = this.items.filter(it => it.itemname.toLowerCase().includes(this.search.toLowerCase()))
|
||||
}
|
||||
|
||||
select(item: Item){
|
||||
this.selected = item
|
||||
this.callbacks.forEach(cb => cb(item))
|
||||
}
|
||||
|
||||
onselect(callback:Function){
|
||||
this.callbacks.push(callback)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
<nb-card class="col-12 col-xl-9">
|
||||
<nb-card-body>
|
||||
<nb-tabset>
|
||||
<nb-tab tabTitle="Items">
|
||||
<itemselect></itemselect>
|
||||
</nb-tab>
|
||||
<nb-tab tabTitle="About">
|
||||
</nb-tab>
|
||||
</nb-tabset>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
import { Component, OnInit, ContentChild, AfterContentInit, ViewChild, AfterViewInit } from '@angular/core';
|
||||
import { ApiService as ApiService } from '../../services/login-api';
|
||||
import { FrontcraftItemSelectComponent } from './itemselector.component';
|
||||
import { NbWindowService, NbWindowRef, NbToastrService, NbDialogService, NbDialogRef } from '@nebular/theme';
|
||||
import { Item, Character, SRToken } from '../../../../../../backend/Types/Types';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
|
||||
@Component({
|
||||
selector: 'shop',
|
||||
templateUrl: './shop.component.html',
|
||||
})
|
||||
export class FrontcraftShopComponent implements AfterViewInit{
|
||||
|
||||
@ViewChild(FrontcraftItemSelectComponent, {static: false})
|
||||
itemselect !: FrontcraftItemSelectComponent
|
||||
|
||||
constructor(
|
||||
private api: ApiService,
|
||||
private dialogService : NbDialogService
|
||||
|
||||
){
|
||||
window['shop'] = this
|
||||
}
|
||||
|
||||
buy = (item) => {
|
||||
|
||||
this.dialogService.open(FrontcraftBuyTokenComponent, {
|
||||
closeOnBackdropClick: true,
|
||||
closeOnEsc: true,
|
||||
context: {
|
||||
item: item
|
||||
}
|
||||
}).onClose.subscribe(()=>{
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
ngAfterViewInit(){
|
||||
this.itemselect.onselect(this.buy)
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'buyToken',
|
||||
template: `
|
||||
<nb-card class="col-12 col-xl-9">
|
||||
<nb-card-header>
|
||||
Buy {{item.itemname}}
|
||||
</nb-card-header>
|
||||
<nb-card-body>
|
||||
<p>
|
||||
You currently have {{currency}} softreserve currency
|
||||
</p>
|
||||
<div *ngIf="currency>0">
|
||||
<div *ngFor="let kv of modifier | keyvalue">
|
||||
<button
|
||||
(click)="buyToken(kv.key)"
|
||||
[disabled]="currency<=0"
|
||||
nbButton
|
||||
outline
|
||||
status="success"
|
||||
size="tiny">
|
||||
buy
|
||||
</button>
|
||||
{{kv.key}} <span *ngIf="kv.value>0">(<b>+{{kv.value}}</b> from priorities)</span>
|
||||
</div>
|
||||
<div *ngFor="let token of ownedtokens">
|
||||
<button
|
||||
(click)="buyToken(token.charactername)"
|
||||
nbButton
|
||||
outline
|
||||
status="success"
|
||||
size="tiny">
|
||||
buy
|
||||
</button>
|
||||
{{token.charactername}} [ {{token.level}} ] => [ {{token.level+1}} ]
|
||||
</div>
|
||||
</div>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
|
||||
`,
|
||||
})
|
||||
export class FrontcraftBuyTokenComponent implements OnInit{
|
||||
|
||||
item : Item
|
||||
characters: Character[]
|
||||
modifier = {}
|
||||
currency: number = 0
|
||||
ownedtokens: SRToken[] = []
|
||||
|
||||
constructor(
|
||||
private toastr: NbToastrService,
|
||||
protected dialogRef: NbDialogRef<FrontcraftBuyTokenComponent>,
|
||||
private api : ApiService
|
||||
){}
|
||||
|
||||
ngOnInit(): void {
|
||||
const usr = this.api.getCurrentUser()
|
||||
this.api.get('CharacterManager')
|
||||
.getCharactersOfUser(usr.username)
|
||||
.then(chars => {
|
||||
chars.forEach(char => {
|
||||
char['color'] = getClassColor(char.class)
|
||||
this.api.get('ItemManager').getToken(char, this.item).then(token => {
|
||||
if(token) this.ownedtokens.push(token)
|
||||
else{
|
||||
this.api.get('ItemManager').calculatePriorities(this.item.itemname, char).then(modifier => {
|
||||
this.modifier[char.charactername] = modifier
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
this.characters = chars
|
||||
})
|
||||
this.api.get('UserManager').getUser(usr.username).then(u => {
|
||||
if(!u) return
|
||||
this.currency = u.currency
|
||||
})
|
||||
}
|
||||
|
||||
buyToken = async (charactername:string) => {
|
||||
|
||||
const src = this.api.get('ItemManager')
|
||||
const token = await src.buyToken(this.api.getAuth().token.value, charactername, this.item.itemname)
|
||||
|
||||
|
||||
if(token){
|
||||
this.toastr.show(token.characterid+' now has a token for '+token.itemname+' of level '+token.level, 'Yay', {status: 'success'})
|
||||
}else{
|
||||
this.toastr.show('Error (something went wrong)', 'Oh no', {status: 'danger'})
|
||||
}
|
||||
this.dialogRef.close()
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
|
||||
|
||||
<nb-card
|
||||
<nb-card class="col-xl-9"
|
||||
accent="info">
|
||||
<nb-card-header>
|
||||
<h2 style="text-transform: capitalize;">{{user.username}}</h2>
|
||||
</nb-card-header>
|
||||
<nb-card-body>
|
||||
{{user.currency}}
|
||||
<nb-card
|
||||
accent="control"
|
||||
*ngFor="let char of characters">
|
||||
@@ -17,7 +18,20 @@ accent="info">
|
||||
</h4>
|
||||
</nb-card-header>
|
||||
<nb-card-body>
|
||||
{{char.specname}} {{char.class}}
|
||||
{{char.race}}<br />
|
||||
{{char.specname}} {{char.class}}
|
||||
<br />
|
||||
<br />
|
||||
<span *ngFor="let token of char.tokens">
|
||||
[ {{token.level}} ]
|
||||
<a [ngStyle]="{'color':token.quality=='Epic'?'#a335ee':'#ff8000'}"
|
||||
target="_blank"
|
||||
[href]="token.url">
|
||||
<img style="min-width: 25px; width: 2.25vw; max-width: 50px"
|
||||
[src]="'https://wow.zamimg.com/images/wow/icons/large/'+token.iconname+'.jpg'" />
|
||||
{{token.itemname}}
|
||||
</a><br />
|
||||
</span>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
</nb-card-body>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { LoginApiService } from '../../services/login-api';
|
||||
import { Router } from '@angular/router';
|
||||
import { ApiService } from '../../services/login-api';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { User, Spec, Character } from '../../../../../../backend/Types/Types';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
|
||||
@@ -14,25 +14,24 @@ export class FrontcraftUserComponent implements OnInit{
|
||||
characters : (Character & Spec)[] = []
|
||||
|
||||
constructor(
|
||||
private router : Router,
|
||||
private loginApi : LoginApiService
|
||||
private route: ActivatedRoute,
|
||||
private api : ApiService
|
||||
){}
|
||||
|
||||
ngOnInit(){
|
||||
const auth = this.loginApi.getAuth()
|
||||
if(!auth){
|
||||
this.router.navigateByUrl('/auth/login')
|
||||
return
|
||||
}
|
||||
this.user = auth.user
|
||||
this.loginApi.getUnprivilegedSocket()
|
||||
.CharacterManager
|
||||
.getCharactersOfUser(this.user.username)
|
||||
.then((characters) => {
|
||||
characters.forEach(c => {
|
||||
c['color'] = getClassColor(c.class)
|
||||
})
|
||||
this.characters = characters
|
||||
})
|
||||
async ngOnInit(){
|
||||
const param = this.route.snapshot.paramMap.get('name');
|
||||
const usr = await this.api.get('UserManager').getUser(param)
|
||||
|
||||
|
||||
if(!usr) return
|
||||
this.user = usr
|
||||
|
||||
const characters = await this.api.get('CharacterManager').getCharactersOfUser(this.user.username)
|
||||
characters.forEach(async c => {
|
||||
const tokens = await this.api.get('ItemManager').getTokens(c)
|
||||
c['tokens'] = tokens
|
||||
c['color'] = getClassColor(c.class)
|
||||
})
|
||||
this.characters = characters
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Injectable, Injector, NgZone } from "@angular/core";
|
||||
import {RPCSocket} from 'rpclibrary/js/src/Frontend'
|
||||
|
||||
import { Token, Auth, User, _Class, FrontcraftFeatureIfc, SomeOf, FrontcraftIfc, } from '../../../../../backend/Types/Types'
|
||||
import { Auth, User, _Class, FrontcraftFeatureIfc, SomeOf, FrontcraftIfc, } from '../../../../../backend/Types/Types'
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
import { Router } from '@angular/router';
|
||||
import { ShoutMessage } from '../../../../../backend/Components/Shoutbox/Interface';
|
||||
|
||||
@Injectable()
|
||||
export class LoginApiService{
|
||||
export class ApiService{
|
||||
private socket:RPCSocket & FrontcraftIfc;
|
||||
private auth:Auth
|
||||
private privSocket: RPCSocket & SomeOf<FrontcraftFeatureIfc>
|
||||
@@ -37,7 +38,7 @@ export class LoginApiService{
|
||||
sock.hook('getUserData', () => auth)
|
||||
sock.hook('navigate', (where:string) => {
|
||||
this.ngZone.run( () => {
|
||||
this.injector.get(Router).navigateByUrl('/')
|
||||
this.injector.get(Router).navigateByUrl(where)
|
||||
})
|
||||
})
|
||||
sock.on('error', (e) => {
|
||||
@@ -55,13 +56,17 @@ export class LoginApiService{
|
||||
}
|
||||
}
|
||||
|
||||
getFeature = async <K extends keyof FrontcraftFeatureIfc>(feature : K) : Promise<void | FrontcraftFeatureIfc[K]> => {
|
||||
get = <K extends (keyof FrontcraftIfc | keyof FrontcraftFeatureIfc)>(feature : K) : K extends keyof FrontcraftIfc?FrontcraftIfc[K]:
|
||||
K extends keyof FrontcraftFeatureIfc?(FrontcraftFeatureIfc[K] | void):
|
||||
never => {
|
||||
try{
|
||||
const sock = await this.getPrivilegedSocket(this.auth)
|
||||
if(sock[feature]) return <FrontcraftFeatureIfc[K]> sock[feature]
|
||||
//@ts-ignore
|
||||
if(this.socket && this.socket[feature]) return this.socket[feature]
|
||||
//@ts-ignore
|
||||
if(this.privSocket && this.privSocket[feature]) return this.privSocket[feature]
|
||||
}catch(e){
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentUser = () : User | undefined => {
|
||||
@@ -70,7 +75,7 @@ export class LoginApiService{
|
||||
|
||||
login = async (username: string, password: string) : Promise<RPCSocket & SomeOf<FrontcraftFeatureIfc>> => {
|
||||
const pwHash = await hash(password)
|
||||
const auth = await this.socket.Authenticator.login(username, pwHash)
|
||||
const auth = await this.socket.UserManager.login(username, pwHash)
|
||||
|
||||
if(!auth){
|
||||
await this.logout()
|
||||
@@ -80,9 +85,14 @@ export class LoginApiService{
|
||||
return sock
|
||||
}
|
||||
|
||||
async connectShoutbox(handler) : Promise<Function>{
|
||||
const res = await this.get('Shoutbox').subscribe(handler)
|
||||
return async (msg: ShoutMessage) => await this.get('Shoutbox').shout(res.uuid, msg)
|
||||
}
|
||||
|
||||
logout = async () => {
|
||||
this.cookieSvc.set('token', undefined)
|
||||
if(this.auth) await this.socket.Authenticator.logout(this.auth.user.username, this.auth.token.value)
|
||||
if(this.auth) await this.socket.UserManager.logout(this.auth.user.username, this.auth.token.value)
|
||||
if(this.privSocket) this.privSocket.destroy()
|
||||
this.privSocket = null
|
||||
this.auth = null
|
||||
@@ -91,15 +101,16 @@ export class LoginApiService{
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
initialize = async () : Promise<any> => {
|
||||
const sock = await RPCSocket.makeSocket<FrontcraftIfc>(20000, window.location.hostname)
|
||||
|
||||
this.socket = sock
|
||||
try{
|
||||
const cookie = JSON.parse(this.cookieSvc.get('token'))
|
||||
|
||||
if(cookie != null) {
|
||||
try{
|
||||
const auth = await sock.Authenticator.getAuth(cookie.token.value)
|
||||
const auth = await sock.UserManager.getAuth(cookie.token.value)
|
||||
if(!auth) return sock
|
||||
return await this.getPrivilegedSocket(auth)
|
||||
}catch(e){
|
||||
@@ -115,7 +126,7 @@ export class LoginApiService{
|
||||
|
||||
async checkLogin() : Promise<boolean>{
|
||||
if(!this.auth) return false
|
||||
const valid = await this.socket.Authenticator.checkToken(this.auth.token.value, this.auth.user.rank)
|
||||
const valid = this.socket.UserManager.checkToken(this.auth.token.value, this.auth.user.rank)
|
||||
if(valid) return true
|
||||
await this.logout()
|
||||
return false
|
||||
@@ -126,7 +137,7 @@ function str2arraybuf(str:string): ArrayBuffer {
|
||||
return new Buffer(str)
|
||||
}
|
||||
|
||||
function buf2hex(buffer) { // buffer is an ArrayBuffer
|
||||
function buf2hex(buffer: ArrayBuffer) {
|
||||
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
|
||||
}
|
||||
|
||||
@@ -137,6 +148,6 @@ export async function hash(value:string) : Promise<string>{
|
||||
}
|
||||
|
||||
//angular depenency manager requires this
|
||||
export function initializeLoginSvc(svc: LoginApiService): () => Promise<any> {
|
||||
return svc.initialize
|
||||
export function initializeLoginSvc(svc: ApiService): () => Promise<any> {
|
||||
return ()=>svc.initialize?svc.initialize():undefined
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"importHelpers": true,
|
||||
"module": "esnext",
|
||||
"module": "commonjs",
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
|
||||
Reference in New Issue
Block a user