0% found this document useful (0 votes)
19 views7 pages

Code

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views7 pages

Code

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

App.

js
import React, { useReducer, useEffect } from 'react';
import reducer, { initialState } from '../state/reducer';
import Context from '../context';
import PubSub from '../pubsub';
import PublishMessage from './PublishMessage';
import MessageBoard from './MessageBoard';
import SetUsername from './SetUsername';
const pubsub = new PubSub();

function App() {
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
pubsub.addListener({
message: messageObject => {
const { channel, message } = messageObject;

console.log('Received message', message, 'channel', channel);


dispatch(message);}});
}, []);
console.log('state', state);
return (
<Context.Provider value={{ state, dispatch, pubsub }}>
<h2>Reaction</h2>
<SetUsername />
<hr />
<PublishMessage />
<hr />
<MessageBoard />
</Context.Provider>
);
}
export default App;

CreateReaction.js
import React from 'react';
import { REACTION_OBJECTS } from '../state/types';
import { useAppContext } from './hooks';
import { createReaction } from '../state/actions';
function CreateReaction({ messageId }) {
const { state: { username }, pubsub: { publish } } = useAppContext();
const publishReaction = ({ type, emoji }) => () => {
publish(createReaction({ type, emoji, username, messageId }));
}return (
<div className='CreateReaction'>
{
REACTION_OBJECTS.map(REACTION_OBJECT => {
const { type, emoji } = REACTION_OBJECT;
return (
<span
key={type}
onClick={publishReaction({ type, emoji })}
>
{emoji}
</span>
)})} </div>)}
export default CreateReaction;

hook.js
Import { useContext } from 'react';
import Context from '../context';
export const useAppContext = () => {
return useContext(Context);}

MessageBoard.js
import React from 'react';
import { useAppContext } from './hooks';
import CreateReaction from './CreateReaction';
import MessageReactions from './MessageReactions';
function MessageBoard() {
const { state: { messages, reactionsMap } } = useAppContext();
return (
<div>
{ messages.map(messageItem => {
const { id, text, username, timestamp } = messageItem;
return (
<div key={id}>
<h4>{new Date(timestamp).toLocaleString()}</h4>
<p>{text}</p>
<h4>- {username}</h4>
<CreateReaction messageId={id} />
<MessageReactions messageReactions={reactionsMap[id]} />
<hr />
</div>
)}) }</div>)}
xport default MessageBoard;
MessageReaction.js
import React from 'react';

function MessageReactions({ messageReactions }) {


if (!messageReactions) return null;

return (
messageReactions.map((reaction, index) => {
const { id, emoji, username } = reaction;

return (
<span key={id}>
<em>{username}: </em>
{emoji}
{index !== messageReactions.length-1 ? ', ' : null}
</span> )}))}
export default MessageReactions;

PublishMessage.js
import React, { useState } from 'react';
import { useAppContext } from './hooks';
import { newMessage } from '../state/actions';

function PublishMessage() {
const { state: { username }, pubsub: { publish } } = useAppContext();
const [text, setText] = useState('');

const updateText = event => {


setText(event.target.value);
}

const publishMessage = () => {


publish(newMessage({ text, username }));
}

const handleKeyPress = event => {


if (event.key === 'Enter') publishMessage();
}

return (
<div>
<h3>Got something to say?</h3>
<input value={text} onChange={updateText} onKeyPress={handleKeyPress} />
{' '}
<button onClick={publishMessage}>Publish it!</button>
</div>
)
}
export default PublishMessage;
SetUsername.js
import React from 'react';
import { useAppContext } from './hooks';
import { setUsername } from '../state/actions';

function SetUsername() {
const { state: { username }, dispatch } = useAppContext();

const updateUsername = event => {


dispatch(setUsername(event.target.value));
}

return (
<div>
<h3>Username</h3>
<input onChange={updateUsername} value={username} />
</div>
)
};
export default SetUsername ;

Action.js
import { NEW_MESSAGE, SET_USERNAME } from './types';
import uuid from 'uuid/v4';

export const newMessage = ({ text, username }) => ({


type: NEW_MESSAGE,
item: { id: uuid(), text, username, timestamp: Date.now() }
});

export const setUsername = username => ({


type: SET_USERNAME, username
});

export const createReaction = ({ type, emoji, username, messageId }) => ({


type,
item: { id: uuid(), timestamp: Date.now(), emoji, username, messageId }
});
reducer.js
import { NEW_MESSAGE, SET_USERNAME, REACTION_OBJECTS } from './types';

export const initialState = {


messages: [],
username: 'anonymous',
reactionsMap: {}
};

const REACTION_TYPES = REACTION_OBJECTS.map(


REACTION_OBJECT => REACTION_OBJECT.type
);
const reducer = (state, action) => {

if (REACTION_TYPES.includes(action.type)) {
let reactionsMap;
const { messageId } = action.item;
const messageReactions = state.reactionsMap[messageId];

if (messageReactions) {
reactionsMap = {
...state.reactionsMap,
[messageId]: [...messageReactions, action.item]
}
} else {
reactionsMap = {
...state.reactionsMap,
[messageId]: [action.item]
}
}

return { ...state, reactionsMap };


}

switch(action.type) {
case NEW_MESSAGE:
return { ...state, messages: [...state.messages, action.item] };
case SET_USERNAME:
return { ...state, username: action.username }
default:
return state;
}
}
export default reducer;
type.js
export const NEW_MESSAGE = 'NEW_MESSAGE';
export const SET_USERNAME = 'SET_USERNAME';
export const REACTION_OBJECTS = [
{

},
❤️
type: 'REACTION_LOVE',
emoji: ' '

},
👍
type: 'REACTION_LIKE',
emoji: ' '

},
👎
type: 'REACTION_DISLIKE',
emoji: ' '

}
😂
type: 'REACTION_LAUGH',
emoji: ' '

];

context.js
import { createContext } from 'react';
export default createContext();

index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( <App />);
pubsub.js
import PubNub from 'pubnub';
import pubnubConfig from './pubnub.config';

export const MESSAGE_CHANNEL = 'MESSAGE_CHANNEL';

function PubSub() {
const pubnub = new PubNub(pubnubConfig);

pubnub.subscribe({ channels: [MESSAGE_CHANNEL] });

this.addListener = listenerConfig => {


pubnub.addListener(listenerConfig);
}

this.publish = message => {


console.log('publish message', message);

pubnub.publish({
message,
channel: MESSAGE_CHANNEL
});
}}
export default PubSub;

pubsum.js
import PubNub from "pubNub";
import PubnubConfig from "./pubnub.config";

const pubnub = new PubNub(PubnubConfig);


export const MESSAGE_CHANNEL = 'MESSAGE_CHANNEL';

pubnub.subscribe({channels:[MESSAGE_CHANNEL]});

pubnub.addListener({
message :messageObject =>{
console.log('messageObject',messageObject);
}
});

setTimeout(()=>{},1000);
pubnub.publish({
message:'foo',
channel:MESSAGE_CHANNEL});

You might also like