finish MVP

This commit is contained in:
Katalina / stardust 2017-12-28 17:10:03 -06:00
parent 7806219464
commit eaa1167f16
22 changed files with 486 additions and 116 deletions

View file

@ -3,7 +3,7 @@ module.exports = (R, $) => {
try {
const { userId } = ctx.session
const srv = $.discord.getRelevantServers(userId)
const presentable = await $.P.oldPresentableServers(srv, userId)
const presentable = await $.P.presentableServers(srv, userId)
ctx.body = presentable
} catch (e) {
@ -23,12 +23,35 @@ module.exports = (R, $) => {
return
}
const gm = srv.members.get(userId)
const server = $.discord.presentableRoles(id, gm)
const gm = $.discord.gm(id, userId)
const server = await $.P.presentableServer(srv, gm)
ctx.body = server
})
R.patch('/api/server/:id', async (ctx) => {
const { userId } = ctx.session
const { id } = ctx.params
let gm = $.discord.gm(id, userId)
// check perms
if (!$.discord.getPermissions(gm).canManageRoles) {
ctx.status = 403
ctx.body = { err: 'cannot_manage_roles' }
return
}
const { message = null, categories = null } = ctx.request.body
// todo make less nasty
await $.server.update(id, {
...((message != null) ? { message } : {}),
...((categories != null) ? { categories } : {})
})
ctx.body = { ok: true }
})
R.patch('/api/servers/:server/roles', async ctx => {
const { userId } = ctx.session
const { server } = ctx.params
@ -36,12 +59,16 @@ module.exports = (R, $) => {
const { added, removed } = ctx.request.body
const allowedRoles = await $.server.getAllowedRoles(server)
const pred = r => $.discord.safeRole(server, r) && allowedRoles.indexOf(r) !== -1
if (added.length > 0) {
gm = await gm.addRoles(added.filter(r => $.discord.safeRole(server, r)))
gm = await gm.addRoles(added.filter(pred))
}
if (removed.length > 0) {
gm = await gm.removeRoles(removed.filter(r => $.discord.safeRole(server, r)))
gm = await gm.removeRoles(removed.filter(pred))
}
ctx.body = { ok: true }

View file

@ -8,6 +8,15 @@ const _io = require('socket.io')
const router = require('koa-better-router')().loadMethods()
const Roleypoly = require('./Roleypoly')
// monkey patch async-reduce because F U T U R E
Array.prototype.areduce = async function (predicate, acc = []) { // eslint-disable-line
for (let i of this) {
acc = await predicate(acc, i)
}
return acc
}
// Create the server and socket.io server
const server = http.createServer(app.callback())
const io = _io(server, { transports: ['websocket'], path: '/api/socket.io', wsEngine: 'uws' })

View file

@ -11,6 +11,7 @@ class DiscordService extends Service {
this.clientSecret = process.env.DISCORD_CLIENT_SECRET
this.oauthCallback = process.env.OAUTH_AUTH_CALLBACK
this.botCallback = `${ctx.config.appUrl}/api/oauth/bot/callback`
this.appUrl = process.env.APP_URL
this.client = new discord.Client()
@ -24,6 +25,8 @@ class DiscordService extends Service {
async startBot () {
await this.client.login(this.botToken)
this.client.on('message', this.handleMessage.bind(this))
for (let server of this.client.guilds.array()) {
await this.ctx.server.ensure(server)
}
@ -127,6 +130,20 @@ class DiscordService extends Service {
getBotJoinUrl () {
return `https://discordapp.com/oauth2/authorize?client_id=${this.clientId}&scope=bot&permissions=268435456&redirect_uri=${this.botCallback}`
}
mentionResponse (message) {
message.channel.send(`🔰 Assign your roles here! <${this.appUrl}/s/${message.guild.id}>`, { disableEveryone: true })
}
handleMessage (message) {
if (message.author.bot && message.channel.type !== 'text') { // drop bot messages and dms
return
}
if (message.mentions.users.has(this.client.user.id)) {
this.mentionResponse(message)
}
}
}
module.exports = DiscordService

View file

@ -14,32 +14,44 @@ class PresentationService extends Service {
let servers = []
for (let server of collection.array()) {
const sd = await this.ctx.server.get(server.id)
console.log(sd.categories)
const gm = server.members.get(userId)
servers.push({
id: server.id,
gm: {
nickname: gm.nickname,
color: gm.displayHexColor
},
server: {
id: server.id,
name: server.name,
ownerID: server.ownerID,
icon: server.icon
},
roles: (await this.rolesByServer(server, sd)).map(r => ({ ...r, selected: gm.roles.has(r.id) })),
message: sd.message,
categories: sd.categories,
perms: this.discord.getPermissions(gm)
})
servers.push(await this.presentableServer(server, gm))
}
return servers
}
async presentableServers (collection, userId) {
return collection.array().areduce(async (acc, server) => {
const gm = server.members.get(userId)
acc.push(await this.presentableServer(server, gm))
return acc
})
}
async presentableServer (server, gm) {
const sd = await this.ctx.server.get(server.id)
return {
id: server.id,
gm: {
nickname: gm.nickname,
color: gm.displayHexColor
},
server: {
id: server.id,
name: server.name,
ownerID: server.ownerID,
icon: server.icon
},
roles: (await this.rolesByServer(server, sd)).map(r => ({ ...r, selected: gm.roles.has(r.id) })),
message: sd.message,
categories: sd.categories,
perms: this.discord.getPermissions(gm)
}
}
async rolesByServer (server) {
return server.roles
.filter(r => r.id !== server.id) // get rid of @everyone

View file

@ -30,18 +30,36 @@ class ServerService extends Service {
return srv.save()
}
update (id, newData) {
const srv = this.get(id)
async update (id, newData) {
const srv = await this.get(id, false)
return srv.update(newData)
}
async get (id) {
return (await this.Server.findOne({
async get (id, plain = true) {
const s = await this.Server.findOne({
where: {
id
}
})).get({ plain: true })
})
if (!plain) {
return s
}
return s.get({ plain: true })
}
async getAllowedRoles (id) {
const server = await this.get(id)
return Object.values(server.categories).reduce((acc, c) => {
if (c.hidden !== true) {
return acc.concat(c.roles)
}
return acc
}, [])
}
}