migrations
This commit is contained in:
Binary file not shown.
Binary file not shown.
Generated
+53
-35
@@ -479,7 +479,8 @@
|
||||
"bluebird": {
|
||||
"version": "3.5.5",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
|
||||
"integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w=="
|
||||
"integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==",
|
||||
"dev": true
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.19.0",
|
||||
@@ -835,9 +836,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"colorette": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.0.8.tgz",
|
||||
"integrity": "sha512-X6Ck90ReaF+EfKdVGB7vdIQ3dr651BbIrBwY5YBKg13fjH+940sTtp7/Pkx33C6ntYfQcRumOs/aUQhaRPpbTQ=="
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.1.0.tgz",
|
||||
"integrity": "sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg=="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
@@ -850,7 +851,8 @@
|
||||
"commander": {
|
||||
"version": "2.20.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
|
||||
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ=="
|
||||
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
|
||||
"dev": true
|
||||
},
|
||||
"commondir": {
|
||||
"version": "1.0.1",
|
||||
@@ -2057,9 +2059,9 @@
|
||||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
|
||||
},
|
||||
"getopts": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.4.tgz",
|
||||
"integrity": "sha512-Rz7DGyomZjrenu9Jx4qmzdlvJgvrEFHXHvjK0FcZtcTC1U5FmES7OdZHUwMuSnEE6QvBvwse1JODKj7TgbSEjQ=="
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz",
|
||||
"integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA=="
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
@@ -2139,6 +2141,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"global-modules": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
|
||||
"integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
|
||||
"requires": {
|
||||
"global-prefix": "^1.0.1",
|
||||
"is-windows": "^1.0.1",
|
||||
"resolve-dir": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"global-prefix": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
|
||||
@@ -2731,27 +2743,37 @@
|
||||
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
|
||||
},
|
||||
"knex": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/knex/-/knex-0.19.2.tgz",
|
||||
"integrity": "sha512-TVYvlp2esS4LjjJSz8XuE48bPJq4N3lWnETQVgJ3hXPEqjiDjxcTa3bCn6F5ipQuBaMAAaFHNrqsZm7BttogdA==",
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/knex/-/knex-0.19.5.tgz",
|
||||
"integrity": "sha512-Hy258avCVircQq+oj3WBqPzl8jDIte438Qlq+8pt1i/TyLYVA4zPh2uKc7Bx0t+qOpa6D42HJ2jjtl2vagzilw==",
|
||||
"requires": {
|
||||
"bluebird": "^3.5.5",
|
||||
"colorette": "1.0.8",
|
||||
"commander": "^2.20.0",
|
||||
"bluebird": "^3.7.0",
|
||||
"colorette": "1.1.0",
|
||||
"commander": "^3.0.2",
|
||||
"debug": "4.1.1",
|
||||
"getopts": "2.2.4",
|
||||
"getopts": "2.2.5",
|
||||
"inherits": "~2.0.4",
|
||||
"interpret": "^1.2.0",
|
||||
"liftoff": "3.1.0",
|
||||
"lodash": "^4.17.15",
|
||||
"mkdirp": "^0.5.1",
|
||||
"pg-connection-string": "2.0.0",
|
||||
"pg-connection-string": "2.1.0",
|
||||
"tarn": "^2.0.0",
|
||||
"tildify": "2.0.0",
|
||||
"uuid": "^3.3.2",
|
||||
"uuid": "^3.3.3",
|
||||
"v8flags": "^3.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"bluebird": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
|
||||
},
|
||||
"commander": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
|
||||
"integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow=="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
@@ -3948,9 +3970,9 @@
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
|
||||
},
|
||||
"pg-connection-string": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.0.0.tgz",
|
||||
"integrity": "sha1-Pu/lmX4G2Ugh5NUC5CtqHHP434I="
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.1.0.tgz",
|
||||
"integrity": "sha512-bhlV7Eq09JrRIvo1eKngpwuqKtJnNhZdpdOlvrPrA4dxqXPjxSrbNrfnIDmTpwMyRszrcV4kU5ZA4mMsQUrjdg=="
|
||||
},
|
||||
"picomatch": {
|
||||
"version": "2.2.1",
|
||||
@@ -4340,18 +4362,6 @@
|
||||
"requires": {
|
||||
"expand-tilde": "^2.0.0",
|
||||
"global-modules": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"global-modules": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
|
||||
"integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
|
||||
"requires": {
|
||||
"global-prefix": "^1.0.1",
|
||||
"is-windows": "^1.0.1",
|
||||
"resolve-dir": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"resolve-url": {
|
||||
@@ -4388,13 +4398,21 @@
|
||||
}
|
||||
},
|
||||
"rpclibrary": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.9.2.tgz",
|
||||
"integrity": "sha512-MOtVm0IBRLryXag1IwkYNPVFegbvW10+MbCjhr3GptO3MA7nHZ545ammgoCWnREtGOgFeN4Jib/EBDOJ9Ep41Q==",
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.10.2.tgz",
|
||||
"integrity": "sha512-uf4FtylK+tyVo1O8YVihxYxaI4KHnKBzq05SsLYe8ZPXdO8Hqrv7Je5cwv3bfx0FBCO1vVrSc8DT1P6ypGY6uQ==",
|
||||
"requires": {
|
||||
"bsock": "^0.1.9",
|
||||
"crypto-js": "^4.0.0",
|
||||
"http": "0.0.0",
|
||||
"uuid": "^3.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"crypto-js": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
|
||||
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"run-queue": {
|
||||
|
||||
+3
-2
@@ -4,6 +4,7 @@
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"tsc": "tsc",
|
||||
"knex": "knex",
|
||||
"launch": "node lib/src/backend/Launcher.js",
|
||||
"start": "npm run build && npm run launch",
|
||||
"start-backend": "npm run build-backend && npm run launch",
|
||||
@@ -37,7 +38,6 @@
|
||||
"git-cherrypicker": "0.0.3",
|
||||
"git-describe": "^4.0.4",
|
||||
"http": "0.0.0",
|
||||
"knex": "^0.19.2",
|
||||
"loadson": "^1.0.0",
|
||||
"log4js": "^4.5.1",
|
||||
"lowdb": "^1.0.0",
|
||||
@@ -46,7 +46,7 @@
|
||||
"path": "^0.12.7",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^3.0.0",
|
||||
"rpclibrary": "^1.9.2",
|
||||
"rpclibrary": "^1.10.2",
|
||||
"simple-git": "^1.124.0",
|
||||
"spawn-sync": "^2.0.0",
|
||||
"sqlite3": "^4.1.1",
|
||||
@@ -58,6 +58,7 @@
|
||||
"xmlhttprequest": "^1.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"knex": "^0.19.5",
|
||||
"madge": "^3.6.0",
|
||||
"mocha": "^7.1.0",
|
||||
"terser-webpack-plugin": "^1.4.1",
|
||||
|
||||
@@ -55,7 +55,11 @@ implements TableDefinitionExporter, IAdmin {
|
||||
dbConf: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: Path.resolve(__dirname, '../../../..', "data/frontworkAdmin.sqlite")
|
||||
filename: Path.resolve(__dirname, '../../../..', "data/frontworkAdmin.sqlite"),
|
||||
},
|
||||
migrations: {
|
||||
directory: Path.resolve(__dirname, '../../../..', "migrations"),
|
||||
extension: 'ts'
|
||||
},
|
||||
useNullAsDefault: true,
|
||||
}
|
||||
@@ -136,6 +140,7 @@ implements TableDefinitionExporter, IAdmin {
|
||||
this.express.get('*.*', (req, res) => {
|
||||
//console.log('*.*', req.path);
|
||||
res.sendFile(Path.join(__dirname, distFolder, 'browser', decodeURIComponent(req.path)))
|
||||
res.status(200)
|
||||
})
|
||||
|
||||
try {
|
||||
@@ -191,6 +196,10 @@ implements TableDefinitionExporter, IAdmin {
|
||||
return await this.knex.schema.createTable(def.name, def.tableBuilder)
|
||||
})
|
||||
)
|
||||
await this.knex.migrate.latest().catch(e => {
|
||||
getLogger('Admin#makeKnex').error(e)
|
||||
process.exit(-1)
|
||||
})
|
||||
return this.knex
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ 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, Raid, Stats } from "../../Types/Types";
|
||||
import { TableDefiniton, Item, Character, SRToken, SRPriority, Spec, Signup, Raid, Stats } from "../../Types/Types";
|
||||
import { IAdmin } from "../../Admin/Interface";
|
||||
import { IItemManager } from "./Interface";
|
||||
import { IUserManager } from "../User/Interface";
|
||||
@@ -171,7 +171,7 @@ export class ItemManager
|
||||
table.boolean('hidden').defaultTo(false).notNullable()
|
||||
table.string('tooltip').notNullable()
|
||||
table.enu('tier', _Tiers).notNullable()
|
||||
table.json('stats').notNullable()
|
||||
table.json('stats')
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { SubscriptionResponse } from "rpclibrary"
|
||||
|
||||
export class IPubSub<UpdateType>{
|
||||
publish: (topic: string, p: UpdateType) => Promise<void>
|
||||
subscribe: (topic:string, callback: (p:UpdateType)=>any) => Promise<SubscriptionResponse&{data:any}>
|
||||
subscribe: (topic:string, callback: (p:UpdateType)=>any) => Promise<string>
|
||||
unsubscribe: (uuid: string) => Promise<void>
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from "../../Injector/ServiceDecorator";
|
||||
import { SubscriptionResponse, makeSubResponse, RPCExporter } from "rpclibrary";
|
||||
import { RPCExporter } from "rpclibrary";
|
||||
import { IPubSub } from "./Interface";
|
||||
const uuidv4 = require('uuid/v4')
|
||||
|
||||
@Injectable(IPubSub)
|
||||
export class PubSub<UpdateType = any>
|
||||
@@ -34,13 +35,11 @@ implements RPCExporter{
|
||||
}))
|
||||
}
|
||||
|
||||
subscribe = async (topic:string, callback:(p:UpdateType)=>any) : Promise<SubscriptionResponse<{topic: string}>> => {
|
||||
const resp = makeSubResponse({
|
||||
topic: topic
|
||||
})
|
||||
subscribe = async (topic:string, callback:(p:UpdateType)=>any) : Promise<string> => {
|
||||
const uuid = uuidv4()
|
||||
if(!this.subs[topic]) this.subs[topic] = {}
|
||||
this.subs[topic][resp.uuid] = callback
|
||||
return resp
|
||||
this.subs[topic][uuid] = callback
|
||||
return uuid
|
||||
}
|
||||
|
||||
private unsubscribe = async (uuid: string) => {
|
||||
|
||||
@@ -6,7 +6,7 @@ export class IRaidManager{
|
||||
addSignup: (signup: Signup) => Promise<Signup>
|
||||
removeSignup: (signup: Signup) => Promise<any>
|
||||
getSignups: (raid:Raid) => Promise<(Signup & Character & Spec & User)[]>
|
||||
sign: (userToken: string, character:Character, raid:Raid, late:boolean) => Promise<any>
|
||||
sign: (userToken: string, character:Character, raid:Raid, late:boolean, memo?: string) => Promise<any>
|
||||
unsign: (userToken: string, character:Character, raid:Raid,) => Promise<any>
|
||||
archiveRaid: (raid:Raid) => Promise<RaidData>
|
||||
getRaidData: (raid:Raid) => Promise<RaidData>
|
||||
|
||||
@@ -7,9 +7,11 @@ import { IRaidManager } from "./Interface";
|
||||
import { IUserManager } from "../User/Interface";
|
||||
import { ICharacterManager } from "../Character/Interface";
|
||||
import { _Tiers } from "../../Types/Items";
|
||||
import { MAX_MEMO_LENGTH } from "../../Types/Constants";
|
||||
import { IItemManager } from "../Item/Interface";
|
||||
import { ItemManager } from "../Item/ItemManager";
|
||||
import { IPubSub } from "../PubSub/Interface";
|
||||
import { getLogger } from "log4js";
|
||||
|
||||
@Injectable(IRaidManager)
|
||||
export class RaidManager
|
||||
@@ -89,6 +91,8 @@ export class RaidManager
|
||||
table.foreign('characterid').references('id').inTable('characters').onDelete('CASCADE')
|
||||
table.boolean('benched').defaultTo('false')
|
||||
table.boolean('late')
|
||||
table.timestamp('timestamp').defaultTo(this.admin.knex.fn.now())
|
||||
table.string('memo').nullable()
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -96,12 +100,20 @@ export class RaidManager
|
||||
|
||||
notifyRaid = async (raid:Raid | {id:number}) => {
|
||||
const data = await this.getRaidData(<Raid>raid)
|
||||
this.pubsub.publish(""+raid.id, data)
|
||||
try{
|
||||
await this.pubsub.publish(String(raid.id), data)
|
||||
await this.notifyRaids()
|
||||
}catch(e){
|
||||
getLogger('RaidManager#notifyRaid').debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
notifyRaids = async () => {
|
||||
this.pubsub.publish('raids', undefined)
|
||||
try{
|
||||
await this.pubsub.publish('raids', undefined)
|
||||
}catch(e){
|
||||
getLogger('RaidManager#notifyRaids').debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
createRaid = async (raid: Raid): Promise<Raid> => {
|
||||
@@ -158,7 +170,7 @@ export class RaidManager
|
||||
|
||||
await Promise.all([
|
||||
...archived.participants.bench.map(giveCurrency),
|
||||
...Object.values(archived.participants).flat().flatMap((b:Signup & Character & Spec) => giveCurrency(b))
|
||||
...Object.values(archived.participants).flat().map((b:Signup & Character & Spec) => giveCurrency(b))
|
||||
])
|
||||
|
||||
await this.notifyRaids()
|
||||
@@ -169,10 +181,10 @@ export class RaidManager
|
||||
archiveRaid = async (raid: Raid): Promise<RaidData> => {
|
||||
const raidData = await this.getRaidData(raid)
|
||||
|
||||
//const tx = await this.admin.knex.transaction()
|
||||
const tx = await this.admin.knex.transaction()
|
||||
|
||||
await this.admin.knex('archive')
|
||||
//.transacting(tx)
|
||||
.transacting(tx)
|
||||
.insert({
|
||||
id: raidData.id,
|
||||
raiddata: JSON.stringify(raidData)
|
||||
@@ -182,7 +194,7 @@ export class RaidManager
|
||||
Object.values(raidData.participants).flat().flatMap((p: (Signup & Character & Spec)) =>
|
||||
this.admin
|
||||
.knex(raid.tier + 'tokens')
|
||||
//.transacting(tx)
|
||||
.transacting(tx)
|
||||
.where({
|
||||
characterid: p.characterid,
|
||||
signupid: null
|
||||
@@ -191,10 +203,10 @@ export class RaidManager
|
||||
))
|
||||
|
||||
await this.admin.knex('raids')
|
||||
//.transacting(tx)
|
||||
.transacting(tx)
|
||||
.where('id', '=', raid.id)
|
||||
.del()
|
||||
//await tx.commit()
|
||||
await tx.commit()
|
||||
|
||||
|
||||
const row = await this.admin.knex('archive')
|
||||
@@ -242,7 +254,6 @@ export class RaidManager
|
||||
healers: <(Signup & Character & Spec)[]>[],
|
||||
tanks: <(Signup & Character & Spec)[]>[]
|
||||
}
|
||||
//const tx = await this.admin.knex.transaction()
|
||||
|
||||
const subQuery = this.admin
|
||||
.knex('signups')
|
||||
@@ -257,14 +268,12 @@ export class RaidManager
|
||||
|
||||
const raidInDb: Raid = await this.admin.knex('raids')
|
||||
.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', 'rank', 'class', 'specid', 'specname', 'race', 'userid', 'benched', 'late', 'raidid', 'characterid', 'specid')
|
||||
.select('s.id as id', 'charactername', 'rank', 'class', 'specid', 'specname', 'race', 'userid', 'benched', 'late', 'raidid', 'characterid', 'specid', 'memo', 'timestamp')
|
||||
.join('raids as r', 's.raidid', '=', 'r.id')
|
||||
.join('characters as c', 's.characterid', '=', 'c.id')
|
||||
.join('users as u', 'c.userid', '=', 'u.id')
|
||||
@@ -285,7 +294,6 @@ export class RaidManager
|
||||
|
||||
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')
|
||||
@@ -300,8 +308,6 @@ export class RaidManager
|
||||
this.whereNotNull('t.signupid')
|
||||
})
|
||||
|
||||
//await tx.commit()
|
||||
|
||||
tokenData.forEach(data => {
|
||||
if (!raiddata.tokens[data.itemname])
|
||||
raiddata.tokens[data.itemname] = []
|
||||
@@ -338,16 +344,15 @@ export class RaidManager
|
||||
.select('*', 'si.id as id')
|
||||
.where('raidid', '=', raid.id!)
|
||||
|
||||
sign = async (usertoken: string, character: Character, raid: Raid, late: boolean) => {
|
||||
sign = async (usertoken: string, character: Character, raid: Raid, late: boolean, memo?: string) => {
|
||||
const maybeUserRecord = this.userManager.getUserRecordByToken(usertoken)
|
||||
if (!maybeUserRecord || maybeUserRecord.user.id != character.userid) {
|
||||
throw new Error("Bad Usertoken")
|
||||
}
|
||||
//const tx = await this.admin.knex.transaction()
|
||||
|
||||
if(memo) memo = memo.substring(0, MAX_MEMO_LENGTH)
|
||||
const exists = await this.admin
|
||||
.knex('signups')
|
||||
//.transacting(tx)
|
||||
.select('*')
|
||||
.where({
|
||||
raidid: raid.id!,
|
||||
@@ -358,17 +363,16 @@ export class RaidManager
|
||||
if (!exists) {
|
||||
await this.admin
|
||||
.knex('signups')
|
||||
//.transacting(tx)
|
||||
.insert({
|
||||
raidid: raid.id!,
|
||||
characterid: character.id!,
|
||||
late: late,
|
||||
benched: false,
|
||||
memo: memo
|
||||
})
|
||||
} else {
|
||||
await this.admin
|
||||
.knex('signups')
|
||||
//.transacting(tx)
|
||||
.where({
|
||||
id: exists.id
|
||||
})
|
||||
@@ -377,9 +381,9 @@ export class RaidManager
|
||||
characterid: character.id!,
|
||||
late: late,
|
||||
benched: false,
|
||||
memo: memo
|
||||
})
|
||||
}
|
||||
//await tx.commit()
|
||||
|
||||
await this.notifyRaid(raid)
|
||||
|
||||
@@ -405,13 +409,6 @@ export class RaidManager
|
||||
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.itemManager.getTokens(character, [raid.tier], true)
|
||||
|
||||
//check if token has to be deleted
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Raid, Signup, Character, RaidData } from "../../Types/Types"
|
||||
import { SubscriptionResponse } from "rpclibrary"
|
||||
|
||||
export type ShoutMessage = {
|
||||
message: string,
|
||||
@@ -10,5 +9,5 @@ export type ShoutMessage = {
|
||||
export class IShoutbox{
|
||||
shout: (uuid:string, msg: ShoutMessage) => Promise<void>
|
||||
getFeed: () => Promise<ShoutMessage[]>
|
||||
subscribe: (callback) => Promise<SubscriptionResponse>
|
||||
subscribe: (callback) => Promise<string>
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ import { ShoutboxFeatureIfc, ShoutboxIfc } from "./RPCInterface";
|
||||
import { FrontworkComponent } from "../../Types/FrontworkComponent";
|
||||
import { TableDefiniton } from "../../Types/Types";
|
||||
import { IShoutbox, ShoutMessage } from "./Interface";
|
||||
import { SubscriptionResponse, makeSubResponse } from "rpclibrary";
|
||||
import * as CircularBuffer from "circular-buffer";
|
||||
const uuid = require('uuid/v4')
|
||||
|
||||
@Injectable(IShoutbox)
|
||||
export class Shoutbox
|
||||
@@ -52,10 +52,10 @@ implements FrontworkComponent<ShoutboxIfc, ShoutboxFeatureIfc>, IShoutbox{
|
||||
return this.log.toarray()
|
||||
}
|
||||
|
||||
subscribe = async (callback) : Promise<SubscriptionResponse> => {
|
||||
const resp = makeSubResponse({})
|
||||
this.subs[resp.uuid] = callback
|
||||
return resp
|
||||
subscribe = async (callback) : Promise<string> => {
|
||||
uuid()
|
||||
this.subs[uuid] = callback
|
||||
return uuid
|
||||
}
|
||||
|
||||
unsubscribe = async (uuid: string) => {
|
||||
|
||||
@@ -6,10 +6,10 @@ import { RaidManager } from "../Raid/RaidManager";
|
||||
import { CharacterManager } from "../Character/CharacterManager";
|
||||
import { UserManagerFeatureIfc, UserManagerIfc } from "./RPCInterface";
|
||||
import { FrontworkComponent } from "../../Types/FrontworkComponent";
|
||||
import { Rank, User, Auth, _Rank, TableDefiniton, RPCPermission, FrontcraftFeatureIfc, AnyRPCExporter, Token, UserRecord } from "../../Types/Types";
|
||||
import { Rank, User, Auth, _Rank, TableDefiniton, RPCPermission, FrontcraftFeatureIfc, Token, UserRecord } from "../../Types/Types";
|
||||
import { IAdmin } from "../../Admin/Interface";
|
||||
import { IUserManager } from "./Interface";
|
||||
import { getLogger, Logger } from "log4js";
|
||||
import { getLogger } from "log4js";
|
||||
import { saltedHash } from "../../Util/hash";
|
||||
import { _Tiers, Tiers } from "../../Types/Items";
|
||||
import { ICharacterManager } from "../Character/Interface";
|
||||
@@ -24,8 +24,8 @@ const uuid = require('uuid/v4')
|
||||
const salt = "6pIbc6yjSN"
|
||||
const ONE_WEEK = 604800000
|
||||
|
||||
type Serverstate<SubresT, InterfaceT extends RPCInterface> = {
|
||||
server: RPCServer<SubresT, InterfaceT>,
|
||||
type Serverstate<InterfaceT extends RPCInterface> = {
|
||||
server: RPCServer<InterfaceT>,
|
||||
port: number,
|
||||
};
|
||||
|
||||
@@ -51,7 +51,7 @@ export class UserManager
|
||||
private character: CharacterManager
|
||||
|
||||
exporters: any[] = []
|
||||
rankServer: Serverstate<{}, FrontcraftFeatureIfc>
|
||||
rankServer: Serverstate<FrontcraftFeatureIfc>
|
||||
userLogins: { [username in string]: UserRecord } = {}
|
||||
allowed: string[] = []
|
||||
|
||||
@@ -376,12 +376,12 @@ export class UserManager
|
||||
return
|
||||
}
|
||||
|
||||
startRankServer = async (port: number): Promise<RPCServer<{}, FrontcraftFeatureIfc>> => {
|
||||
startRankServer = async (port: number): Promise<RPCServer<FrontcraftFeatureIfc>> => {
|
||||
let rpcs = [
|
||||
...this.exportRPCFeatures(),
|
||||
...this.exporters.flatMap((exp) => exp.exportRPCFeatures())
|
||||
]
|
||||
let rpcServer = new RPCServer<{}, FrontcraftFeatureIfc>(port, rpcs, {
|
||||
let rpcServer = new RPCServer<FrontcraftFeatureIfc>(port, rpcs, {
|
||||
accessFilter: async (sesame, exporter) => {
|
||||
const record = this.getUserRecordByToken(sesame!)
|
||||
if (!record) return false
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Injector } from "./Injector";
|
||||
import { Type, GenericClassDecorator } from "./Util";
|
||||
import { FrontworkComponent } from "../Types/FrontworkComponent";
|
||||
import { RPCExporter } from "rpclibrary";
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export const MAX_MEMO_LENGTH = 255
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RPCInterface, RPCExporter, RPCInterfaceArray } from "rpclibrary";
|
||||
import { RPCInterface, RPCExporter, RPCDefinitions } from "rpclibrary";
|
||||
import { PrivilegedRPCExporter } from "./PrivilegedRPCExporter";
|
||||
import { TableDefinitionExporter } from "./Interfaces";
|
||||
import { TableDefiniton } from "./Types";
|
||||
@@ -8,15 +8,14 @@ export interface FrontworkComponent<
|
||||
FeatureIfc extends RPCInterface = RPCInterface,
|
||||
Name extends keyof Ifc = keyof Ifc,
|
||||
FeatureName extends keyof FeatureIfc = keyof FeatureIfc,
|
||||
SubresT = {}
|
||||
> extends
|
||||
PrivilegedRPCExporter<Ifc, FeatureIfc, Name, FeatureName, SubresT>,
|
||||
PrivilegedRPCExporter<Ifc, FeatureIfc, Name, FeatureName>,
|
||||
TableDefinitionExporter
|
||||
{
|
||||
name: Name;
|
||||
|
||||
exportRPCFeatures(): RPCExporter<FeatureIfc, FeatureName, SubresT>[]
|
||||
exportRPCs(): RPCInterfaceArray<Ifc>[Name]
|
||||
exportRPCFeatures(): RPCExporter<FeatureIfc, FeatureName>[]
|
||||
exportRPCs(): RPCDefinitions<Ifc>[Name]
|
||||
getTableDefinitions(): TableDefiniton[]
|
||||
|
||||
initialize?(): Promise<any>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { TableDefiniton } from "./Types"
|
||||
|
||||
|
||||
export abstract class Plugin<ConfType = {}>
|
||||
implements ConfigExporter<ConfType>, RPCExporter<any,any,any>, TableDefinitionExporter{
|
||||
implements ConfigExporter<ConfType>, RPCExporter, TableDefinitionExporter{
|
||||
|
||||
constructor (protected admin: FrontworkAdmin, public name:string){
|
||||
if(!this.getConfig()){
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { RPCExporter, RPCInterface, RPC, RPCInterfaceArray } from "rpclibrary";
|
||||
import { RPCExporter, RPCInterface } from "rpclibrary";
|
||||
|
||||
export interface PrivilegedRPCExporter <
|
||||
Ifc extends RPCInterface = RPCInterface,
|
||||
FeatureIfc extends RPCInterface = RPCInterface,
|
||||
Name extends keyof Ifc = keyof Ifc,
|
||||
FeatureName extends keyof FeatureIfc = keyof FeatureIfc,
|
||||
SubresT = {}
|
||||
>extends RPCExporter<Ifc, Name>{
|
||||
exportRPCFeatures() : RPCExporter<FeatureIfc, FeatureName, SubresT>[]
|
||||
exportRPCFeatures() : RPCExporter<FeatureIfc, FeatureName>[]
|
||||
}
|
||||
@@ -165,6 +165,8 @@ export type Signup = {
|
||||
characterid: number
|
||||
benched: boolean
|
||||
late: boolean
|
||||
timestamp: string
|
||||
memo?: string
|
||||
}
|
||||
|
||||
export type Character = {
|
||||
|
||||
@@ -58,6 +58,9 @@
|
||||
"configurations": {
|
||||
"production": {
|
||||
"aot": true,
|
||||
"optimization": true,
|
||||
"extractCss": true,
|
||||
"sourceMap": true,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
|
||||
Generated
+11
-3
@@ -15742,13 +15742,21 @@
|
||||
"integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ=="
|
||||
},
|
||||
"rpclibrary": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.9.2.tgz",
|
||||
"integrity": "sha512-MOtVm0IBRLryXag1IwkYNPVFegbvW10+MbCjhr3GptO3MA7nHZ545ammgoCWnREtGOgFeN4Jib/EBDOJ9Ep41Q==",
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.10.2.tgz",
|
||||
"integrity": "sha512-uf4FtylK+tyVo1O8YVihxYxaI4KHnKBzq05SsLYe8ZPXdO8Hqrv7Je5cwv3bfx0FBCO1vVrSc8DT1P6ypGY6uQ==",
|
||||
"requires": {
|
||||
"bsock": "^0.1.9",
|
||||
"crypto-js": "^4.0.0",
|
||||
"http": "0.0.0",
|
||||
"uuid": "^3.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"crypto-js": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
|
||||
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"run-async": {
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
"prepush": "npm run lint:ci",
|
||||
"release:changelog": "npm run conventional-changelog -- -p angular -i CHANGELOG.md -s",
|
||||
"add": "ng add @nguniversal/express-engine",
|
||||
"tsc": "tsc --project src/tsconfig.server.json && webpack --config extra-webpack.config.js"
|
||||
"tsc": "tsc --project src/tsconfig.server.json && webpack --config extra-webpack.config.js",
|
||||
"knex": "knex"
|
||||
},
|
||||
"dependencies": {
|
||||
"@agm/core": "^1.0.0-beta.5",
|
||||
@@ -75,7 +76,7 @@
|
||||
"normalize.css": "6.0.0",
|
||||
"pace-js": "1.0.2",
|
||||
"roboto-fontface": "0.8.0",
|
||||
"rpclibrary": "^1.9.2",
|
||||
"rpclibrary": "^1.10.2",
|
||||
"rxjs": "6.5.2",
|
||||
"rxjs-compat": "6.3.0",
|
||||
"socicon": "3.0.5",
|
||||
|
||||
@@ -13,7 +13,7 @@ global['document'] = win.document;
|
||||
global['alert'] = console.log
|
||||
global['XMLHttpRequest'] = require('xmlhttprequest').XMLHttpRequest;
|
||||
|
||||
export async function attachExpress(app, staticDir = "./dist") {
|
||||
export async function attachExpress(app, staticDir = "./dist", loggerService = console) {
|
||||
const STATIC_FOLDER = resolve(process.cwd(), staticDir);
|
||||
|
||||
enableProdMode();
|
||||
@@ -21,7 +21,7 @@ export async function attachExpress(app, staticDir = "./dist") {
|
||||
const bundle = require(staticDir + '/server/main');
|
||||
|
||||
const ServerApiService = bundle.ServerApiService
|
||||
const serviceObj = new ServerApiService()
|
||||
const serviceObj = new ServerApiService(loggerService)
|
||||
await serviceObj.initialize()
|
||||
|
||||
app.set('view engine', 'html');
|
||||
@@ -31,10 +31,15 @@ export async function attachExpress(app, staticDir = "./dist") {
|
||||
bootstrap: bundle.AppServerModuleNgFactory,
|
||||
providers: [
|
||||
provideModuleMap(bundle.LAZY_MODULE_MAP),
|
||||
{
|
||||
provide: bundle.LoggerService,
|
||||
deps: [],
|
||||
useValue: loggerService
|
||||
},
|
||||
{
|
||||
provide: bundle.IApiService,
|
||||
deps: [],
|
||||
useValue: serviceObj,
|
||||
deps: []
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
</nb-action>
|
||||
|
||||
<nb-action class="user-action">
|
||||
<nb-user [nbContextMenu]="userMenu"
|
||||
<nb-user style="text-transform: capitalize;"
|
||||
[nbContextMenu]="userMenu"
|
||||
[onlyPicture]="false"
|
||||
[name]="user?.username">
|
||||
</nb-user>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { LayoutService } from '../../../@core/utils';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { User } from '../../../../../../backend/Types/Types';
|
||||
import { Router } from '@angular/router';
|
||||
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
|
||||
import { ChatComponent } from './chat.component';
|
||||
import { ShoutMessage } from '../../../../../../backend/Components/Shoutbox/Interface';
|
||||
import { IApiService } from '../../../frontcraft/services/ApiService';
|
||||
@@ -41,7 +41,7 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
];
|
||||
|
||||
currentTheme = 'default';
|
||||
userMenu : NbMenuItem[] = [ { title: 'Log out', link: '/auth/logout' } ];
|
||||
userMenu: NbMenuItem[] = [];
|
||||
|
||||
sendMessage: any = console.log
|
||||
chatwindow: ChatComponent
|
||||
@@ -50,22 +50,46 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
lastmessage = "asdasd"
|
||||
modifyPermissions
|
||||
|
||||
constructor(private sidebarService: NbSidebarService,
|
||||
constructor(
|
||||
private sidebarService: NbSidebarService,
|
||||
private router: Router,
|
||||
private themeService: NbThemeService,
|
||||
private layoutService: LayoutService,
|
||||
private api: IApiService,
|
||||
private dialogService : NbDialogService
|
||||
private dialogService: NbDialogService,
|
||||
private route: ActivatedRoute
|
||||
) { }
|
||||
|
||||
private setUserMenu = (redirect = this.router.url) => {
|
||||
if (this.user.username === 'Guest' && this.user.rank === 'Guest'){
|
||||
this.userMenu = [
|
||||
{ title: 'Login', link: '/auth/login', queryParams: { redirect: redirect } },
|
||||
{ title: 'Register', link: '/auth/register', queryParams: { redirect: redirect } },
|
||||
]
|
||||
}else{
|
||||
this.userMenu = [
|
||||
{ title: 'Profile', link: '/frontcraft/user/' + this.user.username },
|
||||
{ title: 'Log out', link: '/auth/logout', queryParams: { redirect: redirect } },
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.themeService.changeTheme("dark");
|
||||
|
||||
this.currentTheme = this.themeService.currentTheme;
|
||||
this.modifyPermissions = this.api.get('modifyPermissions')
|
||||
this.user = this.api.getCurrentUser()
|
||||
if(this.user)
|
||||
this.userMenu.unshift({ title: 'Profile', link: '/frontcraft/user/'+this.user.username });
|
||||
|
||||
this.setUserMenu()
|
||||
|
||||
this.router.events.subscribe((val) => {
|
||||
if(val instanceof NavigationEnd) {
|
||||
this.setUserMenu(val.urlAfterRedirects)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
this.api.get('GuildManager').getGuildInfo().then(info => {
|
||||
this.title = info.name
|
||||
@@ -122,7 +146,6 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
||||
toggleSidebar(): boolean {
|
||||
this.sidebarService.toggle(true, 'menu-sidebar');
|
||||
this.layoutService.changeLayoutSize();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,4 @@ import { Component, OnInit } from '@angular/core';
|
||||
selector: 'ngx-app',
|
||||
template: '<router-outlet></router-outlet>',
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void { }
|
||||
}
|
||||
export class AppComponent { }
|
||||
|
||||
@@ -5,11 +5,15 @@
|
||||
*/
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { NgModule, APP_INITIALIZER, NgZone, Injector } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { ThemeModule } from './@theme/theme.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { CoreModule } from './@core/core.module';
|
||||
import { FrontcraftPagesModule } from './frontcraft/pages/pages.module';
|
||||
import { MyAuthModule } from './frontcraft/auth/auth.module';
|
||||
import { PermissionsModule } from './frontcraft/permissions/permissions.module';
|
||||
import {
|
||||
NbChatModule,
|
||||
NbDatepickerModule,
|
||||
@@ -19,10 +23,6 @@ import {
|
||||
NbToastrModule,
|
||||
NbWindowModule,
|
||||
} from '@nebular/theme';
|
||||
import { CoreModule } from './@core/core.module';
|
||||
import { FrontcraftPagesModule } from './frontcraft/pages/pages.module';
|
||||
import { MyAuthModule } from './frontcraft/auth/auth.module';
|
||||
import { PermissionsModule } from './frontcraft/permissions/permissions.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ServerModule } from '@angular/platform-server';
|
||||
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Router, NavigationStart } from '@angular/router'
|
||||
import { IApiService } from './services/ApiService'
|
||||
import { AnyFunction } from 'rpclibrary'
|
||||
import { LoggerService } from './services/logger.service'
|
||||
import { OnDestroy } from '@angular/core'
|
||||
|
||||
export abstract class UpdatingComponent implements OnDestroy {
|
||||
private _uuid: string
|
||||
private _routerCancel: Function
|
||||
|
||||
constructor(
|
||||
private _router: Router,
|
||||
private _api: IApiService,
|
||||
private _logger: LoggerService
|
||||
) { }
|
||||
|
||||
protected subscribe = (
|
||||
topic: string,
|
||||
callback: AnyFunction,
|
||||
) => {
|
||||
const sub = this._router.events.subscribe(event => {
|
||||
if (event instanceof NavigationStart) {
|
||||
this.ngOnDestroy()
|
||||
}
|
||||
})
|
||||
this._routerCancel = () => { sub.unsubscribe() }
|
||||
this._api.get('PubSub').subscribe(topic, callback).then(uuid => {
|
||||
this._logger.collapsed(`New subscription ${topic}`, "table", {
|
||||
topic: topic,
|
||||
uuid: uuid
|
||||
})
|
||||
this._uuid = uuid
|
||||
}).catch(e => {
|
||||
this._logger.warn(`Subscribe for ${topic} failed, ${String(e)}`)
|
||||
delete this._uuid
|
||||
})
|
||||
}
|
||||
|
||||
//Note angular may call this function several times
|
||||
ngOnDestroy() {
|
||||
if (this._uuid) {
|
||||
const id = this._uuid
|
||||
delete this._uuid
|
||||
this._api.get('PubSub').unsubscribe(id).then(() => {
|
||||
this._logger.log(`Unsubscribed from ${id}`)
|
||||
})
|
||||
}
|
||||
if (this._routerCancel) {
|
||||
try {
|
||||
this._routerCancel()
|
||||
} catch (e) {
|
||||
this._logger.warn(e)
|
||||
}
|
||||
delete this._routerCancel
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ClientApiService } from '../services/client-login-api';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'auth-layout',
|
||||
|
||||
@@ -48,5 +48,5 @@
|
||||
|
||||
|
||||
<section class="another-action" aria-label="Register">
|
||||
Don't have an account? <a class="text-link" routerLink="/auth/register">Register</a>
|
||||
Don't have an account? <a class="text-link" routerLink="/auth/register" [queryParams]="{redirect: '/frontcraft'}">Register</a>
|
||||
</section>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ClientApiService } from '../../services/client-login-api';
|
||||
import { Router } from '@angular/router';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { IApiService } from '../../services/ApiService';
|
||||
import { NbToastrService } from '@nebular/theme';
|
||||
|
||||
@@ -24,7 +23,8 @@ export class MyLoginComponent implements OnInit{
|
||||
constructor(
|
||||
private router : Router,
|
||||
private api : IApiService,
|
||||
private toastr: NbToastrService
|
||||
private toastr: NbToastrService,
|
||||
private route: ActivatedRoute
|
||||
){}
|
||||
|
||||
ngOnInit(){
|
||||
@@ -41,8 +41,9 @@ export class MyLoginComponent implements OnInit{
|
||||
this.toastr.danger("Login failed", "Error")
|
||||
return
|
||||
}else{
|
||||
window['r'] = this.router
|
||||
this.router.navigate(["/froncraft"])
|
||||
this.route.queryParamMap.subscribe(params => {
|
||||
this.router.navigate([params.get('redirect')])
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
You will be redirected shortly. If not click here <a href="/auth/login">click</a>
|
||||
You will be redirected shortly. If not click here <a routerLink="/auth/login" [queryParams]="{redirect: '/frontcraft'}">click</a>
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { IApiService } from '../../services/ApiService';
|
||||
import { Router } from '@angular/router';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'mylogout',
|
||||
@@ -10,12 +10,15 @@ export class LogoutComponent implements OnInit{
|
||||
|
||||
constructor(
|
||||
private api : IApiService,
|
||||
private router: Router
|
||||
private router: Router,
|
||||
private route: ActivatedRoute
|
||||
){}
|
||||
|
||||
ngOnInit(){
|
||||
this.api.logout().then(() => {
|
||||
this.router.navigate(['/auth/login'])
|
||||
this.route.queryParamMap.subscribe(params => {
|
||||
this.router.navigate([params.get('redirect')])
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -92,5 +92,5 @@
|
||||
|
||||
|
||||
<section class="another-action" aria-label="Register">
|
||||
Back to <a class="text-link" routerLink="auth/login">Login</a>
|
||||
Go to <a class="text-link" routerLink="auth/login" [queryParams]="{redirect: '/frontcraft'}">Login</a>
|
||||
</section>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ClientApiService as ClientApiService } from '../../services/client-login-api';
|
||||
import { Router } from '@angular/router';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { _Rank, _Class, Class, User, _Race } from '../../../../../../backend/Types/Types'
|
||||
import { specs } from '../../../../../../backend/Types/PlayerSpecs'
|
||||
import { race } from 'rxjs';
|
||||
import { hash, IApiService } from '../../services/ApiService';
|
||||
|
||||
|
||||
@@ -34,6 +32,7 @@ export class RegisterComponent implements OnInit{
|
||||
|
||||
constructor(
|
||||
private router : Router,
|
||||
private route : ActivatedRoute,
|
||||
private api : IApiService
|
||||
){}
|
||||
|
||||
@@ -84,6 +83,11 @@ export class RegisterComponent implements OnInit{
|
||||
userid: this.api.getAuth().user.id!,
|
||||
race: char.race
|
||||
})
|
||||
|
||||
this.route.queryParamMap.subscribe(params => {
|
||||
this.router.navigate([params.get('redirect')])
|
||||
})
|
||||
|
||||
}catch(e){
|
||||
alert("Error creating character"+e)
|
||||
return
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Component, OnInit } from '@angular/core';
|
||||
import { Item, Stats } from '../../../../../../backend/Types/Types';
|
||||
|
||||
import { NbToastrService } from '@nebular/theme';
|
||||
import { ClientApiService } from '../../services/client-login-api';
|
||||
import { IApiService } from '../../services/ApiService';
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ClientApiService as ClientApiService } from '../../services/client-login-api';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Spec, User, Character, Item } from '../../../../../../backend/Types/Types';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
import { _Tiers } from '../../../../../../backend/Types/Items';
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { Component, AfterContentInit, OnInit } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { NbMenuItem } from '@nebular/theme';
|
||||
import { ClientApiService } from '../services/client-login-api';
|
||||
import { Router } from '@angular/router';
|
||||
import { IApiService } from '../services/ApiService';
|
||||
|
||||
declare const Cookies
|
||||
|
||||
@Component({
|
||||
selector: 'page-layout',
|
||||
@@ -16,7 +14,7 @@ declare const Cookies
|
||||
</ngx-one-column-layout>
|
||||
`,
|
||||
})
|
||||
export class PagesLayoutComponent implements OnInit{
|
||||
export class PagesLayoutComponent{
|
||||
|
||||
menu:NbMenuItem[] = [{
|
||||
icon: 'image',
|
||||
@@ -36,18 +34,6 @@ export class PagesLayoutComponent implements OnInit{
|
||||
link: '/frontcraft/armory'
|
||||
}]
|
||||
|
||||
constructor(
|
||||
private api : IApiService,
|
||||
private router : Router
|
||||
){}
|
||||
constructor(){}
|
||||
|
||||
ngOnInit(): void {
|
||||
/*
|
||||
const u = this.api.getCurrentUser()
|
||||
|
||||
if(!u){
|
||||
this.router.navigate(['/auth/login'])
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
NbInputModule,
|
||||
NbMenuModule,
|
||||
NbCardModule,
|
||||
NbTreeGridModule,
|
||||
NbListModule,
|
||||
NbTabsetModule,
|
||||
NbIconModule,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ClientApiService as ClientApiService } from '../../services/client-login-api';
|
||||
import { RaidData } from '../../../../../../backend/Types/Types';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
import { IApiService } from '../../services/ApiService';
|
||||
@@ -34,7 +33,7 @@ export class FrontcraftArchiveComponent implements OnInit{
|
||||
tanks:[],
|
||||
healers: []
|
||||
}
|
||||
tokens = {}
|
||||
tokens: {[key in string]:any[]} = {}
|
||||
displayedtokens = {}
|
||||
search = ""
|
||||
|
||||
@@ -53,6 +52,10 @@ export class FrontcraftArchiveComponent implements OnInit{
|
||||
|
||||
const raidManager = this.api.get('RaidManager')
|
||||
const raiddata = await raidManager.getArchiveRaid(parseInt(param))
|
||||
|
||||
console.log(raiddata);
|
||||
|
||||
|
||||
this.raid = raiddata
|
||||
this.isTier = raiddata.tier != null
|
||||
this.tokens = raiddata.tokens
|
||||
@@ -69,8 +72,18 @@ export class FrontcraftArchiveComponent implements OnInit{
|
||||
this.changeSearch()
|
||||
}
|
||||
|
||||
changeSearch = () => {
|
||||
this.tokens = this.raid.tokens;
|
||||
this.displayedtokens = this.raid.tokens;
|
||||
changeSearch(){
|
||||
if(!this.search || this.search == ""){
|
||||
this.displayedtokens = this.tokens
|
||||
}else{
|
||||
this.displayedtokens = {}
|
||||
Object.entries(this.tokens).forEach((e) => {
|
||||
const filteredTokens = e[1].filter(item => {
|
||||
return item.itemname.toLocaleLowerCase().includes(this.search.toLocaleLowerCase())
|
||||
})
|
||||
if(filteredTokens.length > 0)
|
||||
this.displayedtokens[e[0]] = filteredTokens
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,21 @@
|
||||
Pick Character
|
||||
</nb-card-header>
|
||||
<nb-card-body>
|
||||
<div *ngFor="let character of characters">
|
||||
<textarea
|
||||
placeholder="Add a note (optional)"
|
||||
rows="7"
|
||||
cols="50"
|
||||
nbInput style="white-space: pre-line;"
|
||||
[(ngModel)]="memo">
|
||||
</textarea>
|
||||
<br />
|
||||
<br />
|
||||
<nb-card *ngFor="let character of characters">
|
||||
<nb-card-header [ngStyle]="{'color': character.color}">
|
||||
<img [src]="'../../../../assets/images/'+character.class.toLowerCase()+'.png'" />
|
||||
<span [ngStyle]="{'color': character.color}">
|
||||
{{character.charactername}}
|
||||
</span>
|
||||
<br >
|
||||
<br >
|
||||
<br >
|
||||
|
||||
</nb-card-header>
|
||||
<nb-card-body>
|
||||
<button
|
||||
(click)="signup(character, false)"
|
||||
nbButton
|
||||
@@ -31,6 +37,7 @@
|
||||
size="medium">
|
||||
<nb-icon icon="clock-outline"></nb-icon> Late
|
||||
</button>
|
||||
</div>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
@@ -1,7 +1,6 @@
|
||||
import { OnInit, Component } from '@angular/core';
|
||||
import { NbWindowRef, NbToastrService, NbDialogRef } from '@nebular/theme';
|
||||
import { NbToastrService, NbDialogRef } from '@nebular/theme';
|
||||
import { RaidData, Character } from '../../../../../../backend/Types/Types';
|
||||
import { ClientApiService } from '../../services/client-login-api';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
import { IApiService } from '../../services/ApiService';
|
||||
|
||||
@@ -13,6 +12,7 @@ export class FrontcraftCharacerpickerComponent implements OnInit{
|
||||
|
||||
raid : RaidData
|
||||
characters: Character[]
|
||||
memo: string
|
||||
|
||||
constructor(
|
||||
protected dialogRef: NbDialogRef<FrontcraftCharacerpickerComponent>,
|
||||
@@ -25,7 +25,7 @@ export class FrontcraftCharacerpickerComponent implements OnInit{
|
||||
const signup = this.api.get('signup')
|
||||
if(!signup) return
|
||||
|
||||
await signup.sign(auth.token.value, character, this.raid, late)
|
||||
await signup.sign(auth.token.value, character, this.raid, late, this.memo)
|
||||
this.toast.show('Signup', 'Success', { status: 'success' })
|
||||
this.dialogRef.close()
|
||||
}
|
||||
|
||||
@@ -5,34 +5,47 @@
|
||||
<nb-tabset>
|
||||
<nb-tab tabTitle="Info">
|
||||
<h1>
|
||||
<img [src]="'../../../../assets/images/'+(raid.tier || 'null').toLowerCase()+'.png'"
|
||||
<img [src]="'/assets/images/'+(raid.tier || 'null').toLowerCase()+'.png'"
|
||||
style="height: 100px" />
|
||||
{{raid.title}}
|
||||
</h1>
|
||||
<p>
|
||||
{{raid.signupcount}} / {{raid.size}} signups
|
||||
</p>
|
||||
<p>
|
||||
<p style="white-space: pre-line;">
|
||||
{{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}}
|
||||
<div *ngIf="isSignedup" style="width: 100%;">
|
||||
<p style="white-space: pre-line;">
|
||||
You are signed as: <span
|
||||
style="text-transform: capitalize; word-break: keep-all;">{{mySignup.charactername}}</span>
|
||||
({{mySignup.race}} {{mySignup.specname}} {{mySignup.class}})
|
||||
<br />
|
||||
Status: {{mySignup.status}}<br /><br />
|
||||
<textarea [status]="mySignup.status === 'Attending'?'success':'warning'"
|
||||
placeholder="Add a note (optional)" rows="10" cols="50" nbInput
|
||||
style="white-space: pre-line;" [(ngModel)]="mySignup.memo">
|
||||
</textarea>
|
||||
</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
|
||||
<button *ngIf="mySignup.status === 'Late'" (click)="setLate(false)" nbButton outline
|
||||
status="success" size="medium">
|
||||
<nb-icon icon="checkmark-outline"></nb-icon> On Time
|
||||
</button>
|
||||
<button *ngIf="mySignup.status === 'Attending'" (click)="setLate(false)" nbButton
|
||||
outline status="success" size="medium">
|
||||
<nb-icon icon="checkmark-outline"></nb-icon> Update
|
||||
</button>
|
||||
<button *ngIf="mySignup.status === 'Late'" (click)="setLate(true)" nbButton outline
|
||||
status="warning" size="medium">
|
||||
<nb-icon icon="clock-outline"></nb-icon> Update
|
||||
</button>
|
||||
<button *ngIf="mySignup.status === 'Attending'" (click)="setLate(true)" nbButton outline
|
||||
status="warning" size="medium">
|
||||
<nb-icon icon="clock-outline"></nb-icon> Late
|
||||
</button>
|
||||
|
||||
<button (click)="unsign()" nbButton outline status="danger" size="medium">
|
||||
<nb-icon icon="close"></nb-icon>unsign
|
||||
</button>
|
||||
@@ -46,7 +59,6 @@
|
||||
</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>
|
||||
@@ -63,11 +75,28 @@
|
||||
<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'" />
|
||||
[src]="'/assets/images/'+participant.race.toLowerCase()+'_xs.gif'" />
|
||||
<img style="width:20px; height:20px"
|
||||
[src]="'../../../../assets/images/'+participant.class.toLowerCase()+'.png'" />
|
||||
[src]="'/assets/images/'+participant.class.toLowerCase()+'.png'" />
|
||||
{{ participant.charactername }}
|
||||
</a>
|
||||
<ng-template #template>
|
||||
<div style="padding: 10px">
|
||||
<p
|
||||
style="white-space: pre-line; max-width: 50vw; word-wrap: break-word;">
|
||||
{{participant.memo}}
|
||||
</p>
|
||||
{{participant.timestamp | date : 'HH:mm EEE MMM d'}}
|
||||
</div>
|
||||
</ng-template>
|
||||
<nb-icon *ngIf="participant.memo == null || participant.memo == ''"
|
||||
[nbPopover]="template" nbPopoverTrigger="hover"
|
||||
style="width: 0.75em; height: 0.75em;" icon="clock-outline"></nb-icon>
|
||||
|
||||
<nb-icon *ngIf="participant.memo != null && participant.memo != ''"
|
||||
[nbPopover]="template" nbPopoverTrigger="hover"
|
||||
style="width: 0.75em; height: 0.75em;" icon="message-circle-outline" status="info">
|
||||
</nb-icon>
|
||||
<span *ngIf="participant.rank=='Trial'" style="font-size: 9px;">
|
||||
Trial
|
||||
</span>
|
||||
@@ -90,11 +119,27 @@
|
||||
<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'" />
|
||||
[src]="'/assets/images/'+participant.race.toLowerCase()+'_xs.gif'" />
|
||||
<img style="width:20px; height:20px"
|
||||
[src]="'../../../../assets/images/'+participant.class.toLowerCase()+'.png'" />
|
||||
[src]="'/assets/images/'+participant.class.toLowerCase()+'.png'" />
|
||||
{{ participant.charactername }}
|
||||
</a>
|
||||
<ng-template #template>
|
||||
<div style="padding: 10px">
|
||||
<p style="white-space: pre-line;">
|
||||
{{participant.memo}}
|
||||
</p>
|
||||
{{participant.timestamp | date : 'HH:mm EEE MMM d'}}
|
||||
</div>
|
||||
</ng-template>
|
||||
<nb-icon *ngIf="participant.memo == null || participant.memo == ''"
|
||||
[nbPopover]="template" nbPopoverTrigger="hover"
|
||||
style="width: 0.75em; height: 0.75em;" icon="clock-outline"></nb-icon>
|
||||
|
||||
<nb-icon *ngIf="participant.memo != null && participant.memo != ''"
|
||||
[nbPopover]="template" nbPopoverTrigger="hover"
|
||||
style="width: 0.75em; height: 0.75em;" icon="message-circle-outline" status="info">
|
||||
</nb-icon>
|
||||
<span *ngIf="participant.rank=='Trial'" style="font-size: 9px;">
|
||||
Trial
|
||||
</span>
|
||||
@@ -119,11 +164,27 @@
|
||||
style="text-transform: capitalize;"
|
||||
[routerLink]="'/frontcraft/character/'+participant.charactername">
|
||||
<img style="width:20px; height:20px"
|
||||
[src]="'../../../../assets/images/'+participant.race.toLowerCase()+'_xs.gif'" />
|
||||
[src]="'/assets/images/'+participant.race.toLowerCase()+'_xs.gif'" />
|
||||
<img style="width:20px; height:20px"
|
||||
[src]="'../../../../assets/images/'+participant.class.toLowerCase()+'.png'" />
|
||||
[src]="'/assets/images/'+participant.class.toLowerCase()+'.png'" />
|
||||
{{ participant.charactername }}
|
||||
</a>
|
||||
<ng-template #template>
|
||||
<div style="padding: 10px">
|
||||
<p style="white-space: pre-line;">
|
||||
{{participant.memo}}
|
||||
</p>
|
||||
{{participant.timestamp | date : 'HH:mm EEE MMM d'}}
|
||||
</div>
|
||||
</ng-template>
|
||||
<nb-icon *ngIf="participant.memo == null || participant.memo == ''"
|
||||
[nbPopover]="template" nbPopoverTrigger="hover"
|
||||
style="width: 0.75em; height: 0.75em;" icon="clock-outline"></nb-icon>
|
||||
|
||||
<nb-icon *ngIf="participant.memo != null && participant.memo != ''"
|
||||
[nbPopover]="template" nbPopoverTrigger="hover"
|
||||
style="width: 0.75em; height: 0.75em;" icon="message-circle-outline" status="info">
|
||||
</nb-icon>
|
||||
<span *ngIf="participant.rank=='Trial'" style="font-size: 9px;">
|
||||
Trial
|
||||
</span>
|
||||
@@ -147,7 +208,8 @@
|
||||
<nb-card-body>
|
||||
<nb-tabset>
|
||||
<nb-tab tabTitle="Reserves" [active]="reservesShown">
|
||||
<input type="text" nbInput [(ngModel)]="search" (change)="changeSearch()" placeholder="Search" fullWidth="true">
|
||||
<input type="text" nbInput [(ngModel)]="search" (change)="changeSearch()" placeholder="Search"
|
||||
fullWidth="true">
|
||||
|
||||
<nb-list class="">
|
||||
<nb-list-item *ngFor="let item of displayedtokens | keyvalue">
|
||||
@@ -161,13 +223,11 @@
|
||||
<tr>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div
|
||||
*ngFor="let token of item.value"
|
||||
class="col-12 col-md-6 col-xl-4">
|
||||
<div *ngFor="let token of item.value" class="col-12 col-md-6 col-xl-4">
|
||||
<span
|
||||
[ngStyle]="{'text-decoration': token.rank=='Trial'? 'line-through' : 'none currentcolor solid' }">
|
||||
<span style="text-transform: capitalize;">
|
||||
[ {{token.level}} ]
|
||||
<span style="text-transform: capitalize; white-space: nowrap;">
|
||||
[ {{token.level}} ]
|
||||
<a [routerLink]="'/frontcraft/character/'+token.charactername"
|
||||
[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}}
|
||||
@@ -179,8 +239,9 @@
|
||||
Becomes valid when promoted to Raider
|
||||
</div>
|
||||
</ng-template>
|
||||
<span *ngIf="token.rank=='Trial'" style="font-size: 9px;" [nbPopover]="tooltip"
|
||||
nbPopoverTrigger="hover" nbPopoverPlacement="top">
|
||||
<span *ngIf="token.rank=='Trial'" style="font-size: 9px;"
|
||||
[nbPopover]="tooltip" nbPopoverTrigger="hover"
|
||||
nbPopoverPlacement="top">
|
||||
Trial
|
||||
</span><br />
|
||||
</div>
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ActivatedRoute, Router, NavigationStart } from '@angular/router';
|
||||
import { ClientApiService as ClientApiService } from '../../services/client-login-api';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { RaidData, Raid, Signup, Character, Spec, Item, SRToken } from '../../../../../../backend/Types/Types';
|
||||
import { NbWindowService, NbToastrService, NbDialogService } from '@nebular/theme';
|
||||
import { NbToastrService, NbDialogService } from '@nebular/theme';
|
||||
import { FrontcraftCharacerpickerComponent } from './characterpicker.component';
|
||||
import { getClassColor, SpecT } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
import { FrontcraftBuyTokenComponent } from '../shop/buytoken.component';
|
||||
import { allItems } from '../../../../../../backend/Types/Items';
|
||||
import { IApiService } from '../../services/ApiService';
|
||||
import { UpdatingComponent } from '../../UpdatingComponent';
|
||||
import { LoggerService } from '../../services/logger.service';
|
||||
|
||||
@Component({
|
||||
selector: 'raid',
|
||||
templateUrl: './raid.component.html',
|
||||
})
|
||||
export class FrontcraftRaidComponent implements OnInit, OnDestroy{
|
||||
export class FrontcraftRaidComponent
|
||||
extends UpdatingComponent
|
||||
implements OnInit{
|
||||
|
||||
canSignup = false
|
||||
isSignedup = false
|
||||
@@ -43,41 +46,28 @@ export class FrontcraftRaidComponent implements OnInit, OnDestroy{
|
||||
tokens: {[itemname in string]: (Character & SRToken & Item)[]} = {}
|
||||
displayedtokens = {}
|
||||
search = ""
|
||||
uuid
|
||||
|
||||
constructor(
|
||||
private api: IApiService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private dialogService : NbDialogService,
|
||||
private toast: NbToastrService
|
||||
private toast: NbToastrService,
|
||||
logger: LoggerService
|
||||
){
|
||||
router.events.subscribe(event => {
|
||||
if (event instanceof NavigationStart) {
|
||||
this.ngOnDestroy()
|
||||
}
|
||||
})
|
||||
super(router, api, logger)
|
||||
}
|
||||
|
||||
ngOnDestroy = () => {
|
||||
if(this.uuid)
|
||||
this.api.get('PubSub').unsubscribe(this.uuid)
|
||||
}
|
||||
|
||||
async ngOnInit(){
|
||||
|
||||
ngOnInit(){
|
||||
this.manageRaid = this.api.get('manageRaid')
|
||||
|
||||
const signupFeature = this.api.get('signup')
|
||||
|
||||
if(signupFeature){
|
||||
this.canSignup = true
|
||||
}
|
||||
await this.refresh()
|
||||
|
||||
const res = await this.api.get('PubSub').subscribe(""+this.raid.id!, (data: RaidData) => {
|
||||
this.display(data)
|
||||
this.refresh().then(() => {
|
||||
this.subscribe(String(this.raid.id), (data: RaidData) => this.display(data))
|
||||
})
|
||||
this.uuid = res.uuid
|
||||
}
|
||||
|
||||
itemSelect = async(item) => {
|
||||
@@ -143,7 +133,7 @@ export class FrontcraftRaidComponent implements OnInit, OnDestroy{
|
||||
await signup.sign(auth.token.value, {
|
||||
...this.mySignup,
|
||||
id: this.mySignup.characterid,
|
||||
}, this.raid, value)
|
||||
}, this.raid, value, this.mySignup.memo)
|
||||
this.toast.show('Signup', 'Success', { status: 'success' })
|
||||
}
|
||||
|
||||
@@ -163,9 +153,7 @@ export class FrontcraftRaidComponent implements OnInit, OnDestroy{
|
||||
const raiddata = await raidManager.getRaidData(<any>{
|
||||
id: param
|
||||
})
|
||||
|
||||
this.display(raiddata)
|
||||
|
||||
}
|
||||
|
||||
display = async (raiddata:RaidData) => {
|
||||
@@ -180,14 +168,16 @@ export class FrontcraftRaidComponent implements OnInit, OnDestroy{
|
||||
|
||||
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.isSignedup = true
|
||||
this.mySignup['status'] = matchingSignup['benched']?'Bench':matchingSignup['late']?'Late':'Attending'
|
||||
}else{
|
||||
this.isSignedup = false
|
||||
this.mySignup = null
|
||||
}
|
||||
|
||||
this.changeSearch()
|
||||
}
|
||||
|
||||
@@ -203,8 +193,6 @@ export class FrontcraftRaidComponent implements OnInit, OnDestroy{
|
||||
if(filteredTokens.length > 0)
|
||||
this.displayedtokens[e[0]] = filteredTokens
|
||||
})
|
||||
console.log(this.displayedtokens);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ClientApiService } from '../../services/client-login-api';
|
||||
import { Raid, RaidData } from '../../../../../../backend/Types/Types';
|
||||
import { NbWindowRef, NbDialogRef } from '@nebular/theme';
|
||||
import { NbDialogRef } from '@nebular/theme';
|
||||
import { Tiers, _Tiers } from '../../../../../../backend/Types/Items';
|
||||
import { IApiService } from '../../services/ApiService';
|
||||
|
||||
@@ -31,7 +30,7 @@ export class FrontcraftCreateRaidsComponent implements OnInit {
|
||||
private api: IApiService
|
||||
) {}
|
||||
|
||||
loadNext(cardData) {
|
||||
loadNext() {
|
||||
}
|
||||
|
||||
onTierSelect(){
|
||||
|
||||
@@ -1,64 +1,70 @@
|
||||
<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-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"
|
||||
class="raidlist"
|
||||
style="cursor: pointer;">
|
||||
<nb-list nbInfiniteList listenWindowScroll [threshold]="500">
|
||||
<nb-list-item *ngFor="let raid of raids" class="raidlist">
|
||||
<a [routerLink]="'/frontcraft/raid/'+raid.id">
|
||||
<div class="row">
|
||||
<img [src]="'../../../../assets/images/'+(raid.tier || 'null').toLowerCase()+'.png'"
|
||||
style="object-fit: contain"
|
||||
class="col-1 col-s-3" />
|
||||
|
||||
<div class="col-11 col-s-9" >
|
||||
<div class="row">
|
||||
<div class="col-12" style="padding-top: 5px">
|
||||
<table>
|
||||
<tr>
|
||||
<td rowspan="2" style="padding-right: 20px;">
|
||||
<img [src]="'/assets/images/'+(raid.tier || 'null').toLowerCase()+'.png'"
|
||||
style="max-width: 50px; object-fit: contain" />
|
||||
</td>
|
||||
<h4>
|
||||
{{raid.title}}
|
||||
</h4>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-right: 25px; white-space: nowrap; color: lightslategray;">
|
||||
<nb-icon icon="checkmark-circle"></nb-icon> {{raid.signupcount}} / {{raid.size}}<br>
|
||||
</td>
|
||||
<td style="padding-right: 25px; white-space: nowrap; color: lightslategray;">
|
||||
<nb-icon icon="clock-outline"></nb-icon> {{raid.start | date : 'HH:mm'}}
|
||||
</td>
|
||||
<td style="padding-right: 25px; white-space: nowrap; color: lightslategray;">
|
||||
<nb-icon icon="calendar-outline"></nb-icon> {{raid.start | date : 'EEE MMM d'}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</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>
|
||||
</a>
|
||||
</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 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>
|
||||
<a [routerLink]="'/frontcraft/archive/'+raid.id">
|
||||
<div class="row">
|
||||
<table>
|
||||
<tr>
|
||||
<td rowspan="2" style="padding-right: 20px;">
|
||||
<img [src]="'/assets/images/'+(raid.tier || 'null').toLowerCase()+'.png'"
|
||||
style="max-width: 50px;;object-fit: contain; filter: grayscale(75%)" />
|
||||
</td>
|
||||
<h4>
|
||||
{{raid.title}}
|
||||
</h4>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-right: 25px; white-space: nowrap; color: lightslategray;">
|
||||
<nb-icon icon="checkmark-circle"></nb-icon> {{raid.signupcount}} / {{raid.size}}<br>
|
||||
</td>
|
||||
<td style="padding-right: 25px; white-space: nowrap; color: lightslategray;">
|
||||
<nb-icon icon="clock-outline"></nb-icon> {{raid.start | date : 'HH:mm'}}
|
||||
</td>
|
||||
<td style="padding-right: 25px; white-space: nowrap; color: lightslategray;">
|
||||
<nb-icon icon="calendar-outline"></nb-icon> {{raid.start | date : 'EEE MMM d'}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</a>
|
||||
</nb-list-item>
|
||||
</nb-list>
|
||||
</nb-card>
|
||||
|
||||
@@ -1,59 +1,50 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ClientApiService } from '../../services/client-login-api';
|
||||
import { NbWindowService, NbDialogService } from '@nebular/theme';
|
||||
import { NbDialogService } from '@nebular/theme';
|
||||
import { FrontcraftCreateRaidsComponent } from './createraid.compontent';
|
||||
import { Router, NavigationStart } from '@angular/router';
|
||||
import { IApiService } from '../../services/ApiService';
|
||||
import { UpdatingComponent } from '../../UpdatingComponent';
|
||||
import { LoggerService } from '../../services/logger.service';
|
||||
|
||||
@Component({
|
||||
selector: 'raids',
|
||||
templateUrl: 'raids.component.html',
|
||||
styleUrls: ['raids.component.scss'],
|
||||
})
|
||||
export class FrontcraftRaidsComponent implements OnInit, OnDestroy{
|
||||
export class FrontcraftRaidsComponent
|
||||
extends UpdatingComponent
|
||||
implements OnInit {
|
||||
|
||||
|
||||
manageRaid
|
||||
raids = []
|
||||
oldraids = []
|
||||
pageSize = 10;
|
||||
uuid
|
||||
|
||||
constructor(
|
||||
private api: IApiService,
|
||||
private router: Router,
|
||||
private dialogService: NbDialogService
|
||||
router: Router,
|
||||
private dialogService: NbDialogService,
|
||||
logger: LoggerService
|
||||
) {
|
||||
this.manageRaid = this.api.get('manageRaid')
|
||||
router.events.subscribe(event => {
|
||||
if (event instanceof NavigationStart) {
|
||||
this.ngOnDestroy()
|
||||
}
|
||||
})
|
||||
super(router, api, logger)
|
||||
}
|
||||
|
||||
ngOnDestroy = () => {
|
||||
if(this.uuid)
|
||||
this.api.get('PubSub').unsubscribe(this.uuid)
|
||||
ngOnDestroy(){
|
||||
super.ngOnDestroy()
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
const res = await this.api.get('PubSub').subscribe("raids", () => {
|
||||
this.refresh()
|
||||
})
|
||||
this.uuid = res.uuid
|
||||
this.subscribe("raids", () => this.refresh())
|
||||
|
||||
this.manageRaid = this.api.get('manageRaid')
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.api.get('RaidManager').getRaids().then(raids => {
|
||||
this.raids = raids
|
||||
})
|
||||
|
||||
async refresh() {
|
||||
this.raids = await this.api.get('RaidManager').getRaids()
|
||||
const raidManager = this.api.get('RaidManager')
|
||||
raidManager.getPastRaids(10).then(raiddata => {
|
||||
this.oldraids = raiddata
|
||||
})
|
||||
this.oldraids = await raidManager.getPastRaids(10)
|
||||
}
|
||||
|
||||
create() {
|
||||
@@ -64,6 +55,5 @@ export class FrontcraftRaidsComponent implements OnInit, OnDestroy{
|
||||
templates: this.oldraids
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { Component, OnInit, ContentChild, AfterContentInit, ViewChild, AfterViewInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { ClientApiService as ClientApiService } from '../../services/client-login-api';
|
||||
import { FrontcraftItemSelectComponent } from './itemselector.component';
|
||||
import { NbWindowService, NbWindowRef, NbToastrService, NbDialogService, NbDialogRef } from '@nebular/theme';
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { NbToastrService, NbDialogRef } from '@nebular/theme';
|
||||
import { Item, Character, SRToken, Signup } from '../../../../../../backend/Types/Types';
|
||||
import { getClassColor } from '../../../../../../backend/Types/PlayerSpecs';
|
||||
import { _Tiers, allItems, Tiers } from '../../../../../../backend/Types/Items';
|
||||
import { _Tiers, Tiers } from '../../../../../../backend/Types/Items';
|
||||
import { IApiService } from '../../services/ApiService';
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -24,8 +24,16 @@ export class FrontcraftItemSelectComponent implements OnInit{
|
||||
|
||||
async ngOnInit(){
|
||||
|
||||
Promise.all(this.items.map(itemname =>
|
||||
this.api.get('ItemManager').getItem(itemname)
|
||||
|
||||
|
||||
|
||||
Promise.all(this.items.map(async itemname => {
|
||||
try{
|
||||
return await this.api.get('ItemManager').getItem(itemname)
|
||||
}catch(e){
|
||||
console.log(itemname);
|
||||
}
|
||||
}
|
||||
)).then(items => {
|
||||
this.allItems = items
|
||||
this.displayedItems = this.allItems
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { ClientApiService as ClientApiService } from '../../services/client-login-api';
|
||||
import { NbDialogService } from '@nebular/theme';
|
||||
import { Item, Character, Signup } from '../../../../../../backend/Types/Types';
|
||||
import { _Tiers, allItems } from '../../../../../../backend/Types/Items';
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ accent="info">
|
||||
</form>
|
||||
<br />
|
||||
|
||||
<h3>Avaiable Reserves</h3>
|
||||
<h3>Available Reserves</h3>
|
||||
{{user.MC}} MC |
|
||||
{{user.BWL}} BWL |
|
||||
{{user.ZG}} ZG |
|
||||
|
||||
-2
@@ -1,6 +1,4 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ClientApiService as ClientApiService } from '../../services/client-login-api';
|
||||
import { Router } from '@angular/router';
|
||||
import { _Rank, _Class, _Race, RPCPermission } from '../../../../../../backend/Types/Types'
|
||||
import { NbToastrService } from '@nebular/theme';
|
||||
import { IApiService } from '../../services/ApiService';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ClientApiService } from '../services/client-login-api';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
import { Auth, FrontcraftIfc, FrontcraftFeatureIfc, User, SomeOf } from '../../../../../backend/Types/Types';
|
||||
import { saltedHash } from '../../../../../backend/Util/hash';
|
||||
import { RPCSocket } from 'rpclibrary';
|
||||
import { RPCSocket, ConnectedSocket } from 'rpclibrary';
|
||||
|
||||
export class IApiService{
|
||||
getUnprivilegedSocket: () => RPCSocket & FrontcraftIfc
|
||||
getUnprivilegedSocket: () => ConnectedSocket<FrontcraftIfc>
|
||||
getAuth: () => Auth | undefined
|
||||
checkLogin: () => Promise<boolean>
|
||||
initialize: () => Promise<any>
|
||||
getCurrentUser: () => User | undefined
|
||||
getCurrentUser: () => User
|
||||
login: (username: string, password: string) => Promise<RPCSocket & SomeOf<FrontcraftFeatureIfc>>
|
||||
connectShoutbox: (callback:Function) => Promise<Function>
|
||||
kick: () => Promise<void>
|
||||
logout: () => Promise<void>
|
||||
get: <K extends (keyof FrontcraftIfc | keyof FrontcraftFeatureIfc)>(feature : K) => K extends keyof FrontcraftIfc?FrontcraftIfc[K]:
|
||||
K extends keyof FrontcraftFeatureIfc?(FrontcraftFeatureIfc[K] | void):
|
||||
never
|
||||
get: <K extends (keyof FrontcraftIfc | keyof FrontcraftFeatureIfc)>(feature : K) => K extends keyof FrontcraftIfc
|
||||
? FrontcraftIfc[K]
|
||||
: K extends keyof FrontcraftFeatureIfc
|
||||
? (FrontcraftFeatureIfc[K] | void)
|
||||
: never
|
||||
}
|
||||
|
||||
export async function hash(value:string) : Promise<string>{
|
||||
return saltedHash(value, "")
|
||||
}
|
||||
|
||||
export const GuestUser: User = {
|
||||
username: 'Guest',
|
||||
pwhash: '',
|
||||
rank: 'Guest'
|
||||
}
|
||||
@@ -1,24 +1,28 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { RPCSocket } from 'rpclibrary/js/src/Frontend'
|
||||
import { ConnectedSocket } from "rpclibrary"
|
||||
import { Auth, User, _Class, FrontcraftFeatureIfc, SomeOf, FrontcraftIfc, } from '../../../../../backend/Types/Types'
|
||||
import { ShoutMessage } from '../../../../../backend/Components/Shoutbox/Interface';
|
||||
import { hash, IApiService } from './ApiService';
|
||||
import { hash, IApiService, GuestUser } from './ApiService';
|
||||
import { LoggerService } from './logger.service';
|
||||
|
||||
declare const Cookies
|
||||
|
||||
@Injectable()
|
||||
export class ClientApiService implements IApiService{
|
||||
private socket:RPCSocket & FrontcraftIfc;
|
||||
private socket:ConnectedSocket<FrontcraftIfc>
|
||||
private auth:Auth
|
||||
private privSocket: RPCSocket & SomeOf<FrontcraftFeatureIfc>
|
||||
private privSocket: RPCSocket<SomeOf<FrontcraftFeatureIfc>>
|
||||
|
||||
constructor(){
|
||||
constructor(
|
||||
private logger: LoggerService
|
||||
){
|
||||
window['s'] = this
|
||||
}
|
||||
|
||||
getUnprivilegedSocket = () : RPCSocket & FrontcraftIfc => this.socket
|
||||
getUnprivilegedSocket = () : ConnectedSocket<FrontcraftIfc> => this.socket
|
||||
|
||||
private getPrivilegedSocket = async (auth:Auth) : Promise<RPCSocket & SomeOf<FrontcraftFeatureIfc>> => {
|
||||
private getPrivilegedSocket = async (auth:Auth) : Promise<RPCSocket<SomeOf<FrontcraftFeatureIfc>>> => {
|
||||
if(this.privSocket) {
|
||||
return this.privSocket
|
||||
}
|
||||
@@ -38,17 +42,17 @@ export class ClientApiService implements IApiService{
|
||||
sock.hook('getUserData', () => auth)
|
||||
|
||||
sock.on('close', async () => {
|
||||
console.log("priv#close");
|
||||
this.logger.log("priv#close");
|
||||
|
||||
//handled via unprivileged socket
|
||||
})
|
||||
|
||||
sock.on('error', async (e) => {
|
||||
console.log("priv#error", e);
|
||||
this.logger.log("priv#error", e);
|
||||
|
||||
//handled via unprivileged socket
|
||||
})
|
||||
const authSock = await sock.connect<RPCSocket & SomeOf<FrontcraftFeatureIfc>>(auth.token.value)
|
||||
const authSock = await sock.connect(auth.token.value)
|
||||
|
||||
this.auth = auth
|
||||
this.privSocket = authSock
|
||||
@@ -74,8 +78,8 @@ export class ClientApiService implements IApiService{
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentUser = () : User | undefined => {
|
||||
return this.auth?this.auth.user:undefined
|
||||
getCurrentUser = () : User => {
|
||||
return this.auth?this.auth.user:GuestUser
|
||||
}
|
||||
|
||||
login = async (username: string, password: string) : Promise<RPCSocket & SomeOf<FrontcraftFeatureIfc>> => {
|
||||
@@ -102,8 +106,8 @@ export class ClientApiService implements IApiService{
|
||||
}
|
||||
|
||||
async connectShoutbox(callback:Function) : Promise<Function>{
|
||||
const res = await this.get('Shoutbox').subscribe(callback)
|
||||
return async (msg: ShoutMessage) => await this.get('Shoutbox').shout(res.uuid, msg)
|
||||
const uuid = await this.get('Shoutbox').subscribe(callback)
|
||||
return async (msg: ShoutMessage) => await this.get('Shoutbox').shout(uuid, msg)
|
||||
}
|
||||
|
||||
kick = async () => {
|
||||
@@ -113,6 +117,7 @@ export class ClientApiService implements IApiService{
|
||||
|
||||
logout = async () => {
|
||||
Cookies.remove('token')
|
||||
if(this.privSocket) this.privSocket.unhook('kick')
|
||||
if(this.auth){
|
||||
try{
|
||||
await this.socket.UserManager.logout(this.auth.user.username, this.auth.token.value)
|
||||
@@ -133,11 +138,11 @@ export class ClientApiService implements IApiService{
|
||||
}
|
||||
|
||||
try{
|
||||
let conn = new RPCSocket(20000, window.location.hostname)
|
||||
let conn = new RPCSocket<FrontcraftIfc>(20000, window.location.hostname)
|
||||
conn.on('close', async () => {
|
||||
})
|
||||
|
||||
this.socket = await conn.connect<FrontcraftIfc>()
|
||||
this.socket = await conn.connect()
|
||||
}catch(e){
|
||||
alert('Unable to connect. The server appears to be down.\nPress OK to refresh the page')
|
||||
location.reload()
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { environment } from '../../../environments/environment';
|
||||
|
||||
interface ILoggerService{
|
||||
log,
|
||||
warn,
|
||||
error,
|
||||
table,
|
||||
collapsed
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class LoggerService implements ILoggerService {
|
||||
|
||||
constructor(
|
||||
private logger = console
|
||||
) { }
|
||||
|
||||
log = (...args) => { this.LOG('log', args) }
|
||||
warn = (...args) => { this.LOG('warn', args) }
|
||||
error = (...args) => { this.LOG('error', args) }
|
||||
table = (...args) => { this.LOG('table', args) }
|
||||
collapsed = (groupname: string, type: keyof ILoggerService, ...args) => {
|
||||
if(type === "collapsed")
|
||||
return this.log(args)
|
||||
|
||||
console.groupCollapsed(groupname)
|
||||
this[type as any].apply(this.logger, args)
|
||||
console.groupEnd()
|
||||
}
|
||||
|
||||
private LOG(type, ...args) {
|
||||
if (!environment.production) {
|
||||
this.logger[type].apply(this.logger, ...args)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,23 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import {RPCSocket} from 'rpclibrary/js/src/Frontend'
|
||||
import { Auth, User, _Class, FrontcraftFeatureIfc, SomeOf, FrontcraftIfc, } from '../../../../../backend/Types/Types'
|
||||
import { hash, IApiService } from './ApiService';
|
||||
import { hash, IApiService, GuestUser } from './ApiService';
|
||||
import { LoggerService } from './logger.service';
|
||||
import { ConnectedSocket } from 'rpclibrary';
|
||||
|
||||
declare const Cookies
|
||||
|
||||
@Injectable()
|
||||
export class ServerApiService implements IApiService{
|
||||
private socket:RPCSocket & FrontcraftIfc;
|
||||
private socket:ConnectedSocket<FrontcraftIfc>
|
||||
private auth:Auth
|
||||
private privSocket: RPCSocket & SomeOf<FrontcraftFeatureIfc>
|
||||
|
||||
constructor(){}
|
||||
constructor(
|
||||
private logger: LoggerService
|
||||
){}
|
||||
|
||||
getUnprivilegedSocket = () : RPCSocket & FrontcraftIfc => this.socket
|
||||
getUnprivilegedSocket = () : ConnectedSocket<FrontcraftIfc> => this.socket
|
||||
|
||||
get = <K extends (keyof FrontcraftIfc | keyof FrontcraftFeatureIfc)>(feature : K) : K extends keyof FrontcraftIfc?FrontcraftIfc[K]:
|
||||
K extends keyof FrontcraftFeatureIfc?(FrontcraftFeatureIfc[K] | void):
|
||||
@@ -22,8 +26,8 @@ export class ServerApiService implements IApiService{
|
||||
return this.socket[feature]
|
||||
}
|
||||
|
||||
getCurrentUser = () : User | undefined => {
|
||||
return this.auth?this.auth.user:undefined
|
||||
getCurrentUser = () : User => {
|
||||
return GuestUser
|
||||
}
|
||||
|
||||
login = async (username: string, password: string) : Promise<RPCSocket & SomeOf<FrontcraftFeatureIfc>> => {
|
||||
@@ -42,13 +46,13 @@ export class ServerApiService implements IApiService{
|
||||
|
||||
//attach error handler now so failed logins dont trigger reloads
|
||||
this.socket.on('error', async (err) => {
|
||||
console.log(err);
|
||||
this.logger.log(err);
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
async connectShoutbox(callback:Function) : Promise<Function>{
|
||||
return console.log
|
||||
return this.logger.log
|
||||
}
|
||||
|
||||
kick = async () => {
|
||||
@@ -60,7 +64,7 @@ export class ServerApiService implements IApiService{
|
||||
try{
|
||||
await this.socket.UserManager.logout(this.auth.user.username, this.auth.token.value)
|
||||
}catch(e){
|
||||
console.warn(e);
|
||||
this.logger.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,13 +80,13 @@ export class ServerApiService implements IApiService{
|
||||
}
|
||||
|
||||
try{
|
||||
let conn = new RPCSocket(20000, window.location.hostname)
|
||||
let conn = new RPCSocket<FrontcraftIfc>(20000, window.location.hostname)
|
||||
conn.on('close', async () => {
|
||||
})
|
||||
|
||||
this.socket = await conn.connect<FrontcraftIfc>()
|
||||
this.socket = await conn.connect()
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
this.logger.log(e);
|
||||
throw new Error("Websocket cannot connect")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,4 @@ export { AppServerModule } from './app/app.server.module';
|
||||
import { IApiService } from './app/frontcraft/services/ApiService';
|
||||
export { IApiService }
|
||||
export { ServerApiService } from './app/frontcraft/services/server-login-api';
|
||||
|
||||
export { LoggerService } from './app/frontcraft/services/logger.service'
|
||||
@@ -10,18 +10,23 @@ import { FrontcraftAppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
import { IApiService } from "./app/frontcraft/services/ApiService"
|
||||
import { ClientApiService } from './app/frontcraft/services/client-login-api';
|
||||
import { LoggerService } from './app/frontcraft/services/logger.service';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
const serviceObj = new ClientApiService()
|
||||
const loggerService = new LoggerService()
|
||||
const serviceObj = new ClientApiService(loggerService)
|
||||
serviceObj.initialize().then(_ => {
|
||||
platformBrowserDynamic([
|
||||
{
|
||||
provide: IApiService,
|
||||
deps: [],
|
||||
useValue: serviceObj
|
||||
},{
|
||||
provide: LoggerService,
|
||||
deps: [],
|
||||
useValue: loggerService
|
||||
}
|
||||
]).bootstrapModule(FrontcraftAppModule)
|
||||
.catch(err => console.error(err));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"strict": false,
|
||||
"outDir": "./out-tsc/app",
|
||||
"paths": {
|
||||
"@angular/*": [
|
||||
|
||||
+7
-7
@@ -1,8 +1,8 @@
|
||||
import { Injector } from "../src/backend/Injector/Injector";
|
||||
import { FrontworkAdmin } from "../src/backend/Admin/Admin";
|
||||
import { T1, T2, Tiers } from "../src/backend/Types/Items";
|
||||
import { T2, Tiers } from "../src/backend/Types/Items";
|
||||
|
||||
import { RPCSocket } from "rpclibrary";
|
||||
import { RPCSocket, ConnectedSocket } from "rpclibrary";
|
||||
import { FrontcraftIfc, Auth, User, FrontcraftFeatureIfc, Raid, Character, Rank, Class, Race, Spec, Signup } from "../src/backend/Types/Types";
|
||||
import { SpecT } from "../src/backend/Types/PlayerSpecs";
|
||||
|
||||
@@ -120,8 +120,8 @@ describe('Frontcraft', () => {
|
||||
let auth: Auth,
|
||||
adminUser: User,
|
||||
server: FrontworkAdmin,
|
||||
client: RPCSocket & FrontcraftIfc,
|
||||
adminClient: RPCSocket & FrontcraftFeatureIfc,
|
||||
client: ConnectedSocket<FrontcraftIfc>,
|
||||
adminClient: ConnectedSocket<FrontcraftFeatureIfc>,
|
||||
raids: Raid[] = [],
|
||||
users: { [username in string]: { account: User, character: Character, auth: Auth, signup?: Signup, item?: string } } = {}
|
||||
|
||||
@@ -168,12 +168,12 @@ describe('Frontcraft', () => {
|
||||
}).then(adminUser => {
|
||||
|
||||
client.UserManager.login(adminUser.username, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb').then(auth => {
|
||||
const sock = new RPCSocket(
|
||||
const sock = new RPCSocket<FrontcraftFeatureIfc>(
|
||||
auth.port,
|
||||
"localhost"
|
||||
)
|
||||
|
||||
sock.connect<any>(auth.token.value).then(cli => {
|
||||
sock.connect(auth.token.value).then(cli => {
|
||||
adminClient = cli
|
||||
sock.hook('kick', () => {
|
||||
console.log("I got kicked");
|
||||
@@ -240,7 +240,7 @@ describe('Frontcraft', () => {
|
||||
|
||||
it('should sign up', (done) => {
|
||||
Promise.all(Object.values(users).map((user) =>
|
||||
adminClient.signup.sign(user.auth.token.value, user.character, raids[0], false).catch(done)
|
||||
adminClient.signup.sign(user.auth.token.value, user.character, raids[0], false, ""+Math.floor(Math.random()*10000)).catch(done)
|
||||
)).then(x => {
|
||||
adminClient.signup.getSignups(raids[0]).then(s => {
|
||||
if (s.length == testAccounts.length) {
|
||||
|
||||
Reference in New Issue
Block a user