mirror of
https://github.com/roleypoly/roleypoly-v1.git
synced 2025-04-25 12:19:10 +00:00
first bit of the role picker
This commit is contained in:
parent
4b6e6f194b
commit
456da9cd0c
3 changed files with 145 additions and 26 deletions
|
@ -6,19 +6,31 @@ import SocialCards from '../../components/social-cards'
|
|||
import redirect from '../../lib/redirect'
|
||||
import { connect } from 'react-redux'
|
||||
import { fetchServerIfNeed, getCurrentServerState, type ServerState } from '../../stores/currentServer'
|
||||
import { renderRoles, getCurrentRoles } from '../../stores/roles'
|
||||
import { renderRoles, getCategoryViewState, toggleRole, type ViewState } from '../../stores/roles'
|
||||
import styled from 'styled-components'
|
||||
import Role from '../../components/role'
|
||||
|
||||
type ServerPageProps = PageProps & {
|
||||
currentServer: ServerState
|
||||
currentServer: ServerState,
|
||||
view: ViewState
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, { router: { query: { id } } }) => {
|
||||
return {
|
||||
currentServer: getCurrentServerState(state, id),
|
||||
roles: getCurrentRoles(state, id)
|
||||
view: getCategoryViewState(state)
|
||||
}
|
||||
}
|
||||
|
||||
const Category = styled.div``
|
||||
|
||||
const Hider = styled.div`
|
||||
/* opacity: ${(props: any) => props.visible ? '1' : '0'}; */
|
||||
/* opacity: 1; */
|
||||
/* transition: opacity 0.15s ease-out; */
|
||||
/* ${(props: any) => props.visible ? '' : 'display: none;'} */
|
||||
`
|
||||
|
||||
class Server extends React.Component<ServerPageProps> {
|
||||
static async getInitialProps (ctx: *, rpc: *, router: *) {
|
||||
if (ctx.user == null) {
|
||||
|
@ -26,29 +38,29 @@ class Server extends React.Component<ServerPageProps> {
|
|||
}
|
||||
|
||||
ctx.robots = 'NOINDEX, NOFOLLOW'
|
||||
try {
|
||||
if (router.query.id == null) {
|
||||
console.warn({ query: router.query })
|
||||
}
|
||||
ctx.store.dispatch(fetchServerIfNeed(router.query.id, rpc))
|
||||
ctx.store.dispatch(renderRoles(router.query.id))
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
await ctx.store.dispatch(fetchServerIfNeed(router.query.id, rpc))
|
||||
await ctx.store.dispatch(renderRoles(router.query.id))
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
async componentDidMount () {
|
||||
const { currentServer, router: { query: { id } }, dispatch } = this.props
|
||||
if (currentServer == null) {
|
||||
this.props.router.push('/s/add')
|
||||
}
|
||||
|
||||
dispatch(fetchServerIfNeed(id))
|
||||
await dispatch(fetchServerIfNeed(id))
|
||||
await dispatch(renderRoles(id))
|
||||
}
|
||||
|
||||
onToggle = (role) => (nextState) => {
|
||||
if (role.safe) {
|
||||
this.props.dispatch(toggleRole(role.id, nextState))
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { currentServer } = this.props
|
||||
console.log({ currentServer })
|
||||
const { currentServer, view } = this.props
|
||||
// console.log({ currentServer })
|
||||
if (currentServer == null) {
|
||||
return null
|
||||
}
|
||||
|
@ -59,7 +71,17 @@ class Server extends React.Component<ServerPageProps> {
|
|||
<title key='title'>{currentServer.server.name} - Roleypoly</title>
|
||||
</Head>
|
||||
<SocialCards title={`${currentServer.server.name} on Roleypoly`} />
|
||||
hello <span style={{ color: currentServer.gm.color }}>{currentServer.gm.nickname}</span> on {currentServer.server.name}
|
||||
hello <span style={{ color: currentServer.gm.color }}>{currentServer.gm.nickname}</span> on {currentServer.server.name} ({ view.dirty ? 'dirty' : 'clean' })
|
||||
<Hider visible={true || currentServer.id !== null}>
|
||||
{ !view.invalidated && view.categories.map(c => <Category key={c.id}>
|
||||
<div>{ c.name }</div>
|
||||
<div>
|
||||
{
|
||||
c._roles && c._roles.map(r => <Role key={r.id} role={r} active={view.selected.includes(r.id)} onToggle={this.onToggle(r)} disabled={!r.safe} />)
|
||||
}
|
||||
</div>
|
||||
</Category>) }
|
||||
</Hider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { dynamicPropertyConfig } from 'fast-redux'
|
||||
// import { Map } from 'immutable'
|
||||
import type { PresentableServer } from '../../services/presentation'
|
||||
import type { Category } from '../../models/Server'
|
||||
import RPC from '../config/rpc'
|
||||
import { action } from './servers'
|
||||
|
||||
|
@ -15,7 +16,8 @@ const DEFAULT_STATE: $Shape<PresentableServer> | { id: ?string } = {
|
|||
},
|
||||
gm: {
|
||||
nickname: 'person',
|
||||
color: '#ff00ff'
|
||||
color: '#ff00ff',
|
||||
roles: ['0000']
|
||||
},
|
||||
categories: {},
|
||||
perms: {
|
||||
|
@ -46,7 +48,7 @@ export const fetchServerIfNeed = (id: string, rpc?: typeof RPC) => async (dispat
|
|||
if (state.id == null || state.id !== id) {
|
||||
const server = await rpc.getServer(id)
|
||||
dispatch(updateCurrentServer(id, server))
|
||||
console.log({ state, server, fullStore: getState() })
|
||||
// console.log({ state, server, fullStore: getState() })
|
||||
} else {
|
||||
console.log('did not update')
|
||||
}
|
||||
|
|
|
@ -1,10 +1,105 @@
|
|||
// @flow
|
||||
// import { action } from './servers'
|
||||
import { namespaceConfig } from 'fast-redux'
|
||||
import { getCurrentServerState } from './currentServer'
|
||||
import { OrderedMap, OrderedSet, Set } from 'immutable'
|
||||
import { getCurrentServerState, type ServerState } from './currentServer'
|
||||
|
||||
export const { action, getState: getCurrentRoles } = namespaceConfig('roles', {})
|
||||
|
||||
export const updateCurrentRoles = action('updateCurrentRoles', (state, data) => data)
|
||||
|
||||
export const renderRoles = (dispatch, getState) => {
|
||||
const server = getCurrentServerState(getState())
|
||||
type RenderedRole = {
|
||||
id: string,
|
||||
name: string,
|
||||
color: string
|
||||
}
|
||||
|
||||
type RenderedCategory = {
|
||||
id: string,
|
||||
name: string,
|
||||
_roles?: RenderedRole[],
|
||||
roles: string[],
|
||||
type: 'single' | 'multi',
|
||||
hidden: boolean,
|
||||
position?: number,
|
||||
}
|
||||
|
||||
const MOCK_DATA: RenderedCategory = {
|
||||
id: '00000',
|
||||
name: 'Placeholder Category',
|
||||
hidden: false,
|
||||
type: 'multi',
|
||||
roles: [ '00000' ],
|
||||
_roles: OrderedSet([
|
||||
{ id: '00000', name: 'Placeholder Role', color: '#ff00ff' }
|
||||
])
|
||||
}
|
||||
|
||||
const DEFAULT_VIEW_STATE = { server: '000', invalidated: true, categories: [ MOCK_DATA ], selected: Set<string>([]), originalSelected: Set<string>([]), dirty: false }
|
||||
export type ViewState = typeof DEFAULT_VIEW_STATE
|
||||
|
||||
export const { action, getState: getCategoryViewState } = namespaceConfig('currentCategoryView', DEFAULT_VIEW_STATE)
|
||||
|
||||
export const toggleRole = action('toggleRole', (state: ViewState, role: string, nextState: boolean) => {
|
||||
let selected = state.selected
|
||||
|
||||
if (nextState === true) {
|
||||
selected = selected.add(role)
|
||||
} else {
|
||||
selected = selected.delete(role)
|
||||
}
|
||||
|
||||
const dirty = !selected.equals(state.originalSelected)
|
||||
|
||||
return {
|
||||
...state,
|
||||
selected,
|
||||
dirty
|
||||
}
|
||||
})
|
||||
|
||||
const getUncategorized = (roleMap: OrderedMap<RenderedRole>, allCategories): RenderedCategory => {
|
||||
const roles = Set(roleMap.keys())
|
||||
const knownRoles = Set([...Object.values(allCategories).map((c: any) => c.roles)])
|
||||
const rolesLeft = roles.subtract(knownRoles)
|
||||
|
||||
// console.log({ roles, knownRoles, rolesLeft })
|
||||
return {
|
||||
id: 'Uncategorized',
|
||||
name: 'Uncategorized',
|
||||
position: -1,
|
||||
roles: rolesLeft,
|
||||
_roles: OrderedSet(rolesLeft.map(r => roleMap.get(r))).sortBy(v => -v.position),
|
||||
hidden: true,
|
||||
type: 'multi'
|
||||
}
|
||||
}
|
||||
|
||||
export const updateCurrentView = action('updateCurrentView', (state, data) => ({ ...state, ...data }))
|
||||
export const invalidateView = action('invalidateView', (state, data) => ({ ...state, invalidated: true }))
|
||||
|
||||
export const renderRoles = (id: string) => (dispatch: *, getState: *) => {
|
||||
const active = getCategoryViewState(getState())
|
||||
const current: ServerState = getCurrentServerState(getState(), id)
|
||||
if (!active.invalidated && current.id === active.id && active.id === id) {
|
||||
return
|
||||
}
|
||||
|
||||
const { roles, categories } = current
|
||||
if (roles == null) {
|
||||
return
|
||||
}
|
||||
|
||||
// console.log({ roles, categories })
|
||||
|
||||
const roleMap: OrderedMap<RenderedRole> = roles.reduce((acc: OrderedMap<RenderedRole>, r) => acc.set(r.id, r), OrderedMap())
|
||||
|
||||
let render = OrderedSet()
|
||||
for (let catId in categories) {
|
||||
const category = categories[catId]
|
||||
category._roles = OrderedSet(category.roles.map(r => roleMap.get(r))).sortBy(v => -v.position)
|
||||
render = render.add(category)
|
||||
}
|
||||
// console.log({id})
|
||||
render = render.add(getUncategorized(roleMap, categories))
|
||||
|
||||
render = render.sortBy(h => h.position || 0)
|
||||
|
||||
dispatch(updateCurrentView({ server: id, categories: render, invalidated: false, selected: Set(current.gm.roles), originalSelected: Set(current.gm.roles) }))
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue