This commit is contained in:
41666 2017-12-20 01:13:34 -06:00
parent 5510d5a1c4
commit 3d541ac480
11 changed files with 108 additions and 42 deletions

View file

@ -40,6 +40,7 @@ class Roleypoly {
// enableReadyCheck: true, // enableReadyCheck: true,
// enableOfflineQueue: true // enableOfflineQueue: true
// }) // })
this.ctx.server = new (require('./services/server'))(this.ctx)
this.ctx.discord = new (require('./services/discord'))(this.ctx) this.ctx.discord = new (require('./services/discord'))(this.ctx)
this.ctx.sessions = new (require('./services/sessions'))(this.ctx) this.ctx.sessions = new (require('./services/sessions'))(this.ctx)
this.ctx.P = new (require('./services/presentation'))(this.ctx) this.ctx.P = new (require('./services/presentation'))(this.ctx)

View file

@ -2,7 +2,7 @@ module.exports = (R, $) => {
R.get('/api/servers', async (ctx) => { R.get('/api/servers', async (ctx) => {
const { userId } = ctx.session const { userId } = ctx.session
const srv = $.discord.getRelevantServers(userId) const srv = $.discord.getRelevantServers(userId)
const presentable = $.P.oldPresentableServers(srv, userId) const presentable = await $.P.oldPresentableServers(srv, userId)
ctx.body = presentable ctx.body = presentable
}) })

View file

@ -20,6 +20,10 @@ class DiscordService extends Service {
async startBot () { async startBot () {
await this.client.login(this.botToken) await this.client.login(this.botToken)
for (let server of this.client.guilds.array()) {
await this.ctx.server.ensure(server)
}
} }
getRelevantServers (userId) { getRelevantServers (userId) {

View file

@ -10,11 +10,15 @@ class PresentationService extends Service {
this.cache = LRU({ max: 500, maxAge: 100 * 60 * 5 }) this.cache = LRU({ max: 500, maxAge: 100 * 60 * 5 })
} }
oldPresentableServers (collection, userId) { async oldPresentableServers (collection, userId) {
return collection.map((server) => { 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) const gm = server.members.get(userId)
return { servers.push({
id: server.id, id: server.id,
gm: { gm: {
nickname: gm.nickname, nickname: gm.nickname,
@ -26,24 +30,26 @@ class PresentationService extends Service {
ownerID: server.ownerID, ownerID: server.ownerID,
icon: server.icon icon: server.icon
}, },
roles: server.roles.filter(r => r.id !== server.id).map(r => ({ roles: (await this.rolesByServer(server, sd)).map(r => ({ ...r, selected: gm.roles.has(r.id) })),
id: r.id, message: sd.message,
color: r.color, categories: sd.categories,
name: r.name,
selected: gm.roles.has(r.id),
position: r.position
})),
message: 'moe moe kyuuuuuuuuun~',
perms: this.discord.getPermissions(gm) perms: this.discord.getPermissions(gm)
} })
}) }
return servers
} }
rolesByServer (serverId, userId) { async rolesByServer (server) {
// get from discord, merge with server categories return server.roles
.filter(r => r.id !== server.id) // get rid of @everyone
.map(r => ({
id: r.id,
color: r.color,
name: r.name,
position: r.position
}))
} }
} }
module.exports = PresentationService module.exports = PresentationService

View file

@ -30,12 +30,12 @@ class ServerService extends Service {
return srv.update(newData) return srv.update(newData)
} }
get (id) { async get (id) {
return this.Server.findOne({ return (await this.Server.findOne({
where: { where: {
id id
} }
}) })).get({ plain: true })
} }
} }

View file

@ -4,3 +4,18 @@
&.hidden &.hidden
opacity: 0 opacity: 0
&__categories
display: flex
align-items: flex-start
flex-wrap: wrap
flex-direction: row
&__category
// flex: 1 3 33%
box-sizing: border-box
background-color: var(--c-1)
padding: 15px
margin: 10px
width: 220px - 30px

View file

@ -1,4 +1,4 @@
import { Map, Set } from 'immutable' import { Map, Set, fromJS } from 'immutable'
import superagent from 'superagent' import superagent from 'superagent'
export const roleUpdate = (id, oldState) => (dispatch, getState) => { export const roleUpdate = (id, oldState) => (dispatch, getState) => {
@ -22,7 +22,6 @@ export const setup = id => async dispatch => {
// roles: data // roles: data
// } // }
// }) // })
dispatch(constructView(id)) dispatch(constructView(id))
} }
@ -30,16 +29,33 @@ export const constructView = id => (dispatch, getState) => {
const server = getState().servers.get(id) const server = getState().servers.get(id)
const roles = server.get('roles') const roles = server.get('roles')
const categories = roles.groupBy(x => x.get('category')) const categories = server.get('categories')
const allRoles = server.get('roles').map(r => r.get('id')).toSet()
const accountedRoles = categories.map(c => c.get('roles')).toSet().flatten()
const unaccountedRoles = allRoles.subtract(accountedRoles)
// console.log('roles', allRoles.toJS(), accountedRoles.toJS(), unaccountedRoles.toJS())
const vm = categories.set('Uncategorized', fromJS({
roles: unaccountedRoles,
hidden: false,
type: 'multi'
})).map(c => {
const roles = c.get('roles').map(r => server.get('roles').find(sr => sr.get('id') === r))
return c.set('roles_map', roles)
})
const selected = roles.reduce((acc, r) => acc.set(r.get('id'), r.get('selected')), Map()) const selected = roles.reduce((acc, r) => acc.set(r.get('id'), r.get('selected')), Map())
console.log(categories, selected) console.log(categories, selected)
dispatch({ dispatch({
type: Symbol.for('setup role picker'), type: Symbol.for('setup role picker'),
data: { data: {
viewMap: categories, viewMap: vm,
rolesSelected: selected, rolesSelected: selected,
originalRolesSelected: selected originalRolesSelected: selected,
hidden: false
} }
}) })
} }

View file

@ -20,31 +20,53 @@ class RolePicker extends Component {
dispatch(Actions.setup(server)) dispatch(Actions.setup(server))
} }
componentWillReceiveProps (nextProps) {
if (this.props.match.params.server !== nextProps.match.params.server) {
const { dispatch } = this.props
dispatch(Actions.setup(nextProps.match.params.server))
}
}
isSelected (id) { isSelected (id) {
return this.props.data.getIn([ 'rolesSelected', id ]) return this.props.data.getIn([ 'rolesSelected', id ])
} }
render () { render () {
console.log(this.constructor.name, this.props) const { data, server } = this.props
if (this.props.server === undefined) { const vm = data.get('viewMap')
if (server === undefined) {
return null return null
} }
return <div className={`role-picker ${(this.props.data.hidden) ? 'hidden' : ''}`}> return <div className={`role-picker ${(data.get('hidden')) ? 'hidden' : ''}`}>
{ (this.props.server.get('message') !== '') { (server.get('message') !== '')
? <section> ? <section>
<h3>Server Message</h3> <h3>Server Message</h3>
<p>{this.props.server.get('message')}</p> <p>{server.get('message')}</p>
</section> </section>
: null : null
} }
<section> <section>
<h3>Roles</h3> <h3>Roles</h3>
<div className="role-picker__categories">
{ {
this.props.server.get('roles').map((r, k) => { vm.map((c, name) => {
return <Role key={k} role={r} selected={this.isSelected(r.get('id'))} onToggle={() => this.props.dispatch(Actions.roleUpdate(r.get('id'), this.isSelected(r.get('id'))))} /> if (c.get('hidden')) {
}) return null
}
return <div key={name} className="role-picker__category">
<h4>{ name }</h4>
{
c.get('roles_map').map((r, k) => {
return <Role key={k} role={r} selected={this.isSelected(r.get('id'))} onToggle={() => this.props.dispatch(Actions.roleUpdate(r.get('id'), this.isSelected(r.get('id'))))} />
}).toArray()
}
</div>
}).toArray()
} }
</div>
</section> </section>
</div> </div>
} }

View file

@ -1,6 +1,6 @@
.servers .servers
$fullH: calc(100vh - 75px) $fullH: calc(100vh - 180px)
display: grid display: grid
grid-template-rows: 100px $fullH grid-template-rows: 100px $fullH
@ -19,3 +19,4 @@
background-color: var(--c-3) background-color: var(--c-3)
padding: 15px padding: 15px
overflow-y: scroll overflow-y: scroll
box-sizing: border-box

View file

@ -2,17 +2,17 @@ import { Map, OrderedMap } from 'immutable'
const initialState = Map({ const initialState = Map({
hidden: true, // should the view be hidden? hidden: true, // should the view be hidden?
emptyRoles: true, // helps derender roles so there's no visible element state change // emptyRoles: true, // helps derender roles so there's no visible element state change
viewMap: OrderedMap({}), // roles in categories viewMap: OrderedMap({}), // roles in categories
originalRolesSelected: Map({}), // Map<role id, bool> -- original roles for diffing against selected originalRolesSelected: Map({}), // Map<role id, bool> -- original roles for diffing against selected
rolesSelected: Map({}) // Map<role id, bool> -- new roles for diffing rolesSelected: Map({}) // Map<role id, bool> -- new roles for diffing
}) })
export default (state = initialState, { type, data }) => { export default (state = initialState, { type, data }) => {
switch (type) { switch (type) {
case Symbol.for('setup role picker'): case Symbol.for('setup role picker'):
return state.mergeDeep(data) return Map(data)
case Symbol.for('hide role picker ui'): case Symbol.for('hide role picker ui'):
return { return {
...state, ...state,
@ -27,9 +27,9 @@ export default (state = initialState, { type, data }) => {
case Symbol.for('update selected roles'): case Symbol.for('update selected roles'):
return state.setIn(['rolesSelected', data.id], data.state) return state.setIn(['rolesSelected', data.id], data.state)
case Symbol.for('zero role picker'): // case Symbol.for('zero role picker'):
return initialState // return initialState
default: default:
return state return state

View file

@ -14,6 +14,7 @@ const blankServer = Map({
icon: '4fa0c1063649a739f3fe1a0589aa2c03' icon: '4fa0c1063649a739f3fe1a0589aa2c03'
}, },
roles: Set([]), roles: Set([]),
categories: OrderedMap(),
perms: { perms: {
isAdmin: true, isAdmin: true,
canManageRoles: true canManageRoles: true