summaryrefslogtreecommitdiff
path: root/assets/js
diff options
context:
space:
mode:
Diffstat (limited to 'assets/js')
-rw-r--r--assets/js/app.js30
-rw-r--r--assets/js/chat.js115
2 files changed, 122 insertions, 23 deletions
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;