From def2b0d2a3ef8b24271771bb7161ae6eeb395f66 Mon Sep 17 00:00:00 2001 From: Kata Date: Wed, 20 Mar 2019 09:25:28 -0500 Subject: [PATCH] first bits of redux --- rpc/servers.js | 23 ++++++++++++++ services/presentation.js | 2 +- ui/components/header/auth.js | 9 ++++-- ui/components/layout.js | 2 +- ui/config/redux.js | 4 ++- ui/containers/header-bar.js | 2 +- ui/pages/_app.js | 14 +++++--- ui/pages/_internal/_server.js | 48 +++++++++++++++++++++++++--- ui/stores/currentServer.js | 53 +++++++++++++++++++++++++++++++ ui/stores/roles.js | 10 ++++++ ui/stores/servers.js | 16 ++++++++++ ui/{containers => stores}/user.js | 0 ui/types.js | 3 +- 13 files changed, 170 insertions(+), 16 deletions(-) create mode 100644 ui/stores/currentServer.js create mode 100644 ui/stores/roles.js create mode 100644 ui/stores/servers.js rename ui/{containers => stores}/user.js (100%) diff --git a/rpc/servers.js b/rpc/servers.js index f82df01..de793ab 100644 --- a/rpc/servers.js +++ b/rpc/servers.js @@ -20,5 +20,28 @@ export default ($: AppContext) => ({ } 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) } }) diff --git a/services/presentation.js b/services/presentation.js index 1c1be82..f097dfc 100644 --- a/services/presentation.js +++ b/services/presentation.js @@ -93,7 +93,7 @@ class PresentationService extends Service { return { id: server.id, gm: { - nickname: gm.nickname, + nickname: gm.nickname || gm.user.username, color: gm.displayHexColor }, server: this.serverSlug(server), diff --git a/ui/components/header/auth.js b/ui/components/header/auth.js index 3414782..0e00e50 100644 --- a/ui/components/header/auth.js +++ b/ui/components/header/auth.js @@ -1,11 +1,12 @@ // @flow import * as React from 'react' import HeaderBarCommon, { Logomark } from './common' -import { type User } from '../../containers/user' +import { type User } from '../../stores/user' import DiscordIcon from '../discord-guild-pic' import styled from 'styled-components' import { Hide } from '../../kit/media' import Link from 'next/link' +import { connect } from 'react-redux' const temporaryServer = { id: '423497622876061707', @@ -86,4 +87,8 @@ const HeaderBarAuth: React.StatelessFunctionalComponent<{ user: User }> = ({ use ) -export default HeaderBarAuth +const mapStateToProps = state => { + +} + +export default connect(mapStateToProps)(HeaderBarAuth) diff --git a/ui/components/layout.js b/ui/components/layout.js index d2ba8ba..d4a0987 100644 --- a/ui/components/layout.js +++ b/ui/components/layout.js @@ -3,7 +3,7 @@ import * as React from 'react' import GlobalColors from './global-colors' import SocialCards from './social-cards' import HeaderBar from '../containers/header-bar' -import { type User } from '../containers/user' +import { type User } from '../stores/user' import styled from 'styled-components' const LayoutWrapper = styled.div` diff --git a/ui/config/redux.js b/ui/config/redux.js index dd43cb3..f01b472 100644 --- a/ui/config/redux.js +++ b/ui/config/redux.js @@ -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) diff --git a/ui/containers/header-bar.js b/ui/containers/header-bar.js index db88730..187b13a 100644 --- a/ui/containers/header-bar.js +++ b/ui/containers/header-bar.js @@ -1,7 +1,7 @@ // @flow import * as React from 'react' import dynamic from 'next/dynamic' -import { type User } from './user' +import { type User } from '../stores/user' type Props = { user: ?User diff --git a/ui/pages/_app.js b/ui/pages/_app.js index 2e529a0..98bc364 100644 --- a/ui/pages/_app.js +++ b/ui/pages/_app.js @@ -4,8 +4,10 @@ import App, { Container } from 'next/app' import Head from 'next/head' import Layout from '../components/layout' import { withCookies } from '../config/rpc' +import { Provider } from 'react-redux' import ErrorP, { Overlay } from './_error' import styled from 'styled-components' +import { withRedux } from '../config/redux' type NextPage = React.Component & React.StatelessFunctionalComponent & { getInitialProps: (ctx: any, ...args: any) => any @@ -58,7 +60,7 @@ class RoleypolyApp extends App { } 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. // Who knows why this would ever happen. const ErrorCaughtComponent = (Component.displayName === 'ErrorPage' || Component.constructor.name === 'ErrorPage') ? ErrorP : Component @@ -84,11 +86,13 @@ class RoleypolyApp extends App { })(document);// ` }} /> - - - + + + + + } } -export default RoleypolyApp +export default withRedux(RoleypolyApp) diff --git a/ui/pages/_internal/_server.js b/ui/pages/_internal/_server.js index e10a663..efc3009 100644 --- a/ui/pages/_internal/_server.js +++ b/ui/pages/_internal/_server.js @@ -4,25 +4,65 @@ import Head from 'next/head' import type { PageProps } from '../../types' 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' -export default class Server extends React.Component { +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 { static async getInitialProps (ctx: *, rpc: *, router: *) { if (ctx.user == null) { redirect(ctx, `/auth/login?r=${router.asPath}`) } 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 () { + const { currentServer } = this.props + console.log({ currentServer }) + if (currentServer == null) { + return null + } + return (
- server name! + {currentServer.server.name} - Roleypoly - - hello {this.props.router.query.id} + + hello {currentServer.gm.nickname} on {currentServer.server.name}
) } } + +export default connect(mapStateToProps)(Server) diff --git a/ui/stores/currentServer.js b/ui/stores/currentServer.js new file mode 100644 index 0000000..1285b0f --- /dev/null +++ b/ui/stores/currentServer.js @@ -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 | { 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') + } +} diff --git a/ui/stores/roles.js b/ui/stores/roles.js new file mode 100644 index 0000000..d2c5ad9 --- /dev/null +++ b/ui/stores/roles.js @@ -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()) +} diff --git a/ui/stores/servers.js b/ui/stores/servers.js new file mode 100644 index 0000000..a1c1d20 --- /dev/null +++ b/ui/stores/servers.js @@ -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 })) diff --git a/ui/containers/user.js b/ui/stores/user.js similarity index 100% rename from ui/containers/user.js rename to ui/stores/user.js diff --git a/ui/types.js b/ui/types.js index 789fd66..314dfa9 100644 --- a/ui/types.js +++ b/ui/types.js @@ -3,7 +3,8 @@ import type { ServerSlug as BackendServerSlug } from '../services/presentation' import type Router from 'next/router' export type PageProps = { - router: Router + router: Router, + dispatch: (...any) => mixed } export type ServerSlug = BackendServerSlug