Hi @hakimd , @ishi8 and @alicem
Sorry for the late reply, I've stopped updating this project and lost access to Retool since then.
I'll share what I have, although I might not remember exactly how it is working
The chat is a custom component:
This is what I have in Model:
{
"displayText": "Chat",
"coach": "TODO",
"client": {{usersTable.selectedRow.data._id}},
"timezone": {{usersTable.selectedRow.data.timezone}},
"data": {{getMessages.data}},
"queryToTrigger": "getUsers",
"queryToLoadMessages": "loadAllMessages",
"unreadCoachMessages": {{getCounters.data.unreadCoachMessages}},
}
This is the iFrame code:
<style>
body {
margin: 0;
padding: 10px;
font-family: 'Overpass', sans-serif;
}
.card-content {
min-height: 100%;
background: #ece5dd;
}
.msg-container {
width: 90%;
margin: 10px 0 10px 0;
white-space: pre-line;
overflow-wrap: break-word;
}
.msg-container-right {
margin-left:10%;
}
.msg {
color: #656565;
background: #fdf8e2;
padding: 4px 8px;
line-height: 26px;
font-size: 14px;
border-radius: 15px 15px 15px 4px;
position: relative;
}
.message-data-time {
color: #888888;
padding-left: 6px;
font-size: 12px;
}
.right-msg {
background: white;
border-radius: 15px 15px 4px 15px;
color: #455a64;
}
.scroll-btn, .load-btn {
display: block;
padding:0.5em;
border:0.16em solid rgba(85, 85, 85, 0.7);
border-radius:2em;
box-sizing: border-box;
text-decoration:none;
background: rgba(85, 85, 85, 0.7);
text-align:center;
transition: all 0.2s;
position:fixed;
right:1%;
z-index:9999;
}
.scroll-btn {
bottom:1%;
}
.load-btn {
top:1%;
}
.scroll-btn:hover, .load-btn:hover, {
background: rgba(255, 255, 255, 0.7);
}
</style>
<script src="https://cdn.tryretool.com/js/react.production.min.js" crossorigin></script>
<script src="https://cdn.tryretool.com/js/react-dom.production.min.js" crossorigin></script>
<script src="https://unpkg.com/@material-ui/core@3.9.3/umd/material-ui.production.min.js"></script>
<script src="https://rawgit.com/moment/moment/2.2.1/min/moment.min.js"></script>
<script src="https://cdn.rawgit.com/moment/moment-timezone/0.2.2/builds/moment-timezone-with-data.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Overpass&display=swap" rel="stylesheet">
<div id="react"></div>
<script type="text/babel">
const { Button, Card, CardContent } = window["material-ui"];
const scrollToBottom = () => {
document.getElementById("scrollToBottom").scrollIntoView();
}
const MyCustomComponent = ({ triggerQuery, model, modelUpdate }) => (
<Card>
<CardContent className="card-content">
<button className="load-btn" onClick={() => triggerQuery(model.queryToLoadMessages)}>βΏ</button>
<button className="scroll-btn" onClick={scrollToBottom}>π½</button>
{
model.data.map((message, index) => {
const time = moment(message.sentAt).tz(model.timezone).format("ddd, MMM D - hh:mm A");
return (
<div className={message.sentBy !== model.client ? "msg-container-right msg-container" : "msg-container"}>
<span class="message-data-time">
{time}
{message.sentBy !== model.client && (model.unreadCoachMessages === 0 || model.data.length - index > model.unreadCoachMessages) ? " β": ""}
{" #" + message._id.slice(0,5)}
</span>
{message.text && <div className={message.sentBy !== model.client ? " msg right-msg" : " msg left-msg"}>{message.text}</div>}
{message.image && <img className="msg-txt-img" width="250" src={message.image}/>}
</div>
)
})
}
<div id="loadAll"></div>
<div id="scrollToBottom"></div>
</CardContent>
</Card>
);
const ConnectedComponent = Retool.connectReactComponent(MyCustomComponent);
ReactDOM.render(<ConnectedComponent />, document.getElementById("react"));
</script>
To type an answer I use a TextInput, and to send it just a button that triggers a query sending the text to our DB. After the text is sent, the chat will reload to have the latest messages.
I hope this helps! Let me know if you need me to show something else from the code