visual polish and bugfixes. auto-refreshing
This commit is contained in:
@@ -20,6 +20,7 @@ import { FrontworkComponent } from '../Types/FrontworkComponent';
|
||||
import { IAdmin } from './Interface';
|
||||
import { Injector } from '../Injector/Injector';
|
||||
import { Shoutbox } from '../Components/Shoutbox/Shoutbox';
|
||||
import { PubSub } from '../Components/PubSub/PubSub';
|
||||
|
||||
|
||||
const logger = getLogger("admin", 'debug')
|
||||
@@ -32,7 +33,8 @@ const logger = getLogger("admin", 'debug')
|
||||
RaidManager,
|
||||
CharacterManager,
|
||||
UserManager,
|
||||
Shoutbox
|
||||
Shoutbox,
|
||||
PubSub
|
||||
]
|
||||
})
|
||||
export class FrontworkAdmin
|
||||
@@ -54,7 +56,7 @@ implements TableDefinitionExporter, IAdmin {
|
||||
dbConf: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: Path.join(__dirname, "data/frontworkAdmin.sqlite")
|
||||
filename: Path.resolve(__dirname, '../../../..', "data/frontworkAdmin.sqlite")
|
||||
},
|
||||
useNullAsDefault: true,
|
||||
}
|
||||
@@ -96,7 +98,9 @@ implements TableDefinitionExporter, IAdmin {
|
||||
getTableDefinitions(): TableDefiniton[]{
|
||||
return [
|
||||
...this.frontworkComponents
|
||||
].flatMap(exporter => exporter.getTableDefinitions())
|
||||
]
|
||||
.filter(exp => exp.getTableDefinitions != null)
|
||||
.flatMap(exp => exp.getTableDefinitions())
|
||||
}
|
||||
|
||||
private startWebsocket(){
|
||||
@@ -123,7 +127,7 @@ implements TableDefinitionExporter, IAdmin {
|
||||
|
||||
let port:number = this.config.getConfig().httpPort
|
||||
this.express = express()
|
||||
this.express.use('/', express.static('dist/static'))
|
||||
this.express.use('/', express.static('static'))
|
||||
|
||||
/**
|
||||
* get the compiled FrontendPlugins.js
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { T1, T2, allItems, _Tiers, Tiers } from "../../Types/Items";
|
||||
import { allItems, _Tiers, Tiers } from "../../Types/Items";
|
||||
import { Inject, Injectable } from "../../Injector/ServiceDecorator";
|
||||
import { ItemManagerFeatureIfc, ItemManagerIfc } from "./RPCInterface";
|
||||
import { FrontworkComponent } from "../../Types/FrontworkComponent";
|
||||
import { TableDefinitionExporter } from "../../Types/Interfaces";
|
||||
import { TableDefiniton, Item, User, Character, SRToken, SRPriority, Spec, Signup } from "../../Types/Types";
|
||||
import { TableDefiniton, Item, User, Character, SRToken, SRPriority, Spec, Signup, Raid } from "../../Types/Types";
|
||||
import { IAdmin } from "../../Admin/Interface";
|
||||
import { IItemManager } from "./Interface";
|
||||
import { getLogger } from "log4js";
|
||||
import { IUserManager } from "../User/Interface";
|
||||
import { ICharacterManager } from "../Character/Interface";
|
||||
import { IPubSub } from "../PubSub/Interface";
|
||||
import { IRaidManager } from "../Raid/Interface";
|
||||
|
||||
const fetch = require('node-fetch')
|
||||
const xml2js = require('xml2js');
|
||||
@@ -28,6 +30,12 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
|
||||
@Inject(ICharacterManager)
|
||||
private character: ICharacterManager
|
||||
|
||||
@Inject(IPubSub)
|
||||
private pubsub: IPubSub<any>
|
||||
|
||||
@Inject(IRaidManager)
|
||||
private raidManager: IRaidManager
|
||||
|
||||
exportRPCs = () => [
|
||||
this.getItems,
|
||||
this.getItem,
|
||||
@@ -51,6 +59,16 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
|
||||
]
|
||||
}]
|
||||
|
||||
notifyRaid = async (raid:Raid | {id:number}) => {
|
||||
const data = await this.raidManager.getRaidData(<Raid>raid)
|
||||
this.pubsub.publish(""+raid.id, data)
|
||||
await this.notifyRaids()
|
||||
}
|
||||
|
||||
notifyRaids = async () => {
|
||||
this.pubsub.publish('raids', undefined)
|
||||
}
|
||||
|
||||
wipeCurrencyAndItems = async () => {
|
||||
await Promise.all([
|
||||
this.userManager.wipeCurrency(),
|
||||
@@ -140,13 +158,12 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
|
||||
|
||||
await this.userManager.decrementCurrency(record.user, item.tier, 1)
|
||||
const modifier = await this.calculatePriorities(itemname, character)
|
||||
|
||||
|
||||
const tx = await this.admin.knex.transaction()
|
||||
|
||||
if(streaks.length > 0){
|
||||
const myStreak = streaks.find(token => token.itemname === itemname)
|
||||
if(myStreak){
|
||||
|
||||
//getLogger('ItemManager').debug('update signupid and increment level')
|
||||
await this.admin
|
||||
.knex(item.tier+'tokens')
|
||||
@@ -176,6 +193,8 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
|
||||
|
||||
if(myStreak){
|
||||
await tx.commit()
|
||||
await this.notifyRaid({id: signup.raidid})
|
||||
|
||||
return await this.getToken(character, item)
|
||||
}
|
||||
}
|
||||
@@ -205,6 +224,8 @@ implements FrontworkComponent<ItemManagerIfc, ItemManagerFeatureIfc>, TableDefin
|
||||
})
|
||||
}
|
||||
await tx.commit()
|
||||
await this.notifyRaid({id: signup.raidid})
|
||||
|
||||
return await this.getToken(character, item)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { SubscriptionResponse } from "rpclibrary"
|
||||
|
||||
export class IPubSub<UpdateType>{
|
||||
publish: (topic: string, p: UpdateType) => void
|
||||
subscribe: (topic:string, callback: (p:UpdateType)=>any) => Promise<SubscriptionResponse>
|
||||
unsubscribe: (uuid: string) => Promise<void>
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { Injectable } from "../../Injector/ServiceDecorator";
|
||||
import { SubscriptionResponse, makeSubResponse, RPCExporter } from "rpclibrary";
|
||||
import { IPubSub } from "./Interface";
|
||||
|
||||
@Injectable(IPubSub)
|
||||
export class PubSub<UpdateType = any>
|
||||
implements RPCExporter{
|
||||
name = "PubSub"
|
||||
subs : {
|
||||
[topic in string]: {
|
||||
[uuid in string]: (p:UpdateType)=>any
|
||||
}
|
||||
}= {}
|
||||
|
||||
exportRPCs = () => [
|
||||
this.unsubscribe,
|
||||
{
|
||||
name: 'subscribe',
|
||||
hook: this.subscribe,
|
||||
onClose: (subres, rpcName) => {
|
||||
this.unsubscribe(subres.uuid)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
publish = ( topic: string, msg: UpdateType ) => {
|
||||
if(!this.subs[topic]) this.subs[topic] = {}
|
||||
Object.entries(this.subs[topic]).forEach(([uuid, callback]:[string, Function]) => {
|
||||
try{
|
||||
callback(msg)
|
||||
}catch(e){
|
||||
delete this.subs[topic][uuid]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
subscribe = async (topic:string, callback:(p:UpdateType)=>any) : Promise<SubscriptionResponse<{topic: string}>> => {
|
||||
const resp = makeSubResponse({
|
||||
topic: topic
|
||||
})
|
||||
if(!this.subs[topic]) this.subs[topic] = {}
|
||||
this.subs[topic][resp.uuid] = callback
|
||||
return resp
|
||||
}
|
||||
|
||||
private unsubscribe = async (uuid: string) => {
|
||||
Object.entries(this.subs).forEach(([topic, submap]) => {
|
||||
delete submap[uuid]
|
||||
if(Object.keys(submap).length === 0)
|
||||
delete this.subs[topic]
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { IPubSub } from "./Interface";
|
||||
|
||||
export type PubSubIfc<UpdateType = any> = {
|
||||
PubSub:{
|
||||
subscribe: IPubSub<UpdateType>['subscribe']
|
||||
unsubscribe: IPubSub<UpdateType>['unsubscribe']
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,12 @@ import { ICharacterManager } from "../Character/Interface";
|
||||
import { _Tiers } from "../../Types/Items";
|
||||
import { IItemManager } from "../Item/Interface";
|
||||
import { ItemManager } from "../Item/ItemManager";
|
||||
import { IPubSub } from "../PubSub/Interface";
|
||||
|
||||
@Injectable(IRaidManager)
|
||||
export class RaidManager
|
||||
implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManager{
|
||||
name = "RaidManager" as "RaidManager";
|
||||
implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManager {
|
||||
name = "RaidManager" as "RaidManager";
|
||||
|
||||
@Inject(IAdmin)
|
||||
private admin: IAdmin
|
||||
@@ -27,6 +28,9 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
|
||||
@Inject(ItemManager)
|
||||
private itemManager: IItemManager
|
||||
|
||||
@Inject(IPubSub)
|
||||
private pubsub: IPubSub<any>
|
||||
|
||||
exportRPCs = () => [
|
||||
this.getRaids,
|
||||
this.getRaidData,
|
||||
@@ -46,7 +50,7 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
|
||||
this.startRaid,
|
||||
this.adminUnsign
|
||||
]
|
||||
},{
|
||||
}, {
|
||||
name: 'signup' as 'signup',
|
||||
exportRPCs: () => [
|
||||
this.getSignups,
|
||||
@@ -55,7 +59,7 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
|
||||
]
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
getTableDefinitions(): TableDefiniton[] {
|
||||
return [
|
||||
{
|
||||
@@ -68,13 +72,13 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
|
||||
table.integer('size').defaultTo(40)
|
||||
table.string('tier').defaultTo('null')
|
||||
}
|
||||
},{
|
||||
}, {
|
||||
name: 'archive',
|
||||
tableBuilder: (table) => {
|
||||
table.integer('id').primary()
|
||||
table.json('raiddata').notNullable()
|
||||
}
|
||||
},{
|
||||
}, {
|
||||
name: 'signups',
|
||||
tableBuilder: (table) => {
|
||||
table.increments('id').primary()
|
||||
@@ -86,55 +90,67 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
|
||||
table.boolean('benched').defaultTo('false')
|
||||
table.boolean('late')
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
createRaid = async (raid:Raid) : Promise<Raid>=> {
|
||||
const ids:number[] = await this.admin
|
||||
.knex('raids')
|
||||
.insert(raid)
|
||||
notifyRaid = async (raid:Raid | {id:number}) => {
|
||||
const data = await this.getRaidData(<Raid>raid)
|
||||
this.pubsub.publish(""+raid.id, data)
|
||||
await this.notifyRaids()
|
||||
}
|
||||
|
||||
return await this.admin.knex('raids').where({id: ids[0]}).first()
|
||||
notifyRaids = async () => {
|
||||
this.pubsub.publish('raids', undefined)
|
||||
}
|
||||
|
||||
createRaid = async (raid: Raid): Promise<Raid> => {
|
||||
const ids: number[] = await this.admin
|
||||
.knex('raids')
|
||||
.insert(raid)
|
||||
|
||||
await this.notifyRaid({ id: ids[0] })
|
||||
|
||||
return await this.admin.knex('raids').where({ id: ids[0] }).first()
|
||||
}
|
||||
|
||||
addSignup = async (signup: Signup) => {
|
||||
|
||||
const ids:number[] = await this.admin
|
||||
.knex('signups')
|
||||
.insert(signup)
|
||||
return await this.admin.knex('signups').where({id: ids[0]}).first()
|
||||
const ids: number[] = await this.admin
|
||||
.knex('signups')
|
||||
.insert(signup)
|
||||
return await this.admin.knex('signups').where({ id: ids[0] }).first()
|
||||
|
||||
}
|
||||
|
||||
removeSignup = async (signup: Signup) => await this.admin
|
||||
.knex('signups')
|
||||
.where({
|
||||
raid_id: signup.raidid,
|
||||
character_id: signup.characterid
|
||||
})
|
||||
.del()
|
||||
.knex('signups')
|
||||
.where({
|
||||
raid_id: signup.raidid,
|
||||
character_id: signup.characterid
|
||||
})
|
||||
.del()
|
||||
|
||||
getRaids = async () : Promise<Raid[]> => {
|
||||
getRaids = async (): Promise<Raid[]> => {
|
||||
|
||||
const subQuery = this.admin
|
||||
.knex('signups')
|
||||
.count('*')
|
||||
.where({
|
||||
raidid: this.admin.knex.ref('raids.id'),
|
||||
benched: false,
|
||||
late: false
|
||||
})
|
||||
.as('signupcount')
|
||||
|
||||
.knex('signups')
|
||||
.count('*')
|
||||
.where({
|
||||
raidid: this.admin.knex.ref('raids.id'),
|
||||
benched: false,
|
||||
late: false
|
||||
})
|
||||
.as('signupcount')
|
||||
|
||||
return await this.admin.knex('raids')
|
||||
.select('*', subQuery)
|
||||
.orderBy('start', 'asc')
|
||||
.select('*', subQuery)
|
||||
.orderBy('start', 'asc')
|
||||
}
|
||||
|
||||
startRaid = async (raid:Raid) : Promise<RaidData> => {
|
||||
startRaid = async (raid: Raid): Promise<RaidData> => {
|
||||
const archived = await this.archiveRaid(raid)
|
||||
|
||||
|
||||
const giveCurrency = async (b: Character) => {
|
||||
const usr = await this.characterManager.getUserOfCharacter(b)
|
||||
await this.userManager.incrementCurrency(usr, raid.tier, 1)
|
||||
@@ -142,122 +158,125 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
|
||||
|
||||
await Promise.all([
|
||||
...archived.participants.bench.map(giveCurrency),
|
||||
...Object.values(archived.participants).map((group: any) => group.map(giveCurrency))
|
||||
...Object.values(archived.participants).flat().flatMap((b:Signup & Character & Spec) => giveCurrency(b))
|
||||
])
|
||||
|
||||
await this.notifyRaids()
|
||||
|
||||
return archived
|
||||
}
|
||||
|
||||
archiveRaid = async (raid:Raid) : Promise<RaidData> => {
|
||||
archiveRaid = async (raid: Raid): Promise<RaidData> => {
|
||||
const raidData = await this.getRaidData(raid)
|
||||
|
||||
//const tx = await this.admin.knex.transaction()
|
||||
|
||||
await this.admin.knex('archive')
|
||||
//.transacting(tx)
|
||||
.insert({
|
||||
id:raidData.id,
|
||||
raiddata: JSON.stringify(raidData)
|
||||
})
|
||||
//.transacting(tx)
|
||||
.insert({
|
||||
id: raidData.id,
|
||||
raiddata: JSON.stringify(raidData)
|
||||
})
|
||||
|
||||
await Promise.all(
|
||||
Object.values(raidData.participants).flat().flatMap((signup) => this.admin
|
||||
.knex(raid.tier+'tokens')
|
||||
Object.values(raidData.participants).flat().flatMap((p: (Signup & Character & Spec)) =>
|
||||
this.admin
|
||||
.knex(raid.tier + 'tokens')
|
||||
//.transacting(tx)
|
||||
.where({
|
||||
characterid: signup.characterid,
|
||||
characterid: p.characterid,
|
||||
signupid: null
|
||||
})
|
||||
.del()
|
||||
))
|
||||
))
|
||||
|
||||
await this.admin.knex('raids')
|
||||
//.transacting(tx)
|
||||
.where('id', '=', raid.id)
|
||||
.del()
|
||||
//.transacting(tx)
|
||||
.where('id', '=', raid.id)
|
||||
.del()
|
||||
//await tx.commit()
|
||||
|
||||
|
||||
|
||||
const row = await this.admin.knex('archive')
|
||||
.select('*')
|
||||
.where({
|
||||
id:raidData.id,
|
||||
})
|
||||
.first()
|
||||
.select('*')
|
||||
.where({
|
||||
id: raidData.id,
|
||||
})
|
||||
.first()
|
||||
return JSON.parse(row.raiddata)
|
||||
}
|
||||
|
||||
getArchiveRaid = async(id:number) : Promise<RaidData> => {
|
||||
getArchiveRaid = async (id: number): Promise<RaidData> => {
|
||||
const data = await this.admin.knex('archive').select('raiddata').where({
|
||||
id: id
|
||||
}).first()
|
||||
|
||||
|
||||
return JSON.parse(data.raiddata)
|
||||
}
|
||||
|
||||
getPastRaids = async(limit: number) : Promise<RaidData[]> => {
|
||||
getPastRaids = async (limit: number): Promise<RaidData[]> => {
|
||||
const raids = await this.admin.knex('archive')
|
||||
.select('*')
|
||||
.orderBy('id', 'desc')
|
||||
.limit(limit)
|
||||
.select('*')
|
||||
.orderBy('id', 'desc')
|
||||
.limit(limit)
|
||||
|
||||
return raids.map(raid => JSON.parse(raid.raiddata))
|
||||
}
|
||||
|
||||
getRaidData = async (raid:Raid) : Promise<RaidData> => {
|
||||
getRaidData = async (raid: Raid): Promise<RaidData> => {
|
||||
const raiddata = {
|
||||
participants:{
|
||||
Druid: <(Signup&Character&Spec)[]>[],
|
||||
Hunter: <(Signup&Character&Spec)[]>[],
|
||||
Mage: <(Signup&Character&Spec)[]>[],
|
||||
Paladin: <(Signup&Character&Spec)[]>[],
|
||||
Priest: <(Signup&Character&Spec)[]>[],
|
||||
Rogue: <(Signup&Character&Spec)[]>[],
|
||||
Shaman: <(Signup&Character&Spec)[]>[],
|
||||
Warlock: <(Signup&Character&Spec)[]>[],
|
||||
Warrior: <(Signup&Character&Spec)[]>[],
|
||||
late: <(Signup&Character&Spec)[]>[],
|
||||
bench: <(Signup&Character&Spec)[]>[],
|
||||
participants: {
|
||||
Druid: <(Signup & Character & Spec)[]>[],
|
||||
Hunter: <(Signup & Character & Spec)[]>[],
|
||||
Mage: <(Signup & Character & Spec)[]>[],
|
||||
Paladin: <(Signup & Character & Spec)[]>[],
|
||||
Priest: <(Signup & Character & Spec)[]>[],
|
||||
Rogue: <(Signup & Character & Spec)[]>[],
|
||||
Shaman: <(Signup & Character & Spec)[]>[],
|
||||
Warlock: <(Signup & Character & Spec)[]>[],
|
||||
Warrior: <(Signup & Character & Spec)[]>[],
|
||||
late: <(Signup & Character & Spec)[]>[],
|
||||
bench: <(Signup & Character & Spec)[]>[],
|
||||
},
|
||||
tokens:{},
|
||||
healers:<(Signup&Character&Spec)[]>[],
|
||||
tanks:<(Signup&Character&Spec)[]>[]
|
||||
tokens: {},
|
||||
healers: <(Signup & Character & Spec)[]>[],
|
||||
tanks: <(Signup & Character & Spec)[]>[]
|
||||
}
|
||||
//const tx = await this.admin.knex.transaction()
|
||||
|
||||
const subQuery = this.admin
|
||||
.knex('signups')
|
||||
.count('*')
|
||||
.where({
|
||||
raidid: this.admin.knex.ref('raids.id'),
|
||||
benched: false,
|
||||
late: false
|
||||
})
|
||||
.as('signupcount')
|
||||
.knex('signups')
|
||||
.count('*')
|
||||
.where({
|
||||
raidid: this.admin.knex.ref('raids.id'),
|
||||
benched: false,
|
||||
late: false
|
||||
})
|
||||
.as('signupcount')
|
||||
|
||||
|
||||
const raidInDb: Raid = await this.admin.knex('raids')
|
||||
.select('*', subQuery)
|
||||
//.transacting(tx)
|
||||
.where('id','=',raid.id)
|
||||
.first()
|
||||
.select('*', subQuery)
|
||||
//.transacting(tx)
|
||||
.where('id', '=', raid.id)
|
||||
.first()
|
||||
|
||||
const characterData: (Signup & Character & Spec)[] = await this.admin
|
||||
.knex('signups as s')
|
||||
//.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('characters as c', 's.characterid','=','c.id')
|
||||
.join('users as u', 'c.userid','=','u.id')
|
||||
.join('specs as sp', 'specid','=','sp.id')
|
||||
.where('r.id','=',raid.id)
|
||||
|
||||
.knex('signups as s')
|
||||
//.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('characters as c', 's.characterid', '=', 'c.id')
|
||||
.join('users as u', 'c.userid', '=', 'u.id')
|
||||
.join('specs as sp', 'specid', '=', 'sp.id')
|
||||
.where('r.id', '=', raid.id)
|
||||
|
||||
characterData.forEach(data => {
|
||||
if(data.benched){
|
||||
if (data.benched) {
|
||||
raiddata.participants.bench.push(data)
|
||||
return
|
||||
}
|
||||
if(data.late){
|
||||
if (data.late) {
|
||||
raiddata.participants.late.push(data)
|
||||
return
|
||||
}
|
||||
@@ -265,42 +284,42 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
|
||||
})
|
||||
|
||||
const tokenData: (Character & SRToken & Item)[] = await this.admin
|
||||
.knex('signups as s')
|
||||
//.transacting(tx)
|
||||
.select('*', 's.id as id')
|
||||
.join('raids as r', 's.raidid','=','r.id')
|
||||
.join('characters as c', 's.characterid','=','c.id')
|
||||
.join(raidInDb.tier+'tokens as t', 't.characterid','=','c.id')
|
||||
.join('items as i', 'i.itemname','=','t.itemname')
|
||||
.where({
|
||||
'r.id': raid.id,
|
||||
})
|
||||
.andWhere(function(){
|
||||
this.whereNotNull('t.signupid')
|
||||
})
|
||||
.knex('signups as s')
|
||||
//.transacting(tx)
|
||||
.select('*', 's.id as id')
|
||||
.join('raids as r', 's.raidid', '=', 'r.id')
|
||||
.join('characters as c', 's.characterid', '=', 'c.id')
|
||||
.join(raidInDb.tier + 'tokens as t', 't.characterid', '=', 'c.id')
|
||||
.join('items as i', 'i.itemname', '=', 't.itemname')
|
||||
.where({
|
||||
'r.id': raid.id,
|
||||
})
|
||||
.andWhere(function () {
|
||||
this.whereNotNull('t.signupid')
|
||||
})
|
||||
|
||||
//await tx.commit()
|
||||
|
||||
tokenData.forEach(data => {
|
||||
if(!raiddata.tokens[data.itemname])
|
||||
if (!raiddata.tokens[data.itemname])
|
||||
raiddata.tokens[data.itemname] = []
|
||||
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)"))
|
||||
(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"))
|
||||
(healers: any[]) => healers.filter((p: any) =>
|
||||
!p.benched
|
||||
&& !p.late
|
||||
&& (p.specname === "Holy"
|
||||
|| p.specname === "Discipline"
|
||||
|| p.specname === "Restoration"))
|
||||
)
|
||||
|
||||
return {
|
||||
@@ -308,128 +327,137 @@ implements FrontworkComponent<RaidManagerIfc, RaidManagerFeatureIfc>, IRaidManag
|
||||
...raiddata
|
||||
}
|
||||
}
|
||||
|
||||
getSignups = async (raid:Raid) : Promise<(Signup & Character & Spec & User)[]> => await this.admin
|
||||
.knex('signups as si')
|
||||
.join('characters as c', 'c.id', '=', 'characterid')
|
||||
.join('specs as s', 's.id', '=', 'specid')
|
||||
.join('users as u', 'u.id', '=', 'userid')
|
||||
.select('*','si.id as id')
|
||||
.where('raidid', '=', raid.id!)
|
||||
|
||||
sign = async (usertoken:string, character:Character, raid:Raid, late:boolean) => {
|
||||
|
||||
getSignups = async (raid: Raid): Promise<(Signup & Character & Spec & User)[]> => await this.admin
|
||||
.knex('signups as si')
|
||||
.join('characters as c', 'c.id', '=', 'characterid')
|
||||
.join('specs as s', 's.id', '=', 'specid')
|
||||
.join('users as u', 'u.id', '=', 'userid')
|
||||
.select('*', 'si.id as id')
|
||||
.where('raidid', '=', raid.id!)
|
||||
|
||||
sign = async (usertoken: string, character: Character, raid: Raid, late: boolean) => {
|
||||
const maybeUserRecord = this.userManager.getUserRecordByToken(usertoken)
|
||||
if(!maybeUserRecord || maybeUserRecord.user.id != character.userid){
|
||||
if (!maybeUserRecord || maybeUserRecord.user.id != character.userid) {
|
||||
throw new Error("Bad Usertoken")
|
||||
}
|
||||
//const tx = await this.admin.knex.transaction()
|
||||
|
||||
const exists = await this.admin
|
||||
.knex('signups')
|
||||
//.transacting(tx)
|
||||
.select('*')
|
||||
.where({
|
||||
raidid: raid.id!,
|
||||
characterid: character.id!,
|
||||
})
|
||||
.first()
|
||||
|
||||
if(!exists){
|
||||
await this.admin
|
||||
.knex('signups')
|
||||
//.transacting(tx)
|
||||
.insert({
|
||||
raidid: raid.id!,
|
||||
characterid: character.id!,
|
||||
late: late,
|
||||
benched: false,
|
||||
})
|
||||
}else{
|
||||
await this.admin
|
||||
.knex('signups')
|
||||
//.transacting(tx)
|
||||
.select('*')
|
||||
.where({
|
||||
id: exists.id
|
||||
})
|
||||
.update({
|
||||
raidid: raid.id!,
|
||||
characterid: character.id!,
|
||||
late: late,
|
||||
benched: false,
|
||||
})
|
||||
.first()
|
||||
|
||||
if (!exists) {
|
||||
await this.admin
|
||||
.knex('signups')
|
||||
//.transacting(tx)
|
||||
.insert({
|
||||
raidid: raid.id!,
|
||||
characterid: character.id!,
|
||||
late: late,
|
||||
benched: false,
|
||||
})
|
||||
} else {
|
||||
await this.admin
|
||||
.knex('signups')
|
||||
//.transacting(tx)
|
||||
.where({
|
||||
id: exists.id
|
||||
})
|
||||
.update({
|
||||
raidid: raid.id!,
|
||||
characterid: character.id!,
|
||||
late: late,
|
||||
benched: false,
|
||||
})
|
||||
}
|
||||
//await tx.commit()
|
||||
|
||||
await this.notifyRaid(raid)
|
||||
|
||||
return await this.admin
|
||||
.knex('signups')
|
||||
.select('*')
|
||||
.where({
|
||||
raidid: raid.id!,
|
||||
characterid: character.id!,
|
||||
})
|
||||
.first()
|
||||
.knex('signups')
|
||||
.select('*')
|
||||
.where({
|
||||
raidid: raid.id!,
|
||||
characterid: character.id!,
|
||||
})
|
||||
.first()
|
||||
}
|
||||
|
||||
unsign = async (usertoken:string, character:Character, raid:Raid) => {
|
||||
unsign = async (usertoken: string, character: Character, raid: Raid) => {
|
||||
const maybeUserRecord = this.userManager.getUserRecordByToken(usertoken)
|
||||
if(!maybeUserRecord || maybeUserRecord.user.id != character.userid){
|
||||
if (!maybeUserRecord || maybeUserRecord.user.id != character.userid) {
|
||||
throw new Error("Bad Usertoken")
|
||||
}
|
||||
|
||||
return await this.adminUnsign(character, raid)
|
||||
return await this.adminUnsign(character, raid)
|
||||
}
|
||||
|
||||
adminUnsign = async (character:Character, raid: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()
|
||||
.where({
|
||||
"si.raidid": raid.id!,
|
||||
"si.characterid": character.id!,
|
||||
}).first()
|
||||
|
||||
const tokens = await this.itemManager.getTokens(character, [raid.tier], true)
|
||||
|
||||
const tokens = await this.admin.knex(raid.tier+'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, raid.tier, 1)
|
||||
const prio = await this.itemManager.calculatePriorities(token.itemname, character)
|
||||
if(token.level <= prio+1){
|
||||
await this.admin.knex(raid.tier+'tokens')
|
||||
.where({
|
||||
characterid: character.id,
|
||||
itemname: token.itemname
|
||||
}).del()
|
||||
}else{
|
||||
await this.admin.knex(raid.tier+'tokens')
|
||||
.where({
|
||||
characterid: character.id,
|
||||
itemname: token.itemname
|
||||
}).update({
|
||||
signupid: null,
|
||||
level: token.level-1
|
||||
})
|
||||
}
|
||||
})
|
||||
)
|
||||
if (tokens) {
|
||||
Promise.all(
|
||||
tokens.map(async token => {
|
||||
await this.userManager.incrementCurrency(user, raid.tier, 1)
|
||||
const prio = await this.itemManager.calculatePriorities(token.itemname, character)
|
||||
if (token.level <= prio + 1) {
|
||||
await this.admin
|
||||
.knex(raid.tier + 'tokens')
|
||||
.where({
|
||||
characterid: character.id,
|
||||
itemname: token.itemname
|
||||
}).del()
|
||||
} else {
|
||||
await this.admin
|
||||
.knex(raid.tier + 'tokens')
|
||||
.where({
|
||||
characterid: character.id,
|
||||
itemname: token.itemname
|
||||
}).update({
|
||||
signupid: null,
|
||||
level: token.level - 1
|
||||
})
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
await this.admin.knex('signups')
|
||||
.where({
|
||||
raidid: raid.id!,
|
||||
characterid: character.id!,
|
||||
})
|
||||
.del()
|
||||
.where({
|
||||
raidid: raid.id!,
|
||||
characterid: character.id!,
|
||||
})
|
||||
.del()
|
||||
|
||||
await this.notifyRaid(raid)
|
||||
}
|
||||
|
||||
setBenched = async (signup: Signup) : Promise<void> => {
|
||||
setBenched = async (signup: Signup): Promise<void> => {
|
||||
await this.admin.knex('signups')
|
||||
.where({
|
||||
raidid: signup.raidid,
|
||||
characterid: signup.characterid
|
||||
})
|
||||
.update(signup)
|
||||
.where({
|
||||
raidid: signup.raidid,
|
||||
characterid: signup.characterid
|
||||
})
|
||||
.update(signup)
|
||||
|
||||
await this.notifyRaid({ id: signup.raidid })
|
||||
}
|
||||
}
|
||||
@@ -455,6 +455,4 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
|
||||
.where('id', '=', user.id)
|
||||
.update(tier, value)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Injector } from "./Injector";
|
||||
import { Type, GenericClassDecorator } from "./Util";
|
||||
import { FrontworkComponent } from "../Types/FrontworkComponent";
|
||||
import { RPCExporter } from "rpclibrary";
|
||||
|
||||
/**
|
||||
* @returns {GenericClassDecorator<Type<any>>}
|
||||
@@ -21,7 +22,7 @@ export const Injectable = (_interface?: Type<any>) : GenericClassDecorator<Type<
|
||||
*/
|
||||
export const RootComponent = (config : {
|
||||
injectable : Type<any>
|
||||
injects : Type<FrontworkComponent>[]
|
||||
injects : Type<RPCExporter>[]
|
||||
}) : GenericClassDecorator<Type<any>> => {
|
||||
return (target: Type<any>) => {
|
||||
Injector.rootModules = config.injects
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ItemManagerFeatureIfc, ItemManagerIfc } from "../Components/Item/RPCInt
|
||||
import { GuildManagerFeatureIfc, GuildManagerIfc } from "../Components/Guild/RPCInterface";
|
||||
import { ShoutboxIfc } from "../Components/Shoutbox/RPCInterface";
|
||||
import { Tiers } from "./Items";
|
||||
import { PubSubIfc } from "../Components/PubSub/RPCInterface";
|
||||
|
||||
export type FrontcraftIfc = RaidManagerIfc
|
||||
& UserManagerIfc
|
||||
@@ -14,6 +15,7 @@ export type FrontcraftIfc = RaidManagerIfc
|
||||
& ItemManagerIfc
|
||||
& GuildManagerIfc
|
||||
& ShoutboxIfc
|
||||
& PubSubIfc
|
||||
|
||||
export type FrontcraftFeatureIfc = RaidManagerFeatureIfc
|
||||
& UserManagerFeatureIfc
|
||||
|
||||
Generated
+3
-3
@@ -14269,9 +14269,9 @@
|
||||
"integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ=="
|
||||
},
|
||||
"rpclibrary": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.6.2.tgz",
|
||||
"integrity": "sha512-lQTU4XkB9CSHz7YgtAcpVfyR5XrmTRX4P4eQjK6DDUjqKSFvJb5ChXjHnt1BcaNWbJ2VqmhCNVbcoyunJ2u7Rg==",
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.7.1.tgz",
|
||||
"integrity": "sha512-Ibo3qfURnQgZAq0eA2o+L9+PWaloJ4PHZs4ak42LL9fRgdWZXn33HAtowV0K2HVckbvrBvFqj/+PWTrWWBSOeg==",
|
||||
"requires": {
|
||||
"bsock": "^0.1.9",
|
||||
"http": "0.0.0",
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
"normalize.css": "6.0.0",
|
||||
"pace-js": "1.0.2",
|
||||
"roboto-fontface": "0.8.0",
|
||||
"rpclibrary": "^1.6.2",
|
||||
"rpclibrary": "^1.7.1",
|
||||
"rxjs": "6.5.2",
|
||||
"rxjs-compat": "6.3.0",
|
||||
"socicon": "3.0.5",
|
||||
|
||||
@@ -1,213 +1,172 @@
|
||||
<nb-card class="col-12 col-xl-9">
|
||||
<nb-card-body>
|
||||
<nb-tabset>
|
||||
<nb-tab tabTitle="Info">
|
||||
<h1>
|
||||
<img [src]="'../../../../assets/images/'+(raid.tier || 'null').toLowerCase()+'.png'" style="height: 100px" />
|
||||
{{raid.title}}
|
||||
</h1>
|
||||
<p>
|
||||
{{raid.signupcount}} / {{raid.size}} signups
|
||||
</p>
|
||||
<p>
|
||||
{{raid.description}}
|
||||
</p>
|
||||
<div *ngIf="canSignup">
|
||||
<div *ngIf="isSignedup">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-xl-6">
|
||||
<nb-card [size]="giant">
|
||||
<nb-card-body>
|
||||
<nb-tabset>
|
||||
<nb-tab tabTitle="Info">
|
||||
<h1>
|
||||
<img [src]="'../../../../assets/images/'+(raid.tier || 'null').toLowerCase()+'.png'"
|
||||
style="height: 100px" />
|
||||
{{raid.title}}
|
||||
</h1>
|
||||
<p>
|
||||
You are signed as: {{mySignup.charactername}} ({{mySignup.race}} {{mySignup.specname}} {{mySignup.class}})<br />
|
||||
Status: {{mySignup.status}}
|
||||
{{raid.signupcount}} / {{raid.size}} signups
|
||||
</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
|
||||
(click)="unsign()"
|
||||
nbButton
|
||||
outline
|
||||
status="danger"
|
||||
size="medium">
|
||||
<nb-icon icon="close"></nb-icon>unsign
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="!isSignedup">
|
||||
<button
|
||||
(click)="signup()"
|
||||
nbButton
|
||||
outline
|
||||
status="success"
|
||||
size="medium">
|
||||
<nb-icon icon="person-done-outline"></nb-icon> sign up
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nb-tab>
|
||||
|
||||
<nb-tab tabTitle="Signups"
|
||||
[badgeText]="raid.signupcount"
|
||||
badgePosition="top right"
|
||||
[badgeStatus]="raid.signupcount<40?'warning':'success'">
|
||||
<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
|
||||
<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)="setLate(true)" *ngIf="mySignup.status !== 'Late'" nbButton outline
|
||||
status="warning" size="medium">
|
||||
<nb-icon icon="clock-outline"></nb-icon> Late
|
||||
</button>
|
||||
<button
|
||||
(click)="adminUnsign(participant)"
|
||||
*ngIf="manageRaid"
|
||||
nbButton
|
||||
outline
|
||||
status="danger"
|
||||
size="tiny">
|
||||
X
|
||||
<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 (click)="unsign()" nbButton outline status="danger" size="medium">
|
||||
<nb-icon icon="close"></nb-icon>unsign
|
||||
</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
|
||||
<div *ngIf="!isSignedup">
|
||||
<button (click)="signup()" nbButton outline status="success" size="medium">
|
||||
<nb-icon icon="person-done-outline"></nb-icon> sign up
|
||||
</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">
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
</nb-tab>
|
||||
<nb-tab tabTitle="Items" *ngIf="isSignedup && isTier">
|
||||
<shop [tier]="raid.tier" (onSelect)="itemSelect($event)"></shop>
|
||||
</nb-tab>
|
||||
<nb-tab tabTitle="Reserves" *ngIf="isTier">
|
||||
<input type="text" nbInput [(ngModel)]="search" (change)="changeSearch()" placeholder="Search" fullWidth="true">
|
||||
|
||||
<nb-list>
|
||||
<nb-list-item *ngFor="let item of displayedtokens | 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>
|
||||
</nb-tab>
|
||||
</nb-tabset>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
</nb-tab>
|
||||
<nb-tab tabTitle="Signups" [badgeText]="raid.signupcount" badgePosition="top right"
|
||||
[badgeStatus]="raid.signupcount<40?'warning':'success'">
|
||||
|
||||
<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">
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
</nb-tab>
|
||||
<nb-tab tabTitle="Admin" *ngIf="manageRaid">
|
||||
<button (click)="startRaid(raid)" nbButton outline status="success" size="medium">
|
||||
start
|
||||
</button>
|
||||
</nb-tab>
|
||||
</nb-tabset>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
</div>
|
||||
<div class="col-12 col-xl-6">
|
||||
<nb-card *ngIf="isTier">
|
||||
<nb-card-body>
|
||||
<nb-tabset>
|
||||
<nb-tab tabTitle="Reserves">
|
||||
<input type="text" nbInput [(ngModel)]="search" (change)="changeSearch()" placeholder="Search"
|
||||
fullWidth="true">
|
||||
|
||||
<nb-list>
|
||||
<nb-list-item *ngFor="let item of displayedtokens | 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="Items" *ngIf="isSignedup">
|
||||
<shop [tier]="raid.tier" (onSelect)="itemSelect($event)"></shop>
|
||||
</nb-tab>
|
||||
</nb-tabset>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ActivatedRoute, Router, NavigationStart } from '@angular/router';
|
||||
import { ApiService as ApiService } from '../../services/login-api';
|
||||
import { RaidData, Raid, Signup, Character, Spec, Item, SRToken } from '../../../../../../backend/Types/Types';
|
||||
import { NbWindowService, NbToastrService, NbDialogService } from '@nebular/theme';
|
||||
@@ -12,7 +12,7 @@ import { allItems } from '../../../../../../backend/Types/Items';
|
||||
selector: 'raid',
|
||||
templateUrl: './raid.component.html',
|
||||
})
|
||||
export class FrontcraftRaidComponent implements OnInit{
|
||||
export class FrontcraftRaidComponent implements OnInit, OnDestroy{
|
||||
|
||||
canSignup = false
|
||||
isSignedup = false
|
||||
@@ -41,6 +41,7 @@ export class FrontcraftRaidComponent implements OnInit{
|
||||
tokens = {}
|
||||
displayedtokens = {}
|
||||
search = ""
|
||||
uuid
|
||||
|
||||
constructor(
|
||||
private api: ApiService,
|
||||
@@ -50,6 +51,16 @@ export class FrontcraftRaidComponent implements OnInit{
|
||||
private toast: NbToastrService
|
||||
){
|
||||
window['r'] = this
|
||||
router.events.subscribe(event => {
|
||||
if (event instanceof NavigationStart) {
|
||||
this.ngOnDestroy()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
ngOnDestroy = () => {
|
||||
if(this.uuid)
|
||||
this.api.get('PubSub').unsubscribe(this.uuid)
|
||||
}
|
||||
|
||||
async ngOnInit(){
|
||||
@@ -60,9 +71,16 @@ export class FrontcraftRaidComponent implements OnInit{
|
||||
if(signupFeature){
|
||||
this.canSignup = true
|
||||
}
|
||||
this.refresh()
|
||||
await this.refresh()
|
||||
|
||||
const res = await this.api.get('PubSub').subscribe(""+this.raid.id!, (data: RaidData) => {
|
||||
this.display(data)
|
||||
})
|
||||
this.uuid = res.uuid
|
||||
}
|
||||
|
||||
|
||||
|
||||
itemSelect = async(item) => {
|
||||
this.dialogService.open(FrontcraftBuyTokenComponent, {
|
||||
context: {
|
||||
@@ -71,7 +89,7 @@ export class FrontcraftRaidComponent implements OnInit{
|
||||
tier: this.raid.tier,
|
||||
characterName: this.mySignup.charactername
|
||||
}
|
||||
}).onClose.subscribe(() => this.refresh())
|
||||
})
|
||||
}
|
||||
|
||||
signup = async () => {
|
||||
@@ -84,9 +102,7 @@ export class FrontcraftRaidComponent implements OnInit{
|
||||
context: {
|
||||
raid: this.raid,
|
||||
}
|
||||
}).onClose.subscribe(()=>{
|
||||
this.refresh()
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
async archiveRaid(raid:Raid){
|
||||
@@ -110,7 +126,6 @@ export class FrontcraftRaidComponent implements OnInit{
|
||||
id: this.mySignup.characterid,
|
||||
}, this.raid)
|
||||
this.toast.show('Success', 'Unsigned', { status: 'success' })
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
setLate = async (value:boolean) => {
|
||||
@@ -123,7 +138,6 @@ export class FrontcraftRaidComponent implements OnInit{
|
||||
id: this.mySignup.characterid,
|
||||
}, this.raid, value)
|
||||
this.toast.show('Signup', 'Success', { status: 'success' })
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
adminUnsign = async() => {
|
||||
@@ -133,7 +147,6 @@ export class FrontcraftRaidComponent implements OnInit{
|
||||
...this.mySignup,
|
||||
id: this.mySignup.characterid,
|
||||
}, this.raid)
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
refresh = async () => {
|
||||
@@ -143,6 +156,11 @@ export class FrontcraftRaidComponent implements OnInit{
|
||||
const raiddata = await raidManager.getRaidData(<any>{
|
||||
id: param
|
||||
})
|
||||
this.display(raiddata)
|
||||
|
||||
}
|
||||
|
||||
display = async (raiddata:RaidData) => {
|
||||
this.isTier = allItems[raiddata.tier] != null
|
||||
|
||||
this.raid = raiddata
|
||||
|
||||
@@ -16,24 +16,31 @@
|
||||
class="raidlist"
|
||||
style="cursor: pointer;">
|
||||
<div class="row">
|
||||
<div class="col-2">
|
||||
<img [src]="'../../../../assets/images/'+(raid.tier || 'null').toLowerCase()+'.png'" style="height: 75px" />
|
||||
</div>
|
||||
<img [src]="'../../../../assets/images/'+(raid.tier || 'null').toLowerCase()+'.png'"
|
||||
style="object-fit: contain"
|
||||
class="col-1 col-s-3" />
|
||||
|
||||
<div class="col-2 vcenter">
|
||||
{{raid.title}}
|
||||
</div>
|
||||
|
||||
<div class="col-2 vcenter">
|
||||
<nb-icon icon="checkmark-circle"></nb-icon> {{raid.signupcount}} / {{raid.size}}<br>
|
||||
</div>
|
||||
|
||||
<div class="col-2 vcenter">
|
||||
<nb-icon icon="clock-outline"></nb-icon> {{raid.start | date : 'HH:mm'}}
|
||||
</div>
|
||||
|
||||
<div class="col-4 vcenter">
|
||||
<nb-icon icon="calendar-outline"></nb-icon> {{raid.start | date : 'EEEE MMMM d'}}
|
||||
<div class="col-11 col-s-9" >
|
||||
<div class="row">
|
||||
<div class="col-12" style="padding-top: 5px">
|
||||
<h4>
|
||||
{{raid.title}}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="padding-top: 5px; padding-bottom: 5px; color:darkgray">
|
||||
<div class="col-6 col-md-3">
|
||||
<nb-icon icon="checkmark-circle"></nb-icon> {{raid.signupcount}} / {{raid.size}}<br>
|
||||
</div>
|
||||
|
||||
<div class="col-6 col-md-3">
|
||||
<nb-icon icon="clock-outline"></nb-icon> {{raid.start | date : 'HH:mm'}}
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6">
|
||||
<nb-icon icon="calendar-outline"></nb-icon> {{raid.start | date : 'EEE MMM d'}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nb-list-item>
|
||||
|
||||
@@ -10,7 +10,14 @@
|
||||
background-color: #293259;
|
||||
}
|
||||
|
||||
.vcenter {
|
||||
height: 75px;
|
||||
padding-top: 30px;
|
||||
.raid {
|
||||
height: 75px
|
||||
}
|
||||
|
||||
.row {
|
||||
margin: -0.5rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-weight: normal
|
||||
}
|
||||
@@ -1,30 +1,48 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ApiService } from '../../services/login-api';
|
||||
import { NbWindowService, NbDialogService } from '@nebular/theme';
|
||||
import { FrontcraftCreateRaidsComponent } from './createraid.compontent';
|
||||
import { Router, NavigationStart } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'raids',
|
||||
templateUrl: 'raids.component.html',
|
||||
styleUrls: ['raids.component.scss'],
|
||||
})
|
||||
export class FrontcraftRaidsComponent implements OnInit{
|
||||
export class FrontcraftRaidsComponent implements OnInit, OnDestroy{
|
||||
|
||||
|
||||
manageRaid
|
||||
raids = []
|
||||
oldraids = []
|
||||
pageSize = 10;
|
||||
uuid
|
||||
|
||||
constructor(
|
||||
private api: ApiService,
|
||||
private router: Router,
|
||||
private dialogService: NbDialogService
|
||||
) {
|
||||
this.manageRaid = this.api.get('manageRaid')
|
||||
|
||||
router.events.subscribe(event => {
|
||||
if (event instanceof NavigationStart) {
|
||||
this.ngOnDestroy()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
ngOnDestroy = () => {
|
||||
console.log("boom");
|
||||
|
||||
if(this.uuid)
|
||||
this.api.get('PubSub').unsubscribe(this.uuid)
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
const res = await this.api.get('PubSub').subscribe("raids", () => {
|
||||
this.refresh()
|
||||
})
|
||||
this.uuid = res.uuid
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
@@ -46,9 +64,7 @@ export class FrontcraftRaidsComponent implements OnInit{
|
||||
context: {
|
||||
templates: this.oldraids
|
||||
}
|
||||
}).onClose.subscribe(()=>{
|
||||
this.refresh()
|
||||
});
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,69 @@
|
||||
<nb-card-body>
|
||||
<nb-tabset>
|
||||
<nb-tab tabTitle="Info">
|
||||
Smart text here
|
||||
<h3>How it works</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Everyone starts out with 1 soft reserve right per raid tier (you can see them in your user profile)
|
||||
</li>
|
||||
<li>
|
||||
The tiers are: MC+Ony, BWL, ZG, AQ20, AQ40, Naxx
|
||||
</li>
|
||||
<li>
|
||||
You gain 1 reserve right for a raid you attend. 2 if you were benched. Rights are granted on raid start.
|
||||
</li>
|
||||
<li>
|
||||
When you sign up to a raid you can spend your reserve rights
|
||||
</li>
|
||||
<li>
|
||||
Every week you can re-reserve the same item to build a streak on it
|
||||
</li>
|
||||
<!--
|
||||
<li>
|
||||
Steaks are color coded. If this means anything will be decided by guild culture:
|
||||
<span style="color: #ff8000">[+ 10]</span>
|
||||
<span style="color: #a335ee">[9. 8]</span>
|
||||
<span style="color: #0070dd">[7, 6]</span>
|
||||
<span style="color: #1eff00">[5, 4]</span>
|
||||
<span style="color: #ffffff">[3, 2]</span>
|
||||
<span style="color: #9d9d9d">[1]</span>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
<br />
|
||||
<h3>Specifics about streaks</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Some classes and races get an initial boost to specific reserves. The list is on the second tab.
|
||||
</li>
|
||||
<li>
|
||||
Switching the selected item destroys previous streaks. (Streaks must be continued without switchup)
|
||||
</li>
|
||||
<li>
|
||||
If you have more than 1 softreserve you can reserve multiple different items. You may only continue one streak the following raid.
|
||||
</li>
|
||||
<li>
|
||||
If you have more than 1 softreserve you can reserve the same item several times to increase its streak.
|
||||
</li>
|
||||
<li>
|
||||
The softreserve counter, Reserves, and Streaks are tiers-specific and only count within their tier.
|
||||
</li>
|
||||
<li>
|
||||
Canceling the signup refunds active reserves and continued streaks. Destroyed streaks cannot be recovered.
|
||||
</li>
|
||||
</ul>
|
||||
</nb-tab>
|
||||
<nb-tab tabTitle="priorities">
|
||||
<nb-list>
|
||||
<nb-list-item *ngFor="let item of rules | keyvalue">
|
||||
<wowhead [item]="item.value[0]"></wowhead><br>
|
||||
<span *ngFor="let rule of item.value" [nbPopover]="templateRef" nbPopoverTrigger="hover">
|
||||
<ng-template #templateRef>
|
||||
<span style="color:white">{{rule.description}}</span>
|
||||
</ng-template>
|
||||
<span *ngIf="rule.modifier>0">+</span>{{rule.modifier}} {{rule.race}} <span [ngStyle]="{'color':rule.color}">{{rule.specname}} {{rule.class}}</span> <br />
|
||||
</span>
|
||||
<div class="row" *ngFor="let rule of item.value">
|
||||
<div class="col-4">
|
||||
<span *ngIf="rule.modifier>0">+</span>{{rule.modifier}} {{rule.race}} <span [ngStyle]="{'color':rule.color}">{{rule.specname}} {{rule.class}}</span>
|
||||
</div>
|
||||
<div class="col-8" style="color:white"> ({{rule.description}})</div>
|
||||
<br />
|
||||
</div>
|
||||
</nb-list-item>
|
||||
</nb-list>
|
||||
</nb-tab>
|
||||
|
||||
Reference in New Issue
Block a user