mirror of https://github.com/waku-org/js-waku.git
Use React Chat UI Kit
https://developers.livechat.com/docs/react-chat-ui-kit/
This commit is contained in:
parent
056dd0e5b3
commit
99321b29c8
|
@ -33,6 +33,7 @@
|
|||
"lastpub",
|
||||
"libauth",
|
||||
"libp",
|
||||
"livechat",
|
||||
"mkdir",
|
||||
"multiaddr",
|
||||
"multiaddrs",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,10 +4,10 @@
|
|||
"private": true,
|
||||
"homepage": "/js-waku",
|
||||
"dependencies": {
|
||||
"@material-ui/core": "^4.11.3",
|
||||
"@livechat/ui-kit": "*",
|
||||
"peer-id": "^0.14.8",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react": "^16.14.0",
|
||||
"react-dom": "^16.14.0",
|
||||
"server-name-generator": "^1.0.5",
|
||||
"waku": "file:../build/main/lib",
|
||||
"waku-chat": "file:../build/main/chat",
|
||||
|
|
|
@ -9,6 +9,7 @@ import handleCommand from './command';
|
|||
import Room from './Room';
|
||||
import Waku from 'waku/waku';
|
||||
import { WakuContext } from './WakuContext';
|
||||
import { ThemeProvider } from '@livechat/ui-kit';
|
||||
import { generate } from 'server-name-generator';
|
||||
|
||||
export const ChatContentTopic = 'dingpu';
|
||||
|
@ -49,21 +50,23 @@ export default function App() {
|
|||
style={{ height: '100vh', width: '100vw', overflow: 'hidden' }}
|
||||
>
|
||||
<WakuContext.Provider value={{ waku: stateWaku }}>
|
||||
<Room
|
||||
nick={nick}
|
||||
lines={stateMessages}
|
||||
commandHandler={(input: string) => {
|
||||
const { command, response } = handleCommand(
|
||||
input,
|
||||
stateWaku,
|
||||
setNick
|
||||
);
|
||||
const commandMessages = response.map((msg) => {
|
||||
return new ChatMessage(new Date(), command, msg);
|
||||
});
|
||||
copyAndReplace(commandMessages, stateMessages, setMessages);
|
||||
}}
|
||||
/>
|
||||
<ThemeProvider>
|
||||
<Room
|
||||
nick={nick}
|
||||
lines={stateMessages}
|
||||
commandHandler={(input: string) => {
|
||||
const { command, response } = handleCommand(
|
||||
input,
|
||||
stateWaku,
|
||||
setNick
|
||||
);
|
||||
const commandMessages = response.map((msg) => {
|
||||
return new ChatMessage(new Date(), command, msg);
|
||||
});
|
||||
copyAndReplace(commandMessages, stateMessages, setMessages);
|
||||
}}
|
||||
/>
|
||||
</ThemeProvider>
|
||||
</WakuContext.Provider>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemText,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { ChatMessage } from '../../build/main/chat/chat_message';
|
||||
import { Message, MessageText, MessageGroup } from '@livechat/ui-kit';
|
||||
|
||||
interface Props {
|
||||
messages: ChatMessage[];
|
||||
|
@ -16,59 +9,32 @@ interface Props {
|
|||
export default function ChatList(props: Props) {
|
||||
const messages = props.messages;
|
||||
|
||||
const listItems = messages.map((message) => (
|
||||
<ListItem key={message.timestamp.toString()}>
|
||||
<ListItemText primary={<Message message={message} />} />
|
||||
</ListItem>
|
||||
const listItems = messages.map((currentMessage) => (
|
||||
<Message
|
||||
key={currentMessage.timestamp.toString()}
|
||||
authorName={currentMessage.nick}
|
||||
date={formatDisplayDate(currentMessage)}
|
||||
>
|
||||
<MessageText>{currentMessage.message}</MessageText>
|
||||
</Message>
|
||||
));
|
||||
|
||||
return (
|
||||
<List dense={true}>
|
||||
<MessageGroup>
|
||||
{listItems}
|
||||
<AlwaysScrollToBottom messages={messages} />
|
||||
</List>
|
||||
</MessageGroup>
|
||||
);
|
||||
}
|
||||
|
||||
interface MessageProps {
|
||||
message: ChatMessage;
|
||||
}
|
||||
|
||||
function Message(props: MessageProps) {
|
||||
const chatMsg = props.message;
|
||||
const timestamp = chatMsg.timestamp.toLocaleString([], {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: '2-digit',
|
||||
hour12: false,
|
||||
});
|
||||
|
||||
// {`<${timestamp}> ${chatMsg.nick}: ${chatMsg.message}`}
|
||||
return (
|
||||
<Card className="chat-message" variant="outlined">
|
||||
<CardContent>
|
||||
<Typography className="chat-nick" variant="subtitle2">
|
||||
{chatMsg.nick}
|
||||
<Typography
|
||||
className="chat-timestamp"
|
||||
color="textSecondary"
|
||||
variant="caption"
|
||||
style={{ marginLeft: 3 }}
|
||||
>
|
||||
{timestamp}
|
||||
</Typography>
|
||||
</Typography>
|
||||
<Typography
|
||||
className="chat-message-content"
|
||||
variant="body1"
|
||||
component="p"
|
||||
>
|
||||
{chatMsg.message}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
function formatDisplayDate(message: ChatMessage) {
|
||||
return message.timestamp.toLocaleString([], {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: '2-digit',
|
||||
hour12: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const AlwaysScrollToBottom = (props: Props) => {
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
import React, { ChangeEvent, KeyboardEvent, useState } from 'react';
|
||||
import { Button, Grid, TextField } from '@material-ui/core';
|
||||
import { ChangeEvent, KeyboardEvent, useState } from 'react';
|
||||
import { useWaku } from './WakuContext';
|
||||
import {
|
||||
TextInput,
|
||||
TextComposer,
|
||||
Row,
|
||||
Fill,
|
||||
Fit,
|
||||
SendButton,
|
||||
} from '@livechat/ui-kit';
|
||||
|
||||
interface Props {
|
||||
messageHandler: (msg: string) => void;
|
||||
|
@ -30,32 +37,20 @@ export default function MessageInput(props: Props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Grid container direction="row" alignItems="center">
|
||||
<Grid item xs={11}>
|
||||
<TextField
|
||||
variant="outlined"
|
||||
label="Send a message"
|
||||
value={inputText}
|
||||
fullWidth={true}
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
onChange={messageHandler}
|
||||
onKeyPress={keyPressHandler}
|
||||
disabled={!waku}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={1}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
size="large"
|
||||
onClick={sendMessage}
|
||||
disabled={!waku}
|
||||
>
|
||||
Send
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<TextComposer
|
||||
onKeyDown={keyPressHandler}
|
||||
onChange={messageHandler}
|
||||
active={waku}
|
||||
onButtonClick={sendMessage}
|
||||
>
|
||||
<Row align="center">
|
||||
<Fill>
|
||||
<TextInput value={inputText} />
|
||||
</Fill>
|
||||
<Fit>
|
||||
<SendButton />
|
||||
</Fit>
|
||||
</Row>
|
||||
</TextComposer>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { ChatMessage } from 'waku-chat/chat_message';
|
||||
import { WakuMessage } from 'waku/waku_message';
|
||||
import { ChatContentTopic } from './App';
|
||||
import ChatList from './ChatList';
|
||||
import MessageInput from './MessageInput';
|
||||
import { useWaku } from './WakuContext';
|
||||
import { TitleBar, MessageList } from '@livechat/ui-kit';
|
||||
|
||||
interface Props {
|
||||
lines: ChatMessage[];
|
||||
|
@ -21,29 +22,25 @@ export default function Room(props: Props) {
|
|||
className="chat-container"
|
||||
style={{ height: '98vh', display: 'flex', flexDirection: 'column' }}
|
||||
>
|
||||
<div
|
||||
className="chat-list"
|
||||
style={{ display: 'flex', flexGrow: 1, overflowY: 'scroll' }}
|
||||
>
|
||||
<TitleBar title="Waku v2 chat app" />
|
||||
<MessageList active containScrollInSubtree>
|
||||
<ChatList messages={props.lines} />
|
||||
</div>
|
||||
<div className="chat-input" style={{ display: 'flex', padding: 20 }}>
|
||||
<MessageInput
|
||||
messageHandler={setMessageToSend}
|
||||
sendMessage={
|
||||
waku
|
||||
? async () => {
|
||||
return handleMessage(
|
||||
messageToSend,
|
||||
props.nick,
|
||||
props.commandHandler,
|
||||
waku.relay.send.bind(waku.relay)
|
||||
);
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</MessageList>
|
||||
<MessageInput
|
||||
messageHandler={setMessageToSend}
|
||||
sendMessage={
|
||||
waku
|
||||
? async () => {
|
||||
return handleMessage(
|
||||
messageToSend,
|
||||
props.nick,
|
||||
props.commandHandler,
|
||||
waku.relay.send.bind(waku.relay)
|
||||
);
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
declare module '@livechat/ui-kit';
|
|
@ -1,11 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
|
@ -18,9 +14,8 @@
|
|||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
"jsx": "react-jsx",
|
||||
"typeRoots": ["node_modules/@types", "src/types"]
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
"include": ["src"]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue