mirror of
https://github.com/roleypoly/roleypoly-v1.git
synced 2025-04-25 12:19:10 +00:00
first bits of redux
This commit is contained in:
parent
9c7f7fda73
commit
def2b0d2a3
13 changed files with 170 additions and 16 deletions
|
@ -20,5 +20,28 @@ export default ($: AppContext) => ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return $.P.serverSlug(srv)
|
return $.P.serverSlug(srv)
|
||||||
|
},
|
||||||
|
|
||||||
|
getServer (ctx: Context, id: string) {
|
||||||
|
const { userId } = (ctx.session: { userId: string })
|
||||||
|
|
||||||
|
const srv = $.discord.client.guilds.get(id)
|
||||||
|
|
||||||
|
if (srv == null) {
|
||||||
|
return { err: 'not_found' }
|
||||||
|
}
|
||||||
|
|
||||||
|
let gm
|
||||||
|
if (srv.members.has(userId)) {
|
||||||
|
gm = $.discord.gm(id, userId)
|
||||||
|
} else if ($.discord.isRoot(userId)) {
|
||||||
|
// gm = $.discord.fakeGm({ id: userId })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gm == null) {
|
||||||
|
return { err: 'not_found' }
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.P.presentableServer(srv, gm)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -93,7 +93,7 @@ class PresentationService extends Service {
|
||||||
return {
|
return {
|
||||||
id: server.id,
|
id: server.id,
|
||||||
gm: {
|
gm: {
|
||||||
nickname: gm.nickname,
|
nickname: gm.nickname || gm.user.username,
|
||||||
color: gm.displayHexColor
|
color: gm.displayHexColor
|
||||||
},
|
},
|
||||||
server: this.serverSlug(server),
|
server: this.serverSlug(server),
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import HeaderBarCommon, { Logomark } from './common'
|
import HeaderBarCommon, { Logomark } from './common'
|
||||||
import { type User } from '../../containers/user'
|
import { type User } from '../../stores/user'
|
||||||
import DiscordIcon from '../discord-guild-pic'
|
import DiscordIcon from '../discord-guild-pic'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { Hide } from '../../kit/media'
|
import { Hide } from '../../kit/media'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
const temporaryServer = {
|
const temporaryServer = {
|
||||||
id: '423497622876061707',
|
id: '423497622876061707',
|
||||||
|
@ -86,4 +87,8 @@ const HeaderBarAuth: React.StatelessFunctionalComponent<{ user: User }> = ({ use
|
||||||
</HeaderBarCommon>
|
</HeaderBarCommon>
|
||||||
)
|
)
|
||||||
|
|
||||||
export default HeaderBarAuth
|
const mapStateToProps = state => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps)(HeaderBarAuth)
|
||||||
|
|
|
@ -3,7 +3,7 @@ import * as React from 'react'
|
||||||
import GlobalColors from './global-colors'
|
import GlobalColors from './global-colors'
|
||||||
import SocialCards from './social-cards'
|
import SocialCards from './social-cards'
|
||||||
import HeaderBar from '../containers/header-bar'
|
import HeaderBar from '../containers/header-bar'
|
||||||
import { type User } from '../containers/user'
|
import { type User } from '../stores/user'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
const LayoutWrapper = styled.div`
|
const LayoutWrapper = styled.div`
|
||||||
|
|
|
@ -12,4 +12,6 @@ export const initStore = (initialState = {}) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const withRedux = (comp) => withNextRedux(initStore)(comp)
|
export const withRedux = (comp) => withNextRedux(initStore, {
|
||||||
|
debug: process.env.NODE_ENV === 'development'
|
||||||
|
})(comp)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import dynamic from 'next/dynamic'
|
import dynamic from 'next/dynamic'
|
||||||
import { type User } from './user'
|
import { type User } from '../stores/user'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
user: ?User
|
user: ?User
|
||||||
|
|
|
@ -4,8 +4,10 @@ import App, { Container } from 'next/app'
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import Layout from '../components/layout'
|
import Layout from '../components/layout'
|
||||||
import { withCookies } from '../config/rpc'
|
import { withCookies } from '../config/rpc'
|
||||||
|
import { Provider } from 'react-redux'
|
||||||
import ErrorP, { Overlay } from './_error'
|
import ErrorP, { Overlay } from './_error'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
import { withRedux } from '../config/redux'
|
||||||
|
|
||||||
type NextPage = React.Component<any> & React.StatelessFunctionalComponent<any> & {
|
type NextPage = React.Component<any> & React.StatelessFunctionalComponent<any> & {
|
||||||
getInitialProps: (ctx: any, ...args: any) => any
|
getInitialProps: (ctx: any, ...args: any) => any
|
||||||
|
@ -58,7 +60,7 @@ class RoleypolyApp extends App {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { Component, pageProps, router, user, layout, robots } = this.props
|
const { Component, pageProps, router, user, layout, robots, store } = this.props
|
||||||
// Fix for next/error rendering instead of our error page.
|
// Fix for next/error rendering instead of our error page.
|
||||||
// Who knows why this would ever happen.
|
// Who knows why this would ever happen.
|
||||||
const ErrorCaughtComponent = (Component.displayName === 'ErrorPage' || Component.constructor.name === 'ErrorPage') ? ErrorP : Component
|
const ErrorCaughtComponent = (Component.displayName === 'ErrorPage' || Component.constructor.name === 'ErrorPage') ? ErrorP : Component
|
||||||
|
@ -84,11 +86,13 @@ class RoleypolyApp extends App {
|
||||||
})(document);//
|
})(document);//
|
||||||
` }} />
|
` }} />
|
||||||
</Head>
|
</Head>
|
||||||
<Layout user={user} {...layout}>
|
<Provider store={store}>
|
||||||
<ErrorCaughtComponent {...pageProps} router={router} originalName={Component.displayName || Component.constructor.name} />
|
<Layout user={user} {...layout}>
|
||||||
</Layout>
|
<ErrorCaughtComponent {...pageProps} router={router} originalName={Component.displayName || Component.constructor.name} />
|
||||||
|
</Layout>
|
||||||
|
</Provider>
|
||||||
</Container>
|
</Container>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default RoleypolyApp
|
export default withRedux(RoleypolyApp)
|
||||||
|
|
|
@ -4,25 +4,65 @@ import Head from 'next/head'
|
||||||
import type { PageProps } from '../../types'
|
import type { PageProps } from '../../types'
|
||||||
import SocialCards from '../../components/social-cards'
|
import SocialCards from '../../components/social-cards'
|
||||||
import redirect from '../../lib/redirect'
|
import redirect from '../../lib/redirect'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import { fetchServerIfNeed, getCurrentServerState, type ServerState } from '../../stores/currentServer'
|
||||||
|
import { renderRoles, getCurrentRoles } from '../../stores/roles'
|
||||||
|
|
||||||
export default class Server extends React.Component<PageProps> {
|
type ServerPageProps = PageProps & {
|
||||||
|
currentServer: ServerState
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state, { router: { query: { id } } }) => {
|
||||||
|
return {
|
||||||
|
currentServer: getCurrentServerState(state, id),
|
||||||
|
roles: getCurrentRoles(state, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Server extends React.Component<ServerPageProps> {
|
||||||
static async getInitialProps (ctx: *, rpc: *, router: *) {
|
static async getInitialProps (ctx: *, rpc: *, router: *) {
|
||||||
if (ctx.user == null) {
|
if (ctx.user == null) {
|
||||||
redirect(ctx, `/auth/login?r=${router.asPath}`)
|
redirect(ctx, `/auth/login?r=${router.asPath}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.robots = 'NOINDEX, NOFOLLOW'
|
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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
const { currentServer, router: { query: { id } }, dispatch } = this.props
|
||||||
|
if (currentServer == null) {
|
||||||
|
this.props.router.push('/s/add')
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(fetchServerIfNeed(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const { currentServer } = this.props
|
||||||
|
console.log({ currentServer })
|
||||||
|
if (currentServer == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Head>
|
<Head>
|
||||||
<title key='title'>server name!</title>
|
<title key='title'>{currentServer.server.name} - Roleypoly</title>
|
||||||
</Head>
|
</Head>
|
||||||
<SocialCards title={'server test'} />
|
<SocialCards title={`${currentServer.server.name} on Roleypoly`} />
|
||||||
hello {this.props.router.query.id}
|
hello <span style={{ color: currentServer.gm.color }}>{currentServer.gm.nickname}</span> on {currentServer.server.name}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps)(Server)
|
||||||
|
|
53
ui/stores/currentServer.js
Normal file
53
ui/stores/currentServer.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// @flow
|
||||||
|
import { dynamicPropertyConfig } from 'fast-redux'
|
||||||
|
// import { Map } from 'immutable'
|
||||||
|
import type { PresentableServer } from '../../services/presentation'
|
||||||
|
import RPC from '../config/rpc'
|
||||||
|
import { action } from './servers'
|
||||||
|
|
||||||
|
const DEFAULT_STATE: $Shape<PresentableServer> | { id: ?string } = {
|
||||||
|
id: null,
|
||||||
|
server: {
|
||||||
|
name: 'PLACEHOLDER',
|
||||||
|
id: '386659935687147521',
|
||||||
|
icon: '4fa0c1063649a739f3fe1a0589aa2c03',
|
||||||
|
ownerID: '62601275618889728'
|
||||||
|
},
|
||||||
|
gm: {
|
||||||
|
nickname: 'person',
|
||||||
|
color: '#ff00ff'
|
||||||
|
},
|
||||||
|
categories: {},
|
||||||
|
perms: {
|
||||||
|
isAdmin: false,
|
||||||
|
canManageRoles: false
|
||||||
|
},
|
||||||
|
roles: []
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ServerState = PresentableServer
|
||||||
|
|
||||||
|
// export const { action, getState: getCurrentServerState } = namespaceConfig('currentServer', DEFAULT_STATE)
|
||||||
|
|
||||||
|
export const { propertyAction: currentServerAction, getPropertyState: getCurrentServerState } = dynamicPropertyConfig(action, DEFAULT_STATE)
|
||||||
|
|
||||||
|
export const updateCurrentServer = currentServerAction('updateCurrentServer', (state, newState) => ({ ...state, ...newState }))
|
||||||
|
|
||||||
|
export const fetchServerIfNeed = (id: string, rpc?: typeof RPC) => async (dispatch: *, getState: *) => {
|
||||||
|
if (rpc == null) {
|
||||||
|
rpc = RPC
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == null) {
|
||||||
|
console.warn({ id })
|
||||||
|
}
|
||||||
|
|
||||||
|
const state: ServerState = getCurrentServerState(getState(), id)
|
||||||
|
if (state.id == null || state.id !== id) {
|
||||||
|
const server = await rpc.getServer(id)
|
||||||
|
dispatch(updateCurrentServer(id, server))
|
||||||
|
console.log({ state, server, fullStore: getState() })
|
||||||
|
} else {
|
||||||
|
console.log('did not update')
|
||||||
|
}
|
||||||
|
}
|
10
ui/stores/roles.js
Normal file
10
ui/stores/roles.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { namespaceConfig } from 'fast-redux'
|
||||||
|
import { getCurrentServerState } 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())
|
||||||
|
}
|
16
ui/stores/servers.js
Normal file
16
ui/stores/servers.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// @flow
|
||||||
|
import { namespaceConfig } from 'fast-redux'
|
||||||
|
// import { Map } from 'immutable'
|
||||||
|
|
||||||
|
const DEFAULT_STATE = {}
|
||||||
|
|
||||||
|
export type ServersState = typeof DEFAULT_STATE
|
||||||
|
|
||||||
|
export const { action, getState: getServerState } = namespaceConfig('servers', DEFAULT_STATE)
|
||||||
|
|
||||||
|
export const updateServers = action('updateServers', (state: ServersState, serverData) => ({
|
||||||
|
...state,
|
||||||
|
servers: serverData
|
||||||
|
}))
|
||||||
|
|
||||||
|
export const updateSingleServer = action('updateSingleServer', (state, data, server) => ({ ...state, [server]: data }))
|
|
@ -3,7 +3,8 @@ import type { ServerSlug as BackendServerSlug } from '../services/presentation'
|
||||||
import type Router from 'next/router'
|
import type Router from 'next/router'
|
||||||
|
|
||||||
export type PageProps = {
|
export type PageProps = {
|
||||||
router: Router
|
router: Router,
|
||||||
|
dispatch: (...any) => mixed
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ServerSlug = BackendServerSlug
|
export type ServerSlug = BackendServerSlug
|
||||||
|
|
Loading…
Add table
Reference in a new issue