add global context

This commit is contained in:
Barry Gitarts 2020-07-22 13:42:13 -04:00
parent 2c51a9922a
commit 28ca53eefa
6 changed files with 107 additions and 14 deletions

View File

@ -8,6 +8,7 @@ import { SetAccount } from './types'
import Header from './components/Header' import Header from './components/Header'
import CreatePoll from './components/CreatePoll' import CreatePoll from './components/CreatePoll'
import ListPolls from './components/ListPolls' import ListPolls from './components/ListPolls'
import { MessagesProvider } from './context/messages/context'
declare global { declare global {
interface Window { interface Window {
@ -64,6 +65,7 @@ function App() {
return ( return (
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<MessagesProvider>
<div className={classes.root}> <div className={classes.root}>
<Header <Header
account={account} account={account}
@ -76,6 +78,7 @@ function App() {
</Switch> </Switch>
</Router> </Router>
</div> </div>
</MessagesProvider>
</ThemeProvider> </ThemeProvider>
); );
} }

View File

@ -1,10 +1,11 @@
import React, { Fragment, useEffect, useState } from 'react' import React, { Fragment, useEffect, useState, useContext } from 'react'
import classnames from 'classnames' import classnames from 'classnames'
import { import {
gotoPublicChat, gotoPublicChat,
getChatMessages, getChatMessages,
useChatMessages useChatMessages
} from '../utils/status' } from '../utils/status'
import { MessagesContext, IMessagesContext } from '../context/messages/context'
import { verifySignedMessage } from '../utils/signing' import { verifySignedMessage } from '../utils/signing'
import { Topics, Message, ISignedMessage, IEnrichedMessage, IPollInfo, IFormattedDate } from '../types' import { Topics, Message, ISignedMessage, IEnrichedMessage, IPollInfo, IFormattedDate } from '../types'
import Typography from '@material-ui/core/Typography' import Typography from '@material-ui/core/Typography'
@ -19,8 +20,16 @@ async function gotoPolls() {
getChatMessages() getChatMessages()
} }
async function enrichMessages(messages: Message[], setState: Function) { async function parseEnrichMessages(messages: Topics, setState: Function) {
const updated = messages.map(async (message): Promise<IEnrichedMessage | Message> => { const parsed: Topics | undefined = await parseMessages(messages)
if (!parsed) return
const rawPolls: Message[] = parsed['polls']
const polls: Message[] = await enrichMessages(rawPolls)
setState({ ...parsed, polls })
}
async function enrichMessages(messages: Message[]) {
const updated = messages.map(async (message): Promise<Message> => {
const { sigMsg } = message const { sigMsg } = message
if (!message || !sigMsg || !sigMsg.msg) return message if (!message || !sigMsg || !sigMsg.msg) return message
const res: string = await getFromIpfs(sigMsg.msg) const res: string = await getFromIpfs(sigMsg.msg)
@ -32,10 +41,10 @@ async function enrichMessages(messages: Message[], setState: Function) {
return message return message
}) })
const resolved = await Promise.all(updated) const resolved = await Promise.all(updated)
setState(resolved) return resolved
} }
async function parseMessages(messages: Topics | undefined, setState: Function) { async function parseMessages(messages: Topics | undefined) {
if (!messages) return if (!messages) return
const fmtMessages: Topics = {} const fmtMessages: Topics = {}
const keys = Object.keys(messages) const keys = Object.keys(messages)
@ -59,7 +68,7 @@ async function parseMessages(messages: Topics | undefined, setState: Function) {
const verified = parsed.filter(m => m.verified === true) const verified = parsed.filter(m => m.verified === true)
fmtMessages[key] = verified fmtMessages[key] = verified
}) })
setState(fmtMessages) return fmtMessages
} }
interface ITableCard { interface ITableCard {
@ -70,6 +79,7 @@ const isOdd = (num: number): boolean => !!(num % 2)
function TableCards({ polls }: ITableCard) { function TableCards({ polls }: ITableCard) {
const classes: any = useStyles() const classes: any = useStyles()
const { cardText, cellColor } = classes const { cardText, cellColor } = classes
console.log({polls})
return ( return (
<Fragment> <Fragment>
@ -87,6 +97,7 @@ function TableCards({ polls }: ITableCard) {
<Typography className={classnames(cellStyling, classes.cardTitle)}>{title}</Typography> <Typography className={classnames(cellStyling, classes.cardTitle)}>{title}</Typography>
<Typography className={classnames(cellStyling, classes.cardSubTitle)}>{description}</Typography> <Typography className={classnames(cellStyling, classes.cardSubTitle)}>{description}</Typography>
<Typography className={lightText}>{plainText}</Typography> <Typography className={lightText}>{plainText}</Typography>
<Typography className={classnames(cellStyling, classes.voteNow)}>Vote now</Typography>
</Fragment> </Fragment>
) )
@ -97,8 +108,11 @@ function TableCards({ polls }: ITableCard) {
function ListPolls() { function ListPolls() {
const [rawMessages] = useChatMessages() const [rawMessages] = useChatMessages()
const [chatMessages, setChatMessages] = useState() //const [chatMessages, setChatMessages] = useState()
const [enrichedPolls, setEnrichedPolls] = useState() const [enrichedPolls, setEnrichedPolls] = useState()
const messagesContext = useContext(MessagesContext)
const { dispatchSetPolls, dispatchSetTopics, chatMessages } = messagesContext
const classes: any = useStyles() const classes: any = useStyles()
useEffect(() => { useEffect(() => {
@ -106,14 +120,10 @@ function ListPolls() {
}, []) }, [])
useEffect(() => { useEffect(() => {
parseMessages(rawMessages, setChatMessages) if (rawMessages && dispatchSetTopics) parseEnrichMessages(rawMessages, dispatchSetTopics)
}, [rawMessages]) }, [rawMessages])
useEffect(() => { console.log({chatMessages, rawMessages, messagesContext})
if (chatMessages) enrichMessages(chatMessages['polls'], setEnrichedPolls)
}, [chatMessages])
console.log({chatMessages, rawMessages})
return ( return (
<Fragment> <Fragment>
<div className={classes.root}> <div className={classes.root}>
@ -121,7 +131,7 @@ function ListPolls() {
buttonText="Goto #polls to get started" buttonText="Goto #polls to get started"
onClick={gotoPolls} onClick={gotoPolls}
/>} />}
{!!enrichedPolls && <TableCards polls={enrichedPolls} />} {!!chatMessages && <TableCards polls={chatMessages['polls'] || []} />}
</div> </div>
</Fragment> </Fragment>
) )

View File

@ -0,0 +1,32 @@
import { Topics, Message } from '../../types'
export enum types {
SET_TOPICS = 'SET_TOPICS',
SET_POLLS = 'SET_POLLS'
}
interface SetTopicsAction {
type: types.SET_TOPICS,
payload: Topics
}
interface SetPollsAction {
type: types.SET_POLLS,
payload: Message[]
}
export type IAction = SetTopicsAction | SetPollsAction
export function setTopics(topics: Topics): SetTopicsAction {
return {
type: types.SET_TOPICS,
payload: topics
}
}
export function setPolls(polls: Message[]): SetPollsAction {
return {
type: types.SET_POLLS,
payload: polls
}
}

View File

@ -0,0 +1,24 @@
import React from "react";
import MessagesReducer from "./reducer";
import { setTopics, setPolls } from "./actions";
import { Topics, Message } from '../../types';
export type IMessagesContext = {
dispatchSetTopics: Function,
dispatchSetPolls: Function,
chatMessages: Topics
}
export const MessagesContext = React.createContext<Partial<IMessagesContext>>({});
export const MessagesConsumer = MessagesContext.Consumer;
export const MessagesProvider = ({ children }: any) => {
const [chatMessages, dispatch] = React.useReducer(MessagesReducer, {});
const dispatchSetTopics = (topics: Topics) => dispatch(setTopics(topics));
const dispatchSetPolls = (polls: Message[]) => dispatch(setPolls(polls));
const values = { chatMessages, dispatchSetPolls, dispatchSetTopics };
return (
<MessagesContext.Provider value={values}>
{children}
</MessagesContext.Provider>
);
};

View File

@ -0,0 +1,21 @@
import { types, IAction } from './actions'
import { Topics } from '../../types'
const MessagesReducer = (state: Topics, action: IAction) => {
switch (action.type) {
case types.SET_TOPICS:
return {
...state,
...action.payload
};
case types.SET_POLLS:
return {
...state,
polls: [ ...action.payload ]
};
default:
return state;
}
};
export default MessagesReducer;

View File

@ -29,6 +29,9 @@ const useStyles = makeStyles(theme => ({
}, },
cardSubTitle: { cardSubTitle: {
lineHeight: '1.5rem' lineHeight: '1.5rem'
},
voteNow: {
color: theme.palette.primary[500]
} }
})) }))