summaryrefslogtreecommitdiff
path: root/assets/js/chat.js
blob: aa7f05df43a8dc13302298f4b3cc86aa8c58624f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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); });
    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;