styling for bot messages

This commit is contained in:
Sharon Kennedy 2020-02-23 16:57:16 -05:00
parent 03335e0cc2
commit 066824cb3b
4 changed files with 99 additions and 49 deletions

View File

@ -30,7 +30,8 @@
font-size: 0.9rem; font-size: 0.9rem;
> div { > div {
padding-bottom: 0.5rem; margin-top: 0.5rem;
margin-bottom: 0.5rem;
} }
} }
@ -41,11 +42,14 @@
} }
.text { .text {
padding: 0.5rem 0.75rem;
margin-top: 0.5rem; margin-top: 0.5rem;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
width: fit-content; width: fit-content;
border: 1px solid $theme-color; }
&.from-bot {
color: $dark-color;
font-size: 0.9rem;
} }
&.from-me { &.from-me {
@ -53,10 +57,12 @@
justify-content: flex-end; justify-content: flex-end;
.text { .text {
border: 1px solid $theme-color;
background-color: $theme-color; background-color: $theme-color;
color: $white; color: $white;
border-radius: 15px 15px 0 15px; border-radius: 15px 15px 0 15px;
margin-left: 10%; margin-left: 10%;
padding: 0.5rem 0.75rem;
} }
} }
@ -65,10 +71,12 @@
justify-content: flex-start; justify-content: flex-start;
.text { .text {
border: 1px solid $theme-color;
background-color: $white; background-color: $white;
color: $dark-color; color: $dark-color;
border-radius: 15px 15px 15px 0; border-radius: 15px 15px 15px 0;
margin-right: 10%; margin-right: 10%;
padding: 0.5rem 0.75rem;
} }
} }
} }

View File

@ -16,8 +16,9 @@ import Message from "./message";
const DEFAULT_MATRIX_SERVER = "https://matrix.rhok.space" const DEFAULT_MATRIX_SERVER = "https://matrix.rhok.space"
const DEFAULT_ROOM_NAME = "Support Chat" const DEFAULT_ROOM_NAME = "Support Chat"
const FACILITATOR_USERNAME = "@help-bot:rhok.space" const BOT_USERNAME = "@help-bot:rhok.space"
const ENCRYPTION_CONFIG = { "algorithm": "m.megolm.v1.aes-sha2" }; const ENCRYPTION_CONFIG = { "algorithm": "m.megolm.v1.aes-sha2" };
const ENCRYPTION_NOTICE = "Messages in this chat are secured with end-to-end encryption."
const DEFAULT_THEME = { const DEFAULT_THEME = {
themeColor: "#008080", // teal themeColor: "#008080", // teal
lightColor: "#FFF8F0", lightColor: "#FFF8F0",
@ -134,7 +135,7 @@ class ChatBox extends React.Component {
const chatTime = currentDate.toLocaleTimeString() const chatTime = currentDate.toLocaleTimeString()
return this.state.client.createRoom({ return this.state.client.createRoom({
room_alias_name: `private-support-chat-${uuid()}`, room_alias_name: `private-support-chat-${uuid()}`,
invite: [FACILITATOR_USERNAME], // TODO: create bot user to add invite: [BOT_USERNAME], // TODO: create bot user to add
visibility: 'private', visibility: 'private',
name: `${chatDate} - ${this.props.roomName} - started at ${chatTime}`, name: `${chatDate} - ${this.props.roomName} - started at ${chatTime}`,
initial_state: [ initial_state: [
@ -148,7 +149,7 @@ class ChatBox extends React.Component {
}) })
.then(data => { .then(data => {
this.verifyAllRoomDevices(data.room_id) this.verifyAllRoomDevices(data.room_id)
this.state.client.setPowerLevel(data.room_id, FACILITATOR_USERNAME, 100) this.state.client.setPowerLevel(data.room_id, BOT_USERNAME, 100)
.then(() => console.log("Set bot power level to 100")) .then(() => console.log("Set bot power level to 100"))
.catch(err => console.log("Error setting bot power level", err)) .catch(err => console.log("Error setting bot power level", err))
this.setState({ this.setState({
@ -193,6 +194,8 @@ class ChatBox extends React.Component {
content: event.getContent(), content: event.getContent(),
} }
console.log("INCOMING MESSAGE", message)
const messages = [...this.state.messages] const messages = [...this.state.messages]
messages.push(message) messages.push(message)
this.setState({ messages }) this.setState({ messages })
@ -216,29 +219,31 @@ class ChatBox extends React.Component {
}); });
this.state.client.on("Room.timeline", (event, room, toStartOfTimeline) => { this.state.client.on("Room.timeline", (event, room, toStartOfTimeline) => {
if (event.getType() === "m.room.message") { // if (event.getType() === "m.room.message") {
if (event.status === "sending") { // if (event.status === "not sent") {
return; // do nothing // return console.log("message not sent!", event)
} // }
if (event.status === "not sent") { // if (event.isEncrypted()) {
return console.log("message not sent!", event) // return console.log("message encrypted")
} // }
if (event.isEncrypted()) { // this.handleMessageEvent(event)
return console.log("message encrypted") // }
}
this.handleMessageEvent(event)
}
if (event.getType() === "m.room.encryption") { if (event.getType() === "m.room.encryption") {
this.setState({ isRoomEncrypted: true }) const msgList = [...this.state.messages]
} const encryptionMsg = {
id: 'encryption-msg-id',
type: 'm.room.message',
sender: BOT_USERNAME,
roomId: room.room_id,
content: { body: ENCRYPTION_NOTICE },
}
msgList.unshift(encryptionMsg)
if (event.getType() === "m.notice") { this.setState({ messages: msgList })
console.log("GOT BOT NOTICE!", event)
} }
}); });
@ -258,11 +263,11 @@ class ChatBox extends React.Component {
}); });
} }
if (prevState.roomId !== this.state.roomId) { // if (prevState.roomId !== this.state.roomId) {
this.setState({ // this.setState({
isRoomEncrypted: this.state.client.isRoomEncrypted(this.state.roomId) // isRoomEncrypted: this.state.client.isRoomEncrypted(this.state.roomId)
}) // })
} // }
if (!prevState.ready && this.state.ready) { if (!prevState.ready && this.state.ready) {
this.chatboxInput.current.focus() this.chatboxInput.current.focus()
@ -298,7 +303,7 @@ class ChatBox extends React.Component {
} }
render() { render() {
const { ready, messages, inputValue, userId, isRoomEncrypted, typingStatus } = this.state; const { ready, messages, inputValue, userId, typingStatus } = this.state;
const { opened, handleToggleOpen, privacyStatement, termsUrl } = this.props; const { opened, handleToggleOpen, privacyStatement, termsUrl } = this.props;
const inputLabel = 'Send a message...' const inputLabel = 'Send a message...'
@ -320,23 +325,20 @@ class ChatBox extends React.Component {
<div className="message-window"> <div className="message-window">
<div className="messages"> <div className="messages">
<div className="notices"> {
{ typingStatus && <div>{typingStatus}</div> } ready ?
</div> messages.map((message, index) => {
{ return(
ready ? <Message key={message.id} message={message} userId={userId} botId={BOT_USERNAME} />
messages.map((message, index) => { )
return( }) :
<Message key={message.id} message={message} userId={userId} /> <div className="loader">loading...</div>
) }
}) : { typingStatus &&
<div className="loader">loading...</div> <div className="notices">
} <div role="status">{typingStatus}</div>
</div> </div>
<div className="notices"> }
{ privacyStatement && <div>{privacyStatement}</div> }
{ termsUrl && <div>By using this service you agree to the <a href={termsUrl} target="_blank">Terms of Use</a>.</div> }
{ isRoomEncrypted && <div role="status">Messages in this chat are secured with end-to-end encryption.</div> }
</div> </div>
</div> </div>
<div className="input-window"> <div className="input-window">

View File

@ -1,11 +1,29 @@
import React from "react" import React from "react"
import PropTypes from "prop-types" import PropTypes from "prop-types"
const Message = ({ message, userId }) => { const Message = ({ message, userId, botId }) => {
const fromMe = message.sender === userId;
const senderClass = () => {
switch (message.sender) {
case userId:
return 'from-me'
case botId:
return 'from-bot'
default:
return 'from-support'
}
}
if (message.content.formatted_body) {
return (
<div className={`message ${senderClass()}`}>
<div className="text" dangerouslySetInnerHTML={{__html: message.content.formatted_body}} />
</div>
)
}
return ( return (
<div className={`message ${fromMe ? "from-me" : "from-support"}`}> <div className={`message ${senderClass()}`}>
<div className="text">{ message.content.body }</div> <div className="text">{ message.content.body }</div>
</div> </div>
) )

22
src/components/notice.jsx Normal file
View File

@ -0,0 +1,22 @@
import React from "react"
import PropTypes from "prop-types"
const Notice = ({ message, userId }) => {
const fromMe = message.sender === userId;
if (message.content.formatted_body) {
return (
<div className={`message ${fromMe ? "from-me" : "from-support"}`}>
<div className="text" dangerouslySetInnerHTML={{__html: message.content.formatted_body}} />
</div>
)
}
return (
<div className={`message ${fromMe ? "from-me" : "from-support"}`}>
<div className="text">{ message.content.body }</div>
</div>
)
}
export default Notice;