From 2e34d65cbf8797a64eca0aa33290b63fd4ad37c4 Mon Sep 17 00:00:00 2001 From: afornerot Date: Wed, 16 Oct 2019 16:17:56 +0200 Subject: [PATCH 1/3] svg --- .../CoreBundle/Command/data/core-init-01.sql | 6 ++++-- .../Resources/public/themes/transnum/look.png | Bin 27748 -> 27748 bytes .../public/themes/transnum/transnum-logo.png | Bin 27748 -> 27748 bytes tmpl/ninegate-template.yml | 1 - 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ninegate-1.0/src/Cadoles/CoreBundle/Command/data/core-init-01.sql b/src/ninegate-1.0/src/Cadoles/CoreBundle/Command/data/core-init-01.sql index e8e84a60..c866b9e7 100644 --- a/src/ninegate-1.0/src/Cadoles/CoreBundle/Command/data/core-init-01.sql +++ b/src/ninegate-1.0/src/Cadoles/CoreBundle/Command/data/core-init-01.sql @@ -5,10 +5,11 @@ SET foreign_key_checks = 0; SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'; INSERT IGNORE INTO `niveau01` (`id`, `label`, `siren`) VALUES -(-100, 'scribe26', '0000000A'); +(-100, 'DRAAF', '130007107'); INSERT IGNORE INTO `user` (`id`, `niveau01_id`, `username`, `firstname`, `lastname`, `password`, `email`, `avatar`, `role`,`siren`,`authlevel`) VALUES -(-100, -100, 'admin', 'Administrateur', 'scribe26', 'PWD_CAS', 'admin@scribe26.ac-arno.fr', 'admin.jpg', 'ROLE_ADMIN', '0000000A', 'simple'); +(-100, -100, 'admin', 'Administrateur', 'draaf', '{SSHA}d+3hdhVA7sp4QIbp8DlYbcKNekrYbPkG +', 'admin@ldapbundle.ac-arno.fr', 'admin.jpg', 'ROLE_ADMIN', '130007107', 'simple'); @@ -24,6 +25,7 @@ INSERT IGNORE INTO `sidebar` (`id`, `parent_id`, `roworder`, `label`, `path`, `f (1200, NULL, 1200, 'ORGANISATION', NULL, 'fa-sitemap', 'ROLE_ADMIN,ROLE_MODO', ''), (1210, 1200, 1210, 'Listes Blanche', 'cadoles_core_config_whitelist', 'fa-tasks', 'ROLE_ADMIN,ROLE_MODO', ''), (1220, 1200, 1220, 'Niveau 01', 'cadoles_core_config_niveau01', 'fa-building', 'ROLE_ADMIN,ROLE_MODO', ''), +(1230, 1200, 1230, 'Niveau 02', 'cadoles_core_config_niveau02', 'fa-sitemap', 'ROLE_ADMIN,ROLE_MODO', ''), (1240, 1200, 1240, 'Groupes', 'cadoles_core_config_group', 'fa-users', 'ROLE_ADMIN,ROLE_MODO', ''), (1250, 1200, 1250, 'Inscriptions', 'cadoles_core_config_registration', 'fa-pencil-square-o', 'ROLE_ADMIN,ROLE_MODO', ''), (1260, 1200, 1260, 'Utilisateurs', 'cadoles_core_config_user', 'fa-child', 'ROLE_ADMIN,ROLE_MODO', ''), diff --git a/src/ninegate-1.0/src/Cadoles/CoreBundle/Resources/public/themes/transnum/look.png b/src/ninegate-1.0/src/Cadoles/CoreBundle/Resources/public/themes/transnum/look.png index fbf86b1ea74235e3ebaf5eda5be1c59856db6159..8a2d430c7349e448cb3dce035210887711a01432 100644 GIT binary patch delta 24 gcmaEIgYn4?#tm0ZIk^P5&9xX^xHfLSXWC{40DwmcMgRZ+ delta 24 gcmaEIgYn4?#tm0ZIXNYHcr<5AOn Date: Thu, 17 Oct 2019 13:37:39 +0200 Subject: [PATCH 2/3] essai reco websocket --- .../Resources/views/Chat/client.html.twig | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/views/Chat/client.html.twig b/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/views/Chat/client.html.twig index 3208b15d..d4135296 100644 --- a/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/views/Chat/client.html.twig +++ b/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/views/Chat/client.html.twig @@ -120,7 +120,7 @@ {% endblock %} {% block localjavascript %} - var webSocket; +var webSocket; $(document).ready(function(){ if (CKEDITOR.instances["chat_message"]) CKEDITOR.instances["chat_message"].destroy(); @@ -147,14 +147,25 @@ },500); $(".switch").bootstrapSwitch(); - var dateoptions = {weekday: "long", year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit" }; $("#mymodal-sendmail").removeAttr("tabindex"); + websocket(); + + }); + + function websocket() + { {% if websocket_activate and app.user %} var _WS_URI = "wss://{{ gos_web_socket_server_host }}:{{ gos_web_socket_server_port }}"; - webSocket = WS.connect(_WS_URI); - var timer; + console.log("INI WS"); + webSocket = WS.connect(_WS_URI); + console.log("END INI WS"); + + var dateoptions = {weekday: "long", year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit" }; + var timer; + var session; + webSocket.on("socket/connect", function (session) { // Reinit du tps de tentative de reco $('#modalinfo').modal('hide'); @@ -260,39 +271,50 @@ webSocket.on("socket/disconnect", function(error){ laberror="Disconnected for " + error.reason + " with code " + error.code; + console.log("=== DISCONNECT ==="); console.log(laberror); - $('#modalinfo').modal('show'); + if(error.code==2) { + $('#modalinfo').modal('show'); $('#modalinfotext').html("
Impossible de se connecter au serveur.
Vous avez dépassé le nombre de reconnexion maximum

Veuillez retentez d'ici quelques secondes

"+laberror+"


Forcer la tentative de reconnexion
"); clearInterval(timer); var nbtentative=10; timer=setInterval(function(){ $('#modalinfotimer').html((nbtentative--)+"s") }, 1000); - setTimeout(function(){ location.reload(true); }, 10000); + setTimeout(function(){ websocket(); }, 10000); + //setTimeout(function(){ location.reload(true); }, 10000); } if(error.code==3) { + $('#modalinfo').modal('show'); $('#modalinfotext').html("
Impossible de se connecter au serveur.
Veuillez retentez d'ici quelques secondes

"+laberror+"


Forcer la tentative de reconnexion
"); clearInterval(timer); var nbtentative=10; timer=setInterval(function(){ $('#modalinfotimer').html((nbtentative--)+"s") }, 1000); - setTimeout(function(){ location.reload(true); }, 10000); + setTimeout(function(){ websocket(); }, 10000); + // setTimeout(function(){ location.reload(true); }, 10000); } if(error.code==6 || error.code==5) { + $('#modalinfotext').html("
Impossible de se connecter au serveur.
Vous allez être reconnecté d'ici quelques secondes

"+laberror+"


Forcer la tentative de reconnexion
"); clearInterval(timer); var nbtentative=5; + //session.unsubscribe("websocket/channel/{{groupid}}"); + websocket(); + /* timer=setInterval(function(){ $('#modalinfotimer').html((nbtentative--)+"s") }, 1000); + setTimeout(function(){ websocket(); }, 10000); + */ } }); {% endif %} - }); + } {% endblock %} \ No newline at end of file From 33f0d05fb655303a5a2d3fe07cdf02c54598ebce Mon Sep 17 00:00:00 2001 From: afornerot Date: Fri, 18 Oct 2019 13:56:25 +0200 Subject: [PATCH 3/3] =?UTF-8?q?g=C3=A9rer=20la=20deconnexion=20au=20websoc?= =?UTF-8?q?ket=20(ref=20#23)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ninegate-1.0/app/config/config.yml | 1 + .../Controller/ChatController.php | 43 ++ .../Resources/config/routing.yml | 6 +- .../Resources/views/Chat/client.html.twig | 391 ++++++++++++------ 4 files changed, 318 insertions(+), 123 deletions(-) diff --git a/src/ninegate-1.0/app/config/config.yml b/src/ninegate-1.0/app/config/config.yml index 08147083..d13e70c6 100644 --- a/src/ninegate-1.0/app/config/config.yml +++ b/src/ninegate-1.0/app/config/config.yml @@ -137,6 +137,7 @@ gos_web_socket: server: port: %websocket_port% #The port the socket server will listen on host: %websocket_host% #The host ip to bind to + router: resources: - "@CadolesWebsocketBundle/Resources/config/topic.yml" diff --git a/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Controller/ChatController.php b/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Controller/ChatController.php index c5611688..c4407118 100644 --- a/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Controller/ChatController.php +++ b/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Controller/ChatController.php @@ -105,4 +105,47 @@ class ChatController extends Controller $response->headers->set('Content-Type', 'application/json'); return $response; } + + public function listAction(Request $request) { + // S'assurer que c'est un appel ajax + if (!$request->isXmlHttpRequest()) { + return new JsonResponse(array('message' => 'Interdit'), 400); + } + + $em = $this->getDoctrine()->getManager(); + $id=$request->request->get('id'); + $output=array(); + + // On récupère le groupe + $group=$em->getRepository("CadolesCoreBundle:Group")->find($id); + if(!$group) die(); + + // On récupere le user + $user=$this->getUser(); + if(!$user) die(); + + // On récupère le lien usergroup + $usergroup=$em->getRepository("CadolesCoreBundle:UserGroup")->findOneBy(["group"=>$group,"user"=>$user]); + if(!$usergroup) die(); + + // On récupere les messages + $messages=$em->getRepository("CadolesWebsocketBundle:Message")->findBy(["group"=>$group],["submitdate"=>"DESC"],10); + + foreach($messages as $message) { + $tmp=[]; + $tmp["id"]=$message->getId(); + $tmp["message"]=$message->getTopic(); + $tmp["submitdate"]=$message->getSubmitdate(); + $tmp["userid"]=$message->getUser()->getId(); + $tmp["userlastname"]=$message->getUser()->getLastname(); + $tmp["userfirstname"]=$message->getUser()->getFirstname(); + $tmp["useravatar"]=$message->getUser()->getAvatar(); + + array_push($output,$tmp); + } + + $response = new Response(json_encode($output)); + $response->headers->set('Content-Type', 'application/json'); + return $response; + } } diff --git a/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/config/routing.yml b/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/config/routing.yml index b249936e..800de139 100644 --- a/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/config/routing.yml +++ b/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/config/routing.yml @@ -4,4 +4,8 @@ cadoles_websocket_chat: cadoles_websocket_message_see: path: /user/message/see - defaults: { _controller: CadolesWebsocketBundle:Chat:see } \ No newline at end of file + defaults: { _controller: CadolesWebsocketBundle:Chat:see } + +cadoles_websocket_message_list: + path: /user/message/list + defaults: { _controller: CadolesWebsocketBundle:Chat:list } \ No newline at end of file diff --git a/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/views/Chat/client.html.twig b/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/views/Chat/client.html.twig index d4135296..2f4f1e39 100644 --- a/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/views/Chat/client.html.twig +++ b/src/ninegate-1.0/src/Cadoles/WebsocketBundle/Resources/views/Chat/client.html.twig @@ -115,12 +115,90 @@ {% block localexternalscript %} - {% endblock %} {% block localjavascript %} -var webSocket; + {% if websocket_activate and app.user %} + var WS = (function() + { + var GosSocket = function(uri, sessionConfig){ + this._uri = uri; + this._session = false; + this._listeners = {}; + this.connect(sessionConfig); + }; + + GosSocket.prototype.connect = function (sessionConfig) { + var that = this; + + ab.connect(this._uri, + + //Function on connect + function(session){ + that.fire({type: "socket/connect", data: session }); + }, + + //Function on disconnect / error + function(code, reason){ + that._session = false; + + that.fire({type: "socket/disconnect", data: {code: code, reason: reason}}); + }, + + sessionConfig + ); + }; + + GosSocket.prototype.on = function(type, listener){ + if (typeof this._listeners[type] == "undefined"){ + this._listeners[type] = []; + } + + this._listeners[type].push(listener); + }; + + GosSocket.prototype.fire = function(event){ + if (typeof event == "string"){ + event = { type: event }; + } + if (!event.target){ + event.target = this; + } + + if (!event.type){ //falsy + throw new Error("Event object missing 'type' property."); + } + + if (this._listeners[event.type] instanceof Array){ + var listeners = this._listeners[event.type]; + for (var i=0, len=listeners.length; i < len; i++){ + listeners[i].call(this, event.data); + } + } + }; + + GosSocket.prototype.off = function(type, listener){ + if (this._listeners[type] instanceof Array){ + var listeners = this._listeners[type]; + for (var i=0, len=listeners.length; i < len; i++){ + if (listeners[i] === listener){ + listeners.splice(i, 1); + break; + } + } + } + }; + + return { + connect: function(uri, sessionConfig) + { + return new GosSocket(uri, sessionConfig); + } + } + + })(); + {% endif %} $(document).ready(function(){ if (CKEDITOR.instances["chat_message"]) CKEDITOR.instances["chat_message"].destroy(); @@ -153,26 +231,43 @@ var webSocket; }); - function websocket() - { - {% if websocket_activate and app.user %} + {% if websocket_activate and app.user %} + + var session; + var dateoptions = {weekday: "long", year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit" }; + var timer; + var delayRetry=5000; + var isdeco=false; + var tosend=false; + var tosendmail=false; + var todelete=false; + var idtodelete; + + function websocket() + { var _WS_URI = "wss://{{ gos_web_socket_server_host }}:{{ gos_web_socket_server_port }}"; - - console.log("INI WS"); - webSocket = WS.connect(_WS_URI); - console.log("END INI WS"); + webSocket = WS.connect(_WS_URI,{retryDelay: delayRetry}); - var dateoptions = {weekday: "long", year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit" }; - var timer; - var session; + webSocket.on("socket/connect", function (sess) { + console.log("=== CONNECT ==="); - webSocket.on("socket/connect", function (session) { - // Reinit du tps de tentative de reco - $('#modalinfo').modal('hide'); - clearInterval(timer); + // Sauvegardce de la session + session=sess; //the callback function in "subscribe" is called everytime an event is published in that channel. - session.subscribe("websocket/channel/{{groupid}}", function (uri, payload) { + sess.subscribe("websocket/channel/{{groupid}}", function (uri, payload) { + + // Récupération lastmessage + if(isdeco) recuplastmsg(); + + // Si action en cours + if(tosend) sendbtn(); + if(tosendmail) sendbtnmail(); + if(todelete) delmessage(idtodelete); + + // Il est co + isdeco=false; + if(payload.msg) { html ="
"; html+="
"; @@ -203,118 +298,170 @@ var webSocket; alert(payload.alert); } }); - - $( "#sendbtn" ).click(function() { - var data = CKEDITOR.instances["chat_message"].getData(); - if($("#sendbymail").bootstrapSwitch('state')) { - CKEDITOR.instances["chat_messagemail"].setData(data); - $("#mailsuject").val("{{app.session.get('appname')}} = Notification {{ group.label }}"); - $("#mailto").val(""); - $("#listtoavatar").html(""); - - {% for user in group.users %} - {%if(user.user!=app.user)%} - $("#mailto").val($("#mailto").val()+";{{user.user.email}}"); - $("#listtoavatar").append($("")); - {%endif%} - {% endfor %} - - $('#mymodal-sendmail').modal('show'); - } - else { - if(data) { - event={mykey: "{{userkey}}", type: "add", message: data}; - session.publish("websocket/channel/{{groupid}}", event); - CKEDITOR.instances["chat_message"].setData(''); - - /* Ne plus envoyer d'event compteur on passe par de l'ajax - event={type: "add", group:{{groupid}}}; - parent.parent.counter(event); - */ - } - } - }); - - $( "#sendbtnmail" ).click(function() { - var data = CKEDITOR.instances["chat_messagemail"].getData(); - var subject=$("#mailsuject").val(); - var mailto=$("#mailto").val(); - - if(data&&subject&&mailto) { - event={mykey: "{{userkey}}", type: "add", message: data, mail: "true", to: mailto, subject: subject}; - session.publish("websocket/channel/{{groupid}}", event); - CKEDITOR.instances["chat_message"].setData(''); - - /* Ne plus envoyer d'event compteur on passe par de l'ajax - event={type: "add", group:{{groupid}}}; - parent.parent.counter(event); - */ - - $("#sendbymail").bootstrapSwitch('state',false); - $('#mymodal-sendmail').modal('hide'); - } - else alert("Sujet, corps et destinataire(s) obligatoire"); - }); - - $(document).on('click', '.delmessage', function(){ - id=$(this).data("id"); - event={mykey: "{{userkey}}", type: "del", id: id}; - session.publish("websocket/channel/{{groupid}}", event); - }); - - $(document).on('click', '#listtoavatar img', function(){ - var mail = ";"+$(this).data("mail"); - $("#mailto").val($("#mailto").val().replace(mail, "")); - $(this).remove(); - }); }); webSocket.on("socket/disconnect", function(error){ laberror="Disconnected for " + error.reason + " with code " + error.code; console.log("=== DISCONNECT ==="); console.log(laberror); - - - if(error.code==2) { - $('#modalinfo').modal('show'); - $('#modalinfotext').html("
Impossible de se connecter au serveur.
Vous avez dépassé le nombre de reconnexion maximum

Veuillez retentez d'ici quelques secondes

"+laberror+"


Forcer la tentative de reconnexion
"); - - clearInterval(timer); - var nbtentative=10; - timer=setInterval(function(){ $('#modalinfotimer').html((nbtentative--)+"s") }, 1000); - - setTimeout(function(){ websocket(); }, 10000); - //setTimeout(function(){ location.reload(true); }, 10000); - } - - if(error.code==3) { - $('#modalinfo').modal('show'); - $('#modalinfotext').html("
Impossible de se connecter au serveur.
Veuillez retentez d'ici quelques secondes

"+laberror+"


Forcer la tentative de reconnexion
"); - - clearInterval(timer); - var nbtentative=10; - timer=setInterval(function(){ $('#modalinfotimer').html((nbtentative--)+"s") }, 1000); - - setTimeout(function(){ websocket(); }, 10000); - // setTimeout(function(){ location.reload(true); }, 10000); - } - - if(error.code==6 || error.code==5) { - - $('#modalinfotext').html("
Impossible de se connecter au serveur.
Vous allez être reconnecté d'ici quelques secondes

"+laberror+"


Forcer la tentative de reconnexion
"); - - clearInterval(timer); - var nbtentative=5; - //session.unsubscribe("websocket/channel/{{groupid}}"); - websocket(); - /* - timer=setInterval(function(){ $('#modalinfotimer').html((nbtentative--)+"s") }, 1000); - setTimeout(function(){ websocket(); }, 10000); - */ - } + isdeco=true; }); + } - {% endif %} - } + $( "#sendbtn" ).click(function() { + sendbtn(); + }); + + function sendbtn() { + var data = CKEDITOR.instances["chat_message"].getData(); + if($("#sendbymail").bootstrapSwitch('state')) { + CKEDITOR.instances["chat_messagemail"].setData(data); + $("#mailsuject").val("{{app.session.get('appname')}} = Notification {{ group.label }}"); + $("#mailto").val(""); + $("#listtoavatar").html(""); + + {% for user in group.users %} + {%if(user.user!=app.user)%} + $("#mailto").val($("#mailto").val()+";{{user.user.email}}"); + $("#listtoavatar").append($("")); + {%endif%} + {% endfor %} + + $('#mymodal-sendmail').modal('show'); + } + else { + if(data) { + try { + // Flager que l'envoit c'est fait + tosend=false; + $("#sendbtn").html("Envoyer"); + $("#sendbtn").removeClass("btn-danger"); + $("#sendbtn").css('cursor','auto'); + + // Push envent sur le websocket + event={mykey: "{{userkey}}", type: "add", message: data}; + session.publish("websocket/channel/{{groupid}}", event); + CKEDITOR.instances["chat_message"].setData(''); + } + catch(error) { + // L'envoi ne s'est pas fait + console.log("Retry to send"); + + // On flag le fait de retenter l'envoit à la reconnexion + tosend=true; + + // On signal que l'envoi est en cours sur le bouton + $("#sendbtn").html("Envoi en cours"); + $("#sendbtn").addClass("btn-danger"); + $("#sendbtn").css('cursor','progress'); + } + } + } + } + + $( "#sendbtnmail" ).click(function() { + sendbtnmail(); + }); + + function sendbtnmail() { + var data = CKEDITOR.instances["chat_messagemail"].getData(); + var subject=$("#mailsuject").val(); + var mailto=$("#mailto").val(); + + if(data&&subject&&mailto) { + try { + // Flager que l'envoit c'est fait + tosendmail=false; + $("#sendbtnmail").html("Envoyer"); + $("#sendbtnmail").removeClass("btn-danger"); + $("#sendbtnmail").css('cursor','auto'); + + // Push envent sur le websocket + event={mykey: "{{userkey}}", type: "add", message: data, mail: "true", to: mailto, subject: subject}; + session.publish("websocket/channel/{{groupid}}", event); + CKEDITOR.instances["chat_message"].setData(''); + + // Cacher la popup + $("#sendbymail").bootstrapSwitch('state',false); + $('#mymodal-sendmail').modal('hide'); + } + catch(error) { + // L'envoi ne s'est pas fait + console.log("Retry to send"); + + // On flag le fait de retenter l'envoit à la reconnexion + tosendmail=true; + + // On signal que l'envoi est en cours sur le bouton + $("#sendbtnmail").html("Envoi en cours"); + $("#sendbtnmail").addClass("btn-danger"); + $("#sendbtnmail").css('cursor','progress'); + } + + } + else alert("Sujet, corps et destinataire(s) obligatoire"); + } + + $(document).on('click', '.delmessage', function(){ + delmessage($(this).data("id")); + }); + + function delmessage(id) { + try { + // Flager que l'envoit c'est fait + todelete=false; + idtodelete=null; + + // Push envent sur le websocket + event={mykey: "{{userkey}}", type: "del", id: id}; + session.publish("websocket/channel/{{groupid}}", event); + } + catch(error){ + // Le delete ne s'est pas fait + console.log("Retry to delete"); + + // On flag le fait de retenter l'envoit à la reconnexion + todelete=true; + idtodelete=id; + } + } + + $(document).on('click', '#listtoavatar img', function(){ + var mail = ";"+$(this).data("mail"); + $("#mailto").val($("#mailto").val().replace(mail, "")); + $(this).remove(); + }); + + function recuplastmsg() { + $.ajax({ + method: "POST", + url: "{{ path('cadoles_websocket_message_list') }}", + data: { + "id": {{ groupid }}, + }, + success: function(datas) { + $.each(datas, function(i,data) { + // Le message a-t-il été déposé durant la déconnexion ? + if(!$("#message-"+data.id).length) { + console.log("regen message"); + html ="
"; + html+="
"; + html+="
"; + if(data.userid=={{app.user.id}} || '{{ fgmanager }}'=='1') { + html+=""; + } + html+="
"; + html+="
" + html+="
"+data.userlastname+"
"+new Date(data.submitdate.date).toLocaleDateString("fr-FR", dateoptions)+"
"; + html+="
"+data.message+"
"; + html+="
"; + html+="
"; + $(".mychat").prepend(html); + } + }); + } + }); + } + {% endif %} {% endblock %} \ No newline at end of file