pretty up

This commit is contained in:
peter
2020-02-07 17:30:55 +01:00
parent 59990af4d2
commit e3eb1f123c
29 changed files with 376 additions and 90 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ implements TableDefinitionExporter, IAdmin {
connection: { connection: {
filename: Path.join(__dirname, "data/frontworkAdmin.sqlite") filename: Path.join(__dirname, "data/frontworkAdmin.sqlite")
}, },
useNullAsDefault: true useNullAsDefault: true,
} }
} }
} }
+2 -2
View File
@@ -7,8 +7,8 @@ export class IItemManager{
setPriority: (itemname:string, priority: any) => Promise<void> setPriority: (itemname:string, priority: any) => Promise<void>
calculatePriorities: (itemname: string, character:Character) => Promise<number> calculatePriorities: (itemname: string, character:Character) => Promise<number>
deletePriority: (priority:SRPriority) => Promise<void> deletePriority: (priority:SRPriority) => Promise<void>
getTokens: (character:Character) => Promise<SRToken[]> getTokens: (character:Character, valid?:boolean) => Promise<SRToken[]>
getToken: (character:Character, item:Item) => Promise<(SRToken & Character & Item) | void> getToken: (character:Character, item:Item, valid?:boolean) => Promise<(SRToken & Character & Item) | void>
getAllPriorities: () => Promise<(SRPriority & Spec & Item)[]> getAllPriorities: () => Promise<(SRPriority & Spec & Item)[]>
wipeCurrencyAndItems: () => Promise<void> wipeCurrencyAndItems: () => Promise<void>
} }
+22 -6
View File
@@ -146,18 +146,27 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
if(matchingtoken){ if(matchingtoken){
//update signupid and increment level //update signupid and increment level
console.log("delete shadow tokens");
await this.admin await this.admin
.knex('tokens') .knex('tokens')
.update({
signupid: signup.id,
level: matchingtoken.level+1
})
.where({ .where({
characterid: character.id, characterid: character.id,
itemname: item.itemname itemname: item.itemname
}) })
.update({
signupid: signup.id,
level: matchingtoken.level+1
})
await this.admin
.knex('tokens')
.where({
characterid: character.id,
itemname: item.itemname,
signupid: null
}).del()
return await this.getToken(character, item) return await this.getToken(character, item)
} }
} }
@@ -248,7 +257,7 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
}).reduce((prev, curr) => prev+curr, 0) }).reduce((prev, curr) => prev+curr, 0)
} }
getToken = async (character:Character, item:Item): Promise<(SRToken & Character & Item) | void>=> { getToken = async (character:Character, item:Item,valid=true): Promise<(SRToken & Character & Item) | void>=> {
return await this.admin return await this.admin
.knex('tokens as t') .knex('tokens as t')
.select('*') .select('*')
@@ -258,6 +267,13 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
characterid: character.id, characterid: character.id,
"i.itemname": item.itemname "i.itemname": item.itemname
}) })
.andWhere(function(){
if(valid){
this.whereNotNull('t.signupid')
}else{
this.whereNull('t.signupid')
}
})
.first() .first()
} }
+1
View File
@@ -14,4 +14,5 @@ export class IRaidManager{
getPastRaids: (limit: number) => Promise<RaidData[]> getPastRaids: (limit: number) => Promise<RaidData[]>
getArchiveRaid: (id:number) => Promise<RaidData> getArchiveRaid: (id:number) => Promise<RaidData>
startRaid: (raid:Raid) => Promise<RaidData> startRaid: (raid:Raid) => Promise<RaidData>
adminUnsign: (character:Character, raid:Raid) => Promise<any>
} }
@@ -17,6 +17,7 @@ export type RaidManagerFeatureIfc = {
archiveRaid: IRaidManager['archiveRaid'] archiveRaid: IRaidManager['archiveRaid']
setBenched: IRaidManager['setBenched'] setBenched: IRaidManager['setBenched']
startRaid: IRaidManager['startRaid'] startRaid: IRaidManager['startRaid']
adminUnsign: IRaidManager['adminUnsign']
} }
signup: { signup: {
getSignups: IRaidManager['getSignups'] getSignups: IRaidManager['getSignups']
+105 -15
View File
@@ -7,6 +7,9 @@ import { IRaidManager } from "./Interface";
import { IUserManager } from "../User/Interface"; import { IUserManager } from "../User/Interface";
import { ICharacterManager } from "../Character/Interface"; import { ICharacterManager } from "../Character/Interface";
import { _Tiers } from "../../Types/Items"; import { _Tiers } from "../../Types/Items";
import { IItemManager } from "../Item/Interface";
import { ItemManager } from "../Item/ItemManager";
import { SpecT } from "../../Types/PlayerSpecs";
@Injectable(IRaidManager) @Injectable(IRaidManager)
export class RaidManager export class RaidManager
@@ -22,6 +25,9 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
@Inject(ICharacterManager) @Inject(ICharacterManager)
private characterManager: ICharacterManager private characterManager: ICharacterManager
@Inject(ItemManager)
private itemManager: IItemManager
exportRPCs = () => [ exportRPCs = () => [
this.getRaids, this.getRaids,
this.getRaidData, this.getRaidData,
@@ -38,7 +44,8 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
this.removeSignup, this.removeSignup,
this.archiveRaid, this.archiveRaid,
this.setBenched, this.setBenched,
this.startRaid this.startRaid,
this.adminUnsign
] ]
},{ },{
name: 'signup' as 'signup', name: 'signup' as 'signup',
@@ -136,15 +143,20 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
archiveRaid = async (raid:Raid) : Promise<RaidData> => { archiveRaid = async (raid:Raid) : Promise<RaidData> => {
const raidData = await this.getRaidData(raid) const raidData = await this.getRaidData(raid)
const tx = await this.admin.knex.transaction()
await this.admin.knex('archive') await this.admin.knex('archive')
.transacting(tx)
.insert({ .insert({
id:raidData.id, id:raidData.id,
raiddata: JSON.stringify(raidData) raiddata: JSON.stringify(raidData)
}) })
await Promise.all( await Promise.all(
Object.values(raidData.participants).flat().flatMap((signup) => this.admin Object.values(raidData.participants).flat().flatMap((signup) => this.admin
.knex('tokens') .knex('tokens')
.transacting(tx)
.where({ .where({
characterid: signup.characterid, characterid: signup.characterid,
signupid: null signupid: null
@@ -153,8 +165,11 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
)) ))
await this.admin.knex('raids') await this.admin.knex('raids')
.transacting(tx)
.where('id', '=', raid.id) .where('id', '=', raid.id)
.del() .del()
await tx.commit()
const row = await this.admin.knex('archive') const row = await this.admin.knex('archive')
.select('*') .select('*')
@@ -162,7 +177,6 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
id:raidData.id, id:raidData.id,
}) })
.first() .first()
return JSON.parse(row.raiddata) return JSON.parse(row.raiddata)
} }
@@ -184,7 +198,7 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
} }
getRaidData = async (raid:Raid) : Promise<RaidData> => { getRaidData = async (raid:Raid) : Promise<RaidData> => {
const ret = { const raiddata = {
participants:{ participants:{
Druid: <(Signup&Character&Spec)[]>[], Druid: <(Signup&Character&Spec)[]>[],
Hunter: <(Signup&Character&Spec)[]>[], Hunter: <(Signup&Character&Spec)[]>[],
@@ -198,8 +212,11 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
late: <(Signup&Character&Spec)[]>[], late: <(Signup&Character&Spec)[]>[],
bench: <(Signup&Character&Spec)[]>[], bench: <(Signup&Character&Spec)[]>[],
}, },
tokens:{} tokens:{},
healers:<(Signup&Character&Spec)[]>[],
tanks:<(Signup&Character&Spec)[]>[]
} }
const tx = await this.admin.knex.transaction()
const subQuery = this.admin const subQuery = this.admin
.knex('signups') .knex('signups')
@@ -211,14 +228,17 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
}) })
.as('signupcount') .as('signupcount')
const raidInDb: Raid = await this.admin.knex('raids') const raidInDb: Raid = await this.admin.knex('raids')
.select('*', subQuery) .select('*', subQuery)
.transacting(tx)
.where('id','=',raid.id) .where('id','=',raid.id)
.first() .first()
const characterData: (Signup & Character & Spec)[] = await this.admin const characterData: (Signup & Character & Spec)[] = await this.admin
.knex('signups as s') .knex('signups as s')
.select('s.id as id', 'charactername', 'class', 'specname', 'race', 'userid', 'benched', 'late', 'raidid', 'characterid') .transacting(tx)
.select('s.id as id', 'charactername', 'class', 'specid', 'specname', 'race', 'userid', 'benched', 'late', 'raidid', 'characterid', 'specid')
.join('raids as r', 's.raidid','=','r.id') .join('raids as r', 's.raidid','=','r.id')
.join('characters as c', 's.characterid','=','c.id') .join('characters as c', 's.characterid','=','c.id')
.join('users as u', 'c.userid','=','u.id') .join('users as u', 'c.userid','=','u.id')
@@ -227,18 +247,19 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
characterData.forEach(data => { characterData.forEach(data => {
if(data.benched){ if(data.benched){
ret.participants.bench.push(data) raiddata.participants.bench.push(data)
return return
} }
if(data.late){ if(data.late){
ret.participants.late.push(data) raiddata.participants.late.push(data)
return return
} }
ret.participants[data.class].push(data) raiddata.participants[data.class].push(data)
}) })
const tokenData: (Character & SRToken & Item)[] = await this.admin const tokenData: (Character & SRToken & Item)[] = await this.admin
.knex('signups as s') .knex('signups as s')
.transacting(tx)
.select('*', 's.id as id') .select('*', 's.id as id')
.join('raids as r', 's.raidid','=','r.id') .join('raids as r', 's.raidid','=','r.id')
.where('r.id','=',raid.id) .where('r.id','=',raid.id)
@@ -249,14 +270,33 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
.join('tokens as t', 't.characterid','=','c.id') .join('tokens as t', 't.characterid','=','c.id')
.join('items as i', 'i.itemname','=','t.itemname') .join('items as i', 'i.itemname','=','t.itemname')
await tx.commit()
tokenData.forEach(data => { tokenData.forEach(data => {
if(!ret.tokens[data.itemname]) if(!raiddata.tokens[data.itemname])
ret.tokens[data.itemname] = [] raiddata.tokens[data.itemname] = []
ret.tokens[data.itemname].push(data) raiddata.tokens[data.itemname].push(data)
}) })
raiddata.tanks = Object.values(raiddata.participants).flatMap(
(tanks:any[]) => tanks.filter((p:any) =>
!p.benched
&& !p.late
&& (p.specname==="Protection"
|| p.specname==="Feral (Tank)"))
)
raiddata.healers = Object.values(raiddata.participants).flatMap(
(healers:any[]) => healers.filter((p:any) =>
!p.benched
&& !p.late
&& (p.specname==="Holy"
|| p.specname==="Discipline"
|| p.specname==="Restoration"))
)
return { return {
...raidInDb, ...raidInDb,
...ret ...raiddata
} }
} }
@@ -273,9 +313,11 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
if(!maybeUserRecord || maybeUserRecord.user.id != character.userid){ if(!maybeUserRecord || maybeUserRecord.user.id != character.userid){
throw new Error("Bad Usertoken") throw new Error("Bad Usertoken")
} }
const tx = await this.admin.knex.transaction()
const exists = await this.admin const exists = await this.admin
.knex('signups') .knex('signups')
.transacting(tx)
.select('*') .select('*')
.where({ .where({
raidid: raid.id!, raidid: raid.id!,
@@ -286,20 +328,28 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
if(!exists){ if(!exists){
await this.admin await this.admin
.knex('signups') .knex('signups')
.transacting(tx)
.insert({ .insert({
raidid: raid.id!, raidid: raid.id!,
characterid: character.id!, characterid: character.id!,
late: late late: late,
benched: false,
}) })
}else{ }else{
await this.admin await this.admin
.knex('signups') .knex('signups')
.transacting(tx)
.where({
id: exists.id
})
.update({ .update({
raidid: raid.id!, raidid: raid.id!,
characterid: character.id!, characterid: character.id!,
late: late late: late,
benched: false,
}) })
} }
await tx.commit()
return await this.admin return await this.admin
.knex('signups') .knex('signups')
@@ -317,6 +367,46 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
throw new Error("Bad Usertoken") throw new Error("Bad Usertoken")
} }
return await this.adminUnsign(character, raid)
}
adminUnsign = async (character:Character, raid:Raid) => {
const user = await this.characterManager.getUserOfCharacter(character)
const signup = await this.admin.knex('signups as si')
.where({
"si.raidid": raid.id!,
"si.characterid": character.id!,
}).first()
const tokens = await this.admin.knex('tokens as t')
.where('t.signupid', signup.id)
//check if token has to be deleted
Promise.all(
tokens.map(async token => {
await this.userManager.incrementCurrency(user, 1)
const prio = await this.itemManager.calculatePriorities(token.itemname, character)
if(token.level <= prio+1){
await this.admin.knex('tokens')
.where({
characterid: character.id,
itemname: token.itemname
}).del()
}else{
await this.admin.knex('tokens')
.where({
characterid: character.id,
itemname: token.itemname
}).update({
signupid: null,
level: token.level-1
})
}
})
)
await this.admin.knex('signups') await this.admin.knex('signups')
.where({ .where({
raidid: raid.id!, raidid: raid.id!,
+2
View File
@@ -58,6 +58,8 @@ export type RaidData = Raid & {
tokens: { tokens: {
[itemname in string]: (Character & SRToken & Item)[] [itemname in string]: (Character & SRToken & Item)[]
} }
tanks: (Signup & Character & Spec)[]
healers: (Signup & Character & Spec)[]
} }
export type SRToken = { export type SRToken = {
@@ -73,8 +73,12 @@ export class HeaderComponent implements OnInit, OnDestroy {
this.api.connectShoutbox((msg) => { this.api.connectShoutbox((msg) => {
this.chatlog.push(msg) this.chatlog.push(msg)
if(msg.message != this.lastmessage) msg['reply']=false
if(msg.message != this.lastmessage){
this.newmessage = true this.newmessage = true
msg['reply']=true
}
if(this.chatwindow) this.chatwindow.messages.push(msg) if(this.chatwindow) this.chatwindow.messages.push(msg)
}).then(sendMsg => { }).then(sendMsg => {
this.sendMessage = (msg) => { this.sendMessage = (msg) => {
@@ -15,7 +15,9 @@ status="control">
</nb-card-header> </nb-card-header>
<nb-card-body> <nb-card-body>
<img style="width:20px; height:20px" [src]="'../../../../assets/images/'+char.race.toLowerCase()+'_xs.gif'" />
{{char.race}}<br /> {{char.race}}<br />
<img style="width:20px; height:20px" [src]="'../../../../assets/images/'+char.class.toLowerCase()+'.png'" />
{{char.specname}} {{char.class}}<br /> {{char.specname}} {{char.class}}<br />
<span *ngIf="link === 'owner'"> <span *ngIf="link === 'owner'">
Owned by <a [routerLink]="'/frontcraft/user/'+char.username"> {{char.username}} ({{char.rank}})</a> Owned by <a [routerLink]="'/frontcraft/user/'+char.username"> {{char.username}} ({{char.rank}})</a>
@@ -13,7 +13,10 @@ export class FrontcraftCharacterComponent implements OnInit{
@Input() name?: string @Input() name?: string
@Input() link?: "owner" | "character" = 'owner' @Input() link?: "owner" | "character" = 'owner'
char : (Character & User & Spec) = {} as any char : (Character & User & Spec) = {
race: 'Human',
class: 'Warrior'
} as any
color : string color : string
tokens tokens
@@ -17,12 +17,14 @@
</a> </a>
</td> </td>
<td> <td>
<img style="width:20px; height:20px" [src]="'../../../../assets/images/'+character.race.toLowerCase()+'_xs.gif'" />
{{character.race}} {{character.race}}
</td> </td>
<td> <td>
{{character.specname}} {{character.specname}}
</td> </td>
<td> <td>
<img style="width:20px; height:20px" [src]="'../../../../assets/images/'+character.class.toLowerCase()+'.png'" />
{{character.class}} {{character.class}}
</td> </td>
</tr> </tr>
@@ -22,10 +22,6 @@ export class PagesLayoutComponent implements AfterContentInit{
icon: 'people', icon: 'people',
title: 'Characters', title: 'Characters',
link: '/frontcraft/characters', link: '/frontcraft/characters',
},{
icon: 'shopping-cart',
title: 'Token Shop',
link: '/frontcraft/shop',
},{ },{
icon: 'book-open-outline', icon: 'book-open-outline',
title: 'Loot Rules', title: 'Loot Rules',
@@ -39,10 +39,6 @@ export const routes: Routes = [
path: 'characters', path: 'characters',
component: FrontcraftCharactersComponent, component: FrontcraftCharactersComponent,
}, },
{
path: 'shop',
component: FrontcraftShopComponent
},
{ {
path: 'rules', path: 'rules',
component: FrontcraftRulesComponent component: FrontcraftRulesComponent
@@ -27,8 +27,13 @@ export class FrontcraftArchiveComponent implements OnInit{
Warlock: [], Warlock: [],
Warrior: [], Warrior: [],
}, },
tokens:{} tokens:{},
tanks:[],
healers: []
} }
tokens = {}
displayedtokens = {}
search = ""
constructor( constructor(
private api: ApiService, private api: ApiService,
@@ -46,19 +51,21 @@ export class FrontcraftArchiveComponent implements OnInit{
const raidManager = this.api.get('RaidManager') const raidManager = this.api.get('RaidManager')
const raiddata = await raidManager.getArchiveRaid(parseInt(param)) const raiddata = await raidManager.getArchiveRaid(parseInt(param))
this.raid = raiddata this.raid = raiddata
this.tokens = raiddata.tokens;
Object.values(raiddata.participants).flat().forEach(p => { [
...raiddata.tanks,
...raiddata.healers,
...Object.values(raiddata.participants).flat()
].forEach(p => {
p['color'] = getClassColor(p.class) p['color'] = getClassColor(p.class)
}) })
const matchingSignup = Object.values(raiddata.participants).flat().find(char => char.userid === this.api.getCurrentUser()!.id!) this.changeSearch()
if(matchingSignup){ }
this.isSignedup = true
this.mySignup = matchingSignup changeSearch = () => {
this.mySignup.status = matchingSignup['benched']?'Bench':matchingSignup['late']?'Late':'Attending' this.tokens = this.raid.tokens;
}else{ this.displayedtokens = this.raid.tokens;
this.isSignedup = false }
this.mySignup = null
}
}
} }
@@ -17,14 +17,32 @@
Status: {{mySignup.status}} Status: {{mySignup.status}}
</p> </p>
<button
(click)="setLate(true)"
*ngIf="mySignup.status !== 'Late'"
nbButton
outline
status="warning"
size="medium">
<nb-icon icon="clock-outline"></nb-icon> Late
</button>
<button
(click)="setLate(false)"
*ngIf="mySignup.status === 'Late'"
nbButton
outline
status="success"
size="medium">
<nb-icon icon="checkmark-outline"></nb-icon> On Time
</button>
<button <button
(click)="unsign()" (click)="unsign()"
nbButton nbButton
outline outline
status="danger" status="danger"
size="medium"> size="medium">
unsign <nb-icon icon="close"></nb-icon>unsign
</button> </button>
</div> </div>
<div *ngIf="!isSignedup"> <div *ngIf="!isSignedup">
<button <button
@@ -33,7 +51,7 @@
outline outline
status="success" status="success"
size="medium"> size="medium">
signup <nb-icon icon="person-done-outline"></nb-icon> sign up
</button> </button>
</div> </div>
</div> </div>
@@ -44,6 +62,74 @@
badgePosition="top right" badgePosition="top right"
[badgeStatus]="raid.signupcount<40?'warning':'success'"> [badgeStatus]="raid.signupcount<40?'warning':'success'">
<div class="row"> <div class="row">
<nb-card
class="col-12 col-md-6"
*ngIf="raid.tanks.length > 0">
<nb-card-header>Tanks ({{raid.tanks.length}})</nb-card-header>
<nb-card-body>
<div *ngFor="let participant of raid.tanks">
<button
(click)="setBench(participant)"
*ngIf="manageRaid"
nbButton
outline
status="warning"
size="tiny">
B
</button>
<button
(click)="adminUnsign(participant)"
*ngIf="manageRaid"
nbButton
outline
status="danger"
size="tiny">
X
</button>
<a [ngStyle]="{'color': participant.color}" style="text-transform: capitalize;"
[routerLink]="'/frontcraft/character/'+participant.charactername">
<img style="width:20px; height:20px" [src]="'../../../../assets/images/'+participant.race.toLowerCase()+'_xs.gif'" />
<img style="width:20px; height:20px" [src]="'../../../../assets/images/'+participant.class.toLowerCase()+'.png'" />
{{ participant.charactername }}
</a>
</div>
</nb-card-body>
</nb-card>
<nb-card
class="col-12 col-md-6"
*ngIf="raid.tanks.length > 0">
<nb-card-header>Healers ({{raid.healers.length}})</nb-card-header>
<nb-card-body>
<div *ngFor="let participant of raid.healers">
<button
(click)="setBench(participant)"
*ngIf="manageRaid"
nbButton
outline
status="warning"
size="tiny">
B
</button>
<button
(click)="adminUnsign(participant)"
*ngIf="manageRaid"
nbButton
outline
status="danger"
size="tiny">
X
</button>
<a [ngStyle]="{'color': participant.color}" style="text-transform: capitalize;"
[routerLink]="'/frontcraft/character/'+participant.charactername">
<img style="width:20px; height:20px" [src]="'../../../../assets/images/'+participant.race.toLowerCase()+'_xs.gif'" />
<img style="width:20px; height:20px" [src]="'../../../../assets/images/'+participant.class.toLowerCase()+'.png'" />
{{ participant.charactername }}
</a>
</div>
</nb-card-body>
</nb-card>
<ng-container *ngFor="let group of raid.participants | keyvalue"> <ng-container *ngFor="let group of raid.participants | keyvalue">
<nb-card <nb-card
class="col-12 col-md-6 col-xl-4" class="col-12 col-md-6 col-xl-4"
@@ -60,8 +146,19 @@
size="tiny"> size="tiny">
B B
</button> </button>
<button
(click)="adminUnsign(participant)"
*ngIf="manageRaid"
nbButton
outline
status="danger"
size="tiny">
X
</button>
<a [ngStyle]="{'color': participant.color}" style="text-transform: capitalize;" <a [ngStyle]="{'color': participant.color}" style="text-transform: capitalize;"
[routerLink]="'/frontcraft/character/'+participant.charactername"> [routerLink]="'/frontcraft/character/'+participant.charactername">
<img style="width:20px; height:20px" [src]="'../../../../assets/images/'+participant.race.toLowerCase()+'_xs.gif'" />
<img style="width:20px; height:20px" [src]="'../../../../assets/images/'+participant.class.toLowerCase()+'.png'" />
{{ participant.charactername }} {{ participant.charactername }}
</a> </a>
</div> </div>
@@ -70,12 +167,14 @@
</ng-container> </ng-container>
</div> </div>
</nb-tab> </nb-tab>
<nb-tab tabTitle="Shop"> <nb-tab tabTitle="Shop" *ngIf="isSignedup">
<shop (onSelect)="itemSelect($event)"></shop> <shop (onSelect)="itemSelect($event)"></shop>
</nb-tab> </nb-tab>
<nb-tab tabTitle="Reserves"> <nb-tab tabTitle="Reserves">
<input type="text" nbInput [(ngModel)]="search" (change)="changeSearch()" placeholder="Search" fullWidth="true">
<nb-list> <nb-list>
<nb-list-item *ngFor="let item of raid.tokens | keyvalue"> <nb-list-item *ngFor="let item of displayedtokens | keyvalue">
<a [ngStyle]="{'color':item.value[0].quality=='Epic'?'#a335ee':'#ff8000'}" <a [ngStyle]="{'color':item.value[0].quality=='Epic'?'#a335ee':'#ff8000'}"
target="_blank" target="_blank"
[href]="item.value[0].url"> [href]="item.value[0].url">
@@ -104,15 +203,6 @@
size="medium"> size="medium">
start start
</button> </button>
<button
(click)="archiveRaid(raid)"
nbButton
outline
status="danger"
size="medium">
archive
</button>
</nb-tab> </nb-tab>
</nb-tabset> </nb-tabset>
</nb-card-body> </nb-card-body>
@@ -1,10 +1,10 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { ApiService as ApiService } from '../../services/login-api'; import { ApiService as ApiService } from '../../services/login-api';
import { RaidData, Raid, Signup } from '../../../../../../backend/Types/Types'; import { RaidData, Raid, Signup, Character, Spec, Item, SRToken } from '../../../../../../backend/Types/Types';
import { NbWindowService, NbToastrService, NbDialogService } from '@nebular/theme'; import { NbWindowService, NbToastrService, NbDialogService } from '@nebular/theme';
import { FrontcraftCharacerpickerComponent } from './characterpicker.component'; import { FrontcraftCharacerpickerComponent } from './characterpicker.component';
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs'; import { getClassColor, SpecT } from '../../../../../../backend/Types/PlayerSpecs';
import { FrontcraftBuyTokenComponent } from '../shop/buytoken.component'; import { FrontcraftBuyTokenComponent } from '../shop/buytoken.component';
@Component({ @Component({
@@ -15,8 +15,9 @@ export class FrontcraftRaidComponent implements OnInit{
canSignup = false canSignup = false
isSignedup = false isSignedup = false
islate = false
manageRaid manageRaid
mySignup mySignup: (Signup & Character & Spec)
raid: RaidData = <any>{ raid: RaidData = <any>{
participants:{ participants:{
@@ -30,9 +31,14 @@ export class FrontcraftRaidComponent implements OnInit{
Warlock: [], Warlock: [],
Warrior: [], Warrior: [],
}, },
tanks: [],
healers: [],
tokens:{} tokens:{}
} }
tokens = {}
displayedtokens = {}
search = ""
constructor( constructor(
private api: ApiService, private api: ApiService,
private route: ActivatedRoute, private route: ActivatedRoute,
@@ -93,11 +99,40 @@ export class FrontcraftRaidComponent implements OnInit{
const signupFeature = this.api.get('signup') const signupFeature = this.api.get('signup')
if(!signupFeature) return if(!signupFeature) return
await signupFeature.unsign(this.api.getAuth().token.value, <any>{id: this.mySignup.characterid, userid: this.mySignup.userid}, this.raid) await signupFeature.unsign(this.api.getAuth().token.value, {
...this.mySignup,
id: this.mySignup.characterid,
}, this.raid)
this.toast.show('Success', 'Unsigned', { status: 'success' }) this.toast.show('Success', 'Unsigned', { status: 'success' })
this.refresh() this.refresh()
} }
setLate = async (value:boolean) => {
const auth = this.api.getAuth()
const signup = this.api.get('signup')
if(!signup) return
console.log("setlate");
await signup.sign(auth.token.value, {
...this.mySignup,
id: this.mySignup.characterid,
}, this.raid, value)
this.toast.show('Signup', 'Success', { status: 'success' })
this.refresh()
}
adminUnsign = async() => {
const manage = this.api.get('manageRaid')
if(!manage) return
await manage.adminUnsign({
...this.mySignup,
id: this.mySignup.characterid,
}, this.raid)
this.refresh()
}
refresh = async () => { refresh = async () => {
const param = this.route.snapshot.paramMap.get('id'); const param = this.route.snapshot.paramMap.get('id');
@@ -105,22 +140,40 @@ export class FrontcraftRaidComponent implements OnInit{
const raiddata = await raidManager.getRaidData(<any>{ const raiddata = await raidManager.getRaidData(<any>{
id: param id: param
}) })
this.raid = raiddata this.raid = raiddata
this.tokens = raiddata.tokens;
Object.values(raiddata.participants).flat().forEach(p => { [...raiddata.tanks, ...raiddata.healers, ...Object.values(raiddata.participants).flat()].forEach(p => {
p['color'] = getClassColor(p.class) p['color'] = getClassColor(p.class)
}) })
const user = this.api.getCurrentUser() const user = this.api.getCurrentUser()
const matchingSignup = Object.values(raiddata.participants).flat().find(char => user && char.userid === user.id!) const matchingSignup = Object.values(raiddata.participants).flat().find(char => user && char.userid === user.id!)
if(matchingSignup){ if(matchingSignup){
this.isSignedup = true this.isSignedup = true
this.mySignup = matchingSignup this.mySignup = matchingSignup
this.mySignup.status = matchingSignup['benched']?'Bench':matchingSignup['late']?'Late':'Attending' this.mySignup['status'] = matchingSignup['benched']?'Bench':matchingSignup['late']?'Late':'Attending'
}else{ }else{
this.isSignedup = false this.isSignedup = false
this.mySignup = null this.mySignup = null
} }
this.changeSearch()
}
changeSearch(){
if(!this.search || this.search == ""){
this.displayedtokens = this.tokens
}else{
this.displayedtokens = {}
Object.entries(this.tokens).forEach((e: [string, (Character & SRToken & Item)[]]) => {
const filteredTokens = e[1].filter(item => {
return item.itemname.toLocaleLowerCase().includes(this.search.toLocaleLowerCase())
})
if(filteredTokens.length > 0)
this.displayedtokens[e[0]] = filteredTokens
})
}
} }
setBench(signup:Signup){ setBench(signup:Signup){
@@ -20,7 +20,7 @@
<ng-template #templateRef> <ng-template #templateRef>
<span style="color:white">{{rule.description}}</span> <span style="color:white">{{rule.description}}</span>
</ng-template> </ng-template>
+{{rule.modifier}} {{rule.race}} <span [ngStyle]="{'color':rule.color}">{{rule.specname}} {{rule.class}}</span> <br /> <span *ngIf="rule.modifier>0">+</span>{{rule.modifier}} {{rule.race}} <span [ngStyle]="{'color':rule.color}">{{rule.specname}} {{rule.class}}</span> <br />
</span> </span>
</nb-list-item> </nb-list-item>
</nb-list> </nb-list>
@@ -72,13 +72,18 @@ import { _Tiers, allItems, Tiers } from '../../../../../../backend/Types/Items';
.then(chars => { .then(chars => {
chars.forEach(char => { chars.forEach(char => {
char['color'] = getClassColor(char.class) char['color'] = getClassColor(char.class)
this.api.get('ItemManager').getToken(char, this.item).then(token => { this.api.get('ItemManager').getToken(char, this.item, false).then(token => {
if(token) this.ownedtokens.push(token) if(token) this.ownedtokens.push(token)
else{ else{
this.api.get('ItemManager').calculatePriorities(this.item.itemname, char).then(modifier => { this.api.get('ItemManager').getToken(char, this.item, true).then(tokken => {
this.modifier[char.charactername] = modifier if(tokken) this.ownedtokens.push(tokken)
}) else{
} this.api.get('ItemManager').calculatePriorities(this.item.itemname, char).then(modifier => {
this.modifier[char.charactername] = modifier
})
}
})
}
}) })
}) })
this.characters = chars this.characters = chars
@@ -90,15 +95,14 @@ import { _Tiers, allItems, Tiers } from '../../../../../../backend/Types/Items';
} }
buyToken = async (charactername:string) => { buyToken = async (charactername:string) => {
const src = this.api.get('ItemManager')
const src = this.api.get('ItemManager') const token = await src.buyToken(this.api.getAuth().token.value, charactername, this.item.itemname, this.signup)
const token = await src.buyToken(this.api.getAuth().token.value, charactername, this.item.itemname, this.signup)
if(token){
if(token){ this.toastr.show(token.characterid+' now has a token for '+token.itemname+' of level '+token.level, 'Yay', {status: 'success'})
this.toastr.show(token.characterid+' now has a token for '+token.itemname+' of level '+token.level, 'Yay', {status: 'success'}) }else{
}else{ this.toastr.show('Error (something went wrong)', 'Oh no', {status: 'danger'})
this.toastr.show('Error (something went wrong)', 'Oh no', {status: 'danger'}) }
} this.dialogRef.close()
this.dialogRef.close()
} }
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 610 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

+22 -3
View File
@@ -79,7 +79,7 @@ const testAccounts : protoAccount[] = [
spec: 'Fury', spec: 'Fury',
rank: 'Classleader' rank: 'Classleader'
},{ },{
name: 'Teenieweenie', name: 'Teeniweeni',
class: 'Warlock', class: 'Warlock',
race: 'Gnome', race: 'Gnome',
spec: 'Demonology', spec: 'Demonology',
@@ -276,10 +276,30 @@ describe('Frontcraft', () => {
undefined, 1, "hit bias" undefined, 1, "hit bias"
), ),
makePrio(
'Maladath, Runed Blade of the Black Flight',
undefined,
"Human", -2, "(1) Non-Human"
),
makePrio(
'Maladath, Runed Blade of the Black Flight',
{class:'Rogue', specname:'Subtlety'},
undefined, 2, "...Rogues (weapon skill bias)"
),
makePrio(
'Maladath, Runed Blade of the Black Flight',
{class:'Rogue', specname:'Combat'},
undefined, 2, "...Rogues (weapon skill bias)"
),
makePrio(
'Maladath, Runed Blade of the Black Flight',
{class:'Rogue', specname:'Assassination'},
undefined, 2, "...Rogues (weapon skill bias)"
),
makePrio( makePrio(
'Maladath, Runed Blade of the Black Flight', 'Maladath, Runed Blade of the Black Flight',
{class:'Warrior', specname:'Fury'}, {class:'Warrior', specname:'Fury'},
'Human', 2, "weapon skill bias" 'Human', 4, "+2 Fury Warrior (weapon skill bias), +2 to offset (1)"
), ),
makePrio( makePrio(
@@ -556,7 +576,6 @@ describe('Frontcraft', () => {
} }
else{ else{
console.log("Bad user currency", dbUser); console.log("Bad user currency", dbUser);
} }
}) })
} }