0% found this document useful (0 votes)
18 views

Code

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

Code

Copyright
© © All Rights Reserved
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