summaryrefslogtreecommitdiff
path: root/assets
diff options
context:
space:
mode:
Diffstat (limited to 'assets')
-rw-r--r--assets/css/app.css119
-rw-r--r--assets/js/app.js30
-rw-r--r--assets/js/chat.js115
3 files changed, 132 insertions, 132 deletions
diff --git a/assets/css/app.css b/assets/css/app.css
index 2cc38b4..0bab67f 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -126,115 +126,16 @@
white-space: pre-line;
}
-
-/* Chat css from: https://www.bootdey.com/snippets/view/card-chat-list#html */
-.chat-container {
- height: 300px;
- overflow-y: scroll;
-}
-
-.chat-list {
- padding: 0;
- font-size: .8rem;
- padding-bottom: 12px;
-}
-
-.chat-list li {
- margin-bottom: 10px;
- overflow: auto;
- color: #ffffff;
+.circle {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ display: flex; /* or inline-flex */
+ align-items: center;
+ justify-content: center;
}
-.chat-list .chat-img {
- float: left;
- width: 48px;
-}
-
-.chat-list .chat-img img {
- -webkit-border-radius: 50px;
- -moz-border-radius: 50px;
- border-radius: 50px;
- width: 100%;
-}
-
-.chat-list .chat-message {
- -webkit-border-radius: 50px;
- -moz-border-radius: 50px;
- border-radius: 50px;
- background: #5a99ee;
- display: inline-block;
- padding: 10px 20px;
- position: relative;
-}
-
-.chat-list .chat-message:before {
- content: "";
- position: absolute;
- top: 15px;
- width: 0;
- height: 0;
-}
-
-.chat-list .chat-message h5 {
- margin: 0 0 5px 0;
- font-weight: 600;
- line-height: 100%;
- font-size: .9rem;
-}
-
-.chat-list .chat-message p {
- line-height: 18px;
- margin: 0;
- padding: 0;
-}
-
-.chat-list .chat-body {
- margin-left: 20px;
- float: left;
- width: 70%;
-}
-
-.chat-list .in .chat-message:before {
- left: -12px;
- border-bottom: 20px solid transparent;
- border-right: 20px solid #5a99ee;
-}
-
-.chat-list .out .chat-img {
- float: right;
-}
-
-.chat-list .out .chat-body {
- float: right;
- margin-right: 20px;
- text-align: right;
-}
-
-.chat-list .out .chat-message {
- background: #fc6d4c;
-}
-
-.chat-list .out .chat-message:before {
- right: -12px;
- border-bottom: 20px solid transparent;
- border-left: 20px solid #fc6d4c;
-}
-
-.card .card-header:first-child {
- -webkit-border-radius: 0.3rem 0.3rem 0 0;
- -moz-border-radius: 0.3rem 0.3rem 0 0;
- border-radius: 0.3rem 0.3rem 0 0;
-}
-.card .card-header {
- background: #17202b;
- border: 0;
- font-size: 1rem;
- padding: .65rem 1rem;
- position: relative;
- font-weight: 600;
- color: #ffffff;
+.chat {
+ max-height: 50vh;
+ overflow-y: scroll;
}
-
-.content{
- margin-top:40px;
-} \ No newline at end of file
diff --git a/assets/js/app.js b/assets/js/app.js
index 94780d0..92b68d1 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -1,6 +1,6 @@
// We import the CSS which is extracted to its own file by esbuild.
// Remove this line if you add a your own CSS build pipeline (e.g postcss).
-import "../css/app.css"
+import "../css/app.css";
// If you want to use Phoenix channels, run `mix help phx.gen.channel`
// to get started and then uncomment the line below.
@@ -20,32 +20,32 @@ import "../css/app.css"
//
// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
-import "phoenix_html"
+import "phoenix_html";
// Establish Phoenix Socket and LiveView configuration.
-import {Socket} from "phoenix"
-import {LiveSocket} from "phoenix_live_view"
-import topbar from "../vendor/topbar"
+import {Socket} from "phoenix";
+import {LiveSocket} from "phoenix_live_view";
+import topbar from "../vendor/topbar";
-let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
-let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})
+let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
+let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}});
// Show progress bar on live navigation and form submits
-topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
-window.addEventListener("phx:page-loading-start", info => topbar.show())
-window.addEventListener("phx:page-loading-stop", info => topbar.hide())
+topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"});
+window.addEventListener("phx:page-loading-start", info => topbar.show());
+window.addEventListener("phx:page-loading-stop", info => topbar.hide());
// connect if there are any LiveViews on the page
-liveSocket.connect()
+liveSocket.connect();
// expose liveSocket on window for web console debug logs and latency simulation:
// >> liveSocket.enableDebug()
// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session
// >> liveSocket.disableLatencySim()
-window.liveSocket = liveSocket
+window.liveSocket = liveSocket;
// Hack to remove alerts on click
-Array.from(window.document.getElementsByClassName('alert')).forEach((x) => x.addEventListener('click', () => x.style.display = "none"))
+Array.from(window.document.getElementsByClassName('alert')).forEach((x) => x.addEventListener('click', () => x.style.display = "none"));
-import RoomChat from "./chat"
+window.userSocket = new Socket("/socket", {params: {_csrf_token: csrfToken}});
+import RoomChat from "./chat";
window.RoomChat = RoomChat;
-window.userSocket = new Socket("/socket", {params: {_csrf_token: csrfToken}}) \ No newline at end of file
diff --git a/assets/js/chat.js b/assets/js/chat.js
index 4183531..aa7f05d 100644
--- a/assets/js/chat.js
+++ b/assets/js/chat.js
@@ -1,11 +1,110 @@
-let RoomChat = {
- connect(socket, postId) {
- let channel = socket.channel(`post:${postId}`)
+const gruvboxColors = [
+ "#b8bb26",
+ "#fabd2f",
+ "#83a598",
+ "#d3869b",
+ "#8ec07c",
+ "#458588",
+ "#cc241d",
+ "#d65d0e",
+ "#bdae93",
+];
+const generateGruvboxFromString = (string) =>
+ gruvboxColors[Array.from(string).map((x) => x.charCodeAt(0)).reduce((a, x) => a+x, 0) % gruvboxColors.length];
+
+const RoomChat = (() => {
+ let channel;
+ const connect = (socket, postId) => {
+ channel = socket.channel(`post:${postId}`);
channel.join()
- .receive("ok", resp => { console.log("Joined successfully: ", resp) })
- .receive("error", resp => { console.log("Unable to join: ", resp) })
+ .receive("ok", resp => { console.log("Joined successfully: ", resp); })
+ .receive("error", resp => { console.log("Unable to join: ", resp); });
return channel;
- },
-}
+ };
+
+ const scrollToBottom = (element) => {
+ element.scrollTop = element.scrollHeight;
+ };
+
+ const appendComment = ({user, body, id, user_id, inserted_at}, element) => {
+ const messageElement = document.createElement("div");
+ messageElement.innerHTML = `
+ <div class="d-flex flex-row card border rounded m-2 align-items-center">
+ <div class="m-2">
+ <div class="circle" style="background:${generateGruvboxFromString(user)}">${user.charAt(0)}</div>
+ </div>
+ <div class="m-2">
+ <div class="comment">
+ <div class="comment-header">
+ <span class="comment-username">${user}</span>
+ <span class="text-muted">${new Date(inserted_at).toLocaleString()}</span>
+ </div>
+ <div class="comment-body">
+ ${body}
+ </div>
+ </div>
+ </div>
+ </div>
+ `;
+ element.appendChild(messageElement);
+ scrollToBottom(element);
+ };
+
+ const leaveChannel = () => {
+ if (channel) {
+ channel.leave();
+ console.log(channel);
+ }
+ };
+
+ const main = (post_id) => {
+ leaveChannel();
+ const chatWindow = document.getElementById("chat");
+ window.userSocket.connect();
+ channel = connect(window.userSocket, post_id);
+
+ channel.on('shout', (comment) => {
+ appendComment(comment, chatWindow);
+ });
+
+ channel.on('initial-comments', ({comments}) => {
+ comments.forEach((comment) => {
+ appendComment(comment, chatWindow);
+ });
+ scrollToBottom(chatWindow);
+ });
+
+ channel.on('join', ({ user }) => {
+ const joinElement = document.createElement("div");
+ joinElement.innerHTML = `
+ <div class="m-2 card border rounded p-2 text-muted">
+ join: ${user}
+ </div>
+ `;
+ chatWindow.appendChild(joinElement);
+ scrollToBottom(chatWindow);
+ });
+
+ channel.on('left', ({ user }) => {
+ console.log(user, "left");
+ });
+ };
+
+ const submitForm = (e) => {
+ e.preventDefault();
+ let message = e.target.elements.message.value;
+ if (message) {
+ channel.push("send", {body: message});
+ e.target.elements.message.value = "";
+ }
+ return false;
+ };
+
+ return { main, submitForm };
+})();
+
+window.addEventListener('load', () => {
+ window.addEventListener('phx:initial-post', (e) => RoomChat.main(e.detail.id));
+});
-export default RoomChat; \ No newline at end of file
+export default RoomChat;