{% extends "base.html" %} {% block title_row %}{% endblock %} {% block title_ruler %}{% endblock %} {% block js_media %} <script type="text/javascript"> var chatSocket = new WebSocket( 'ws://' + window.location.host + '/ws/chat/'); </script> <script type="text/javascript" src="{{ static('mathjax_config.js') }}"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_HTML"></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['id'], data['image'], data['css_class'], true); // console.log(data); $('#chat-box').scrollTop($('#chat-box')[0].scrollHeight); }; function encodeHTML(content) { return content.replace(/[\u00A0-\u9999<>\&]/gim, function(i) { return '&#'+i.charCodeAt(0)+';'; }); } const datesAreOnSameDay = (first, second) => first.getFullYear() === second.getFullYear() && first.getMonth() === second.getMonth() && first.getDate() === second.getDate(); function loadMessage(content, user, time, messid, image, css_class, isNew) { // if (isNew) content = encodeHTML(content) time = new Date(time); if (datesAreOnSameDay(time, new Date())) { time = moment(time).format("HH:mm"); } else { time = moment(time).format("HH:mm DD-MM-YYYY"); } content = encodeHTML(content); li = `<li class="message"> <img src="${image}" class="profile-pic"> <div class="body-message"> <div class="user-time"> <span class="${css_class}"> <a href="{{ url('user_page') }}/${user}"> ${user} </a> </span> <span class="time">${time}</span> {% if request.user.is_staff %} <a class="chatbtn_remove_mess" style="color:red; cursor: pointer;" data-messtime="${time}" data-author="${user}" data-messid="${messid}">Delete</a> {% endif %} </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) } MathJax.Hub.Queue(["Typeset",MathJax.Hub]); } (function init_chatlog() { ul = $('#chat-log') {% autoescape on %} {% for msg in message %} loadMessage("{{msg.body|safe|escapejs}}", `{{msg.author}}`, `{{msg.time}}`, `{{msg.id}}`, `{{gravatar(msg.author, 32)}}`,`{{msg.author.css_class}}`); {% endfor %} {% endautoescape %} $('#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.id, msg.image, msg.css_class) } loader.hide() // scroll to last msg container.scrollTop( scrollTopOfBottom(container) - lastMsgPos ) }, 500) } }) } } })} scrollContainer($('#chat-box'), $('#loader')) {% if request.user.is_staff %} $(document).on("click", ".chatbtn_remove_mess", function() { var elt = $(this); $.ajax({ url: 'delete/', type: 'post', data: elt.data(), dataType: 'json', success: function(data){ console.log('delete ajax call success!'); location.reload(); } }); }); {% endif %} $("#chat-submit").click(function() { if ($("#chat-input").val().trim()) { let body = $('#chat-input').val().trim(); let img = '{{ gravatar(request.user, 32) }}' message = { 'body': body, } 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 }); }); $(document).ready(function () { $('.chat-right-panel').hide(); $('#chat-tab').find('a').click(function (e) { e.preventDefault(); $('#chat-tab').addClass('active'); $('#online-tab').removeClass('active'); $('.chat-left-panel').show(); $('.chat-right-panel').hide(); }); $('#online-tab').find('a').click(function (e) { e.preventDefault(); $('#online-tab').addClass('active'); $('#chat-tab').removeClass('active'); $('.chat-left-panel').hide(); $('.chat-right-panel').show(); }); }); </script> {% endblock js_media %} {% block media %} <style> #content { margin-top: -0.5em; } </style> {% endblock media %} {% block body %} {% csrf_token %} {% block before_posts %}{% endblock %} <div id="mobile" class="tabs"> <ul> <li id="chat-tab" class="tab active"><a href="#"> <i class="tab-icon fa fa-comments"></i> {{ _('Chat') }} </a></li> <li id="online-tab" class="tab"><a href="#"><i class="tab-icon fa fa-wifi"></i> {{ _('Online Users') }}</a></li> </ul> </div> <div id="chat-container"> <div id="chat-area" class="chat-left-panel"> <div id="chat-box"> <img src="http://opengraphicdesign.com/wp-content/uploads/2009/01/loader64.gif" id="loader"> <ul id="chat-log"> </ul> </div> <textarea id="chat-input" placeholder="{{_('Enter your message')}}"></textarea> </div> <button id="chat-submit" style="display:none;"> Send </button> <div id="chat-online" class="chat-right-panel sidebox"> <h3> {{_('Online Users')}} <i class="fa fa-wifi"></i> </h3> <ul id="chat-online-content"> <h4>{{_('Admins')}}: </h4> <hr/> {% for user in admin_status %} <li style="padding-left: 1em"> {% if user.is_online %} <span class="green-dot"></span> {% else %} <span class="red-dot"></span> {% endif %} <span style="padding-left:0.25em"> {{ link_user(user.user) }} </span> </li> {% endfor %} <h4 style="margin-top:1em;">{{_('Users')}}: </h4> <hr/> {% for user in online_users %} <li style="padding-left: 1em"> <span class="green-dot"></span> <span style="padding-left:0.25em"> {{ link_user(user.user) }} </span> </li> {% endfor %} </ul> </div> </div> {% endblock body %}