{% extends "base.html" %} {% block js_media %} <script type="text/javascript"> var chatSocket = new WebSocket( 'ws://' + window.location.host + '/ws/chat/'); </script> <script type="text/javascript"> $(function() { let currentPage = 1; $('#loader').hide(); chatSocket.onmessage = function(e) { let data = JSON.parse(e.data) data = data['message'] loadMessage(data['body'], data['author'], data['time'], data['image'], true) $('#chat-box').scrollTop($('#chat-box')[0].scrollHeight); }; function encodeHTML(content) { return content.replace(/[\u00A0-\u9999<>\&]/gim, function(i) { return '&#'+i.charCodeAt(0)+';'; }); } function loadMessage(content, user, time, image, isNew) { if (isNew) content = encodeHTML(content) li = `<li class="message"> <img src="${image}" class="profile-pic"> <div class="body-message"> <div class="user-time"> <a href="{{ url('user_page') }}/${user}" class="user"> ${user} </a> <span class="time">${time}</span> </div> <span class="content-message">${content} </span> </div> <div class="clear"></div> </li>` ul = $('#chat-log') if (isNew) { ul.append(li) } else { ul.prepend(li) } } (function init_chatlog() { ul = $('#chat-log') {% for msg in message %} loadMessage(`{{msg.body}}`, `{{msg.author}}`, `{{msg.time}}`, `{{gravatar(msg.author, 32)}}`) {% endfor %} $('#chat-box').scrollTop($('#chat-box')[0].scrollHeight); })() function scrollTopOfBottom(container) { return container[0].scrollHeight - container.innerHeight() } function scrollContainer(container, loader) { container.scroll(function() { if (container.scrollTop() == 0) { if (currentPage < {{paginator.num_pages}}) { currentPage++; loader.show(); $.ajax({ url: `{{request.path}}?page=${currentPage}`, success: function(data) { let lastMsg = $('.message:first') let lastMsgPos = scrollTopOfBottom(container) data = JSON.parse(data) setTimeout( () => { for (msg of data) { loadMessage(msg.body, msg.author, msg.time, msg.image) } loader.hide() // scroll to last msg container.scrollTop( scrollTopOfBottom(container) - lastMsgPos ) }, 500) } }) } } })} scrollContainer($('#chat-box'), $('#loader')) $("#chat-submit").click(function() { if ($("#chat-input").val().trim()) { let body = $('#chat-input').val().trim(); let img = '{{ gravatar(request.user, 32) }}' message = { 'body': body, 'image': img, 'author': '{{request.profile}}', 'author_id': {{request.profile.id}}, } chatSocket.send(JSON.stringify({ 'message': message })); $('#chat-input').val('').focus(); } }); chatSocket.onclose = function(e) { console.error('Chat socket closed unexpectedly'); }; $("#chat-log").change(function() { $('#chat-log').scrollTop($('#chat-log')[0].scrollHeight); }); $('#chat-input').focus(); $('#chat-input').keydown(function(e) { if (e.keyCode === 13) { if (e.ctrlKey || e.shiftKey) { var val = this.value; if (typeof this.selectionStart == "number" && typeof this.selectionEnd == "number") { var start = this.selectionStart; this.value = val.slice(0, start) + "\n" + val.slice(this.selectionEnd); this.selectionStart = this.selectionEnd = start + 1; } else if (document.selection && document.selection.createRange) { this.focus(); var range = document.selection.createRange(); range.text = "\r\n"; range.collapse(false); range.select(); } } else { e.preventDefault(); $('#chat-submit').click(); } return false } return true }); }); </script> {% endblock js_media %} {% block body %} <div id="chat-area"> <div id="chat-box"> <img src="http://opengraphicdesign.com/wp-content/uploads/2009/01/loader64.gif" id="loader"> <ul id="chat-log"> </ul> </div> {{_('Your message')}} <textarea rows="6" id="chat-input"></textarea> </div> <button id="chat-submit"> Send </button> {% endblock body %}