ADD fin de la page admin
authorGreg Burri <greg.burri@gmail.com>
Mon, 19 May 2008 20:21:36 +0000 (20:21 +0000)
committerGreg Burri <greg.burri@gmail.com>
Mon, 19 May 2008 20:21:36 +0000 (20:21 +0000)
MOD petites modifs sur le style du menu (utilisation de ul/li)
ADD possibilité de formatage en ''italic'' et '''bold'''

css/1/euphorik.css
css/1/pageMinichat.css
doc/TODO.txt
doc/protocole3.txt
index.html
js/euphorik.js
js/pageAdmin.js
js/pageMinichat.js
modules/erl/euphorik_bd.erl
modules/erl/euphorik_protocole.erl

index 81f6a77..76e50be 100755 (executable)
@@ -27,17 +27,18 @@ body {
    margin-top: 40px;\r
 }
 
-#menu {
+ul#menu {
        /*
        left: 300px;
        top: 2px;*/
        padding-left: 300px;
        /*position: absolute;*/
-       height: 25px;
+       height: 23px;
        font-size: 11px;
        background-color: #000000;
+       list-style-type:none;
 }
-#menu div {
+#menu li {
        cursor: pointer;        
        z-index: 20;
        float: left;
@@ -45,10 +46,10 @@ body {
        margin-left: 2px;
        background-color: #4f5519;
 }
-#menu div.courante {   
+#menu li.courante {    
        background-color: #818c27;
 }
-#menu div:hover {      
+#menu li:hover {       
        background-color: #818c27
 }
 
index 27a0ef8..bd2a920 100755 (executable)
@@ -1,4 +1,5 @@
 #page.minichat {
+       padding-top: 5px;
    padding-right: 0px;
    padding-left: 0px
 }
index efa6f6a..21e2468 100755 (executable)
@@ -1,7 +1,6 @@
 == TODO ==\r
 \r
-=== v1.0 ===
-\r
+=== v1.0 ===\r
 [80%] Un statut "EK" avec plein de privilège à la con. (avoir une petite étoile à coté de son nick ou le nick d'une certaine couleur)\r
    * Une page "admin" avec :\r
       * Trolls : La liste des trolls proposés. L'admin peut éditer ses propres trolls.\r
@@ -10,7 +9,8 @@
       * Un kick : l'utilisateur (ip) est kické et bannis pour 15 min\r
       * Un ban : l'utilisateur (ip) est kické et bannis pour 3 jours\r
       * Modification de la BD -> ajouter une relation "banned_ip"\r
-* Créer un style common puis adapter les CSS (classic et cold -> web2.0)\r
+* Créer un style common puis adapter les CSS (classic et cold -> web2.0)
+* Faire des infos bulles à la facebook\r
 * Rendre compatible IE 7 (pfff..)\r
 * Mettre un icon (genre sablier ou truc qui tourne à la apple) lorsque le chat se charge (également lors d'un changement de page par exemple)\r
    * Simuler un réseau lent\r
index faa7596..8489e58 100644 (file)
@@ -236,7 +236,7 @@ ou
 indique de mettre à jour la liste d'ips
 s -> c
    {
-      "reply" : "maj_banned_ips"
+      "reply" : "banned_ips_refresh"
    }
 \r
 \r
index 54132c1..c70b03d 100755 (executable)
@@ -21,9 +21,9 @@
       <div id="container">
          <div id="logo"></div>\r
          <div id="info" style="display:none" ><div id="icone"></div><div class="fermer" ></div><div class="message" ></div><div class="boutons"></div></div>
-         <div id="menu">
-            <div class="minichat">chat</div><div class="admin" style="display:none">admin</div><div class="profile"></div><div class="register">register</div><div class="logout">logout</div><div class="about">about</div>\r
-         </div>
+         <ul id="menu">
+            <li class="minichat">chat</li><li class="admin" style="display:none">admin</li><li class="profile"></li><li class="register">register</li><li class="logout">logout</li><li class="about">about</li>\r
+         </ul>
          <!-- form action=""  id="formMenuCss">
             <p>
                <select id="menuCss">
index a19d33e..36a2f06 100755 (executable)
@@ -65,13 +65,16 @@ String.prototype.rtrim = function()
 ///////////////////////////////////////////////////////////////////////////////////////////////////\r
 \r
 /**\r
-  * Cette classe regroupe des fonctions utilitaires (helpers).\r
+  * Cette classe regroupe des fonctions utilitaires (helpers).
+  * @formateur est permet de formater les messages affichés à l'aide de messageDialogue (facultatif)\r
   */
-function Util()
+function Util(formateur)
 {
    $("#info .fermer").click(function(){
       $("#info").slideUp(50) 
    })
+   
+   this.formateur = formateur
 }
 
 var messageType = {informatif: 0, question: 1, erreur: 2}
@@ -82,11 +85,17 @@ var messageType = {informatif: 0, question: 1, erreur: 2}
   * @param type voir 'messageType'. par défaut messageType.informatif\r
   * @param les boutons sous la forme d'un objet ou les clefs sont les labels des boutons\r
   *        et les valeurs les fonctions executées lorsqu'un bouton est activé.
+  * @param formate faut-il formaté le message ? true par défaut
   */
-Util.prototype.messageDialogue = function(message, type, boutons)
+Util.prototype.messageDialogue = function(message, type, boutons, formate)
 {
+   var thisUtil = this
+
    if (type == undefined)
       type = messageType.informatif
+      
+   if (formate == undefined)
+      formate = true
 
    if (this.timeoutMessageDialogue != undefined)
       clearTimeout(this.timeoutMessageDialogue)
@@ -94,7 +103,7 @@ Util.prototype.messageDialogue = function(message, type, boutons)
    var fermer = function(){$("#info").slideUp(100)}
    fermer()   
    
-   $("#info .message").html(message)
+   $("#info .message").html(thisUtil.formateur == undefined || !formate ? message : thisUtil.formateur.traitementComplet(message))
    switch(type)
    {
       case messageType.informatif : $("#info #icone").attr("class", "information"); break
@@ -250,6 +259,11 @@ Pages.prototype.afficherPage = function(nomPage, forcerChargement)
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
+/**
+  * Classe permettant de formater du texte par exemple pour la substitution des liens dans les
+  * message par "[url]".
+  * TODO : améliorer l'efficacité des méthods notamment lié au smiles.
+  */
 function Formateur()
 {
    this.smiles = conf.smiles\r
@@ -289,7 +303,7 @@ Formateur.prototype.getSmilesHTML = function()
   */
 Formateur.prototype.traitementComplet = function(M, pseudo)
 {
-   return this.traiterLiensConv(this.traiterSmiles(this.traiterURL(this.remplacerBalisesHTML(M), pseudo)))
+   return this.traiterLiensConv(this.traiterSmiles(this.traiterURL(this.traiterWikiSyntaxe(this.remplacerBalisesHTML(M)), pseudo)))
 }
 
 /**
@@ -326,7 +340,7 @@ Formateur.prototype.traiterSmiles = function(M)
 
 Formateur.prototype.remplacerBalisesHTML = function(M)
 {
-   return M.replace(/</g, "&lt;").replace(/>/g, "&gt;")
+   return M.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;")
 }
 
 Formateur.prototype.traiterURL = function(M, pseudo)
@@ -343,6 +357,27 @@ Formateur.prototype.traiterURL = function(M, pseudo)
    }
    return M.replace(this.regexUrl, traitementUrl)
 }
+
+/**
+  * Formatage en utilisant un sous-ensemble des règles de mediwiki.
+  * par exemple ''italic'' devient <i>italic</i>
+  */
+Formateur.prototype.traiterWikiSyntaxe = function(M)
+{
+   return M.replace(
+      /'''(.*?)'''/g,
+      function(texte, capture)
+      {
+         return "<b>" + capture + "</b>"
+      }
+   ).replace(
+      /''(.*?)''/g,
+      function(texte, capture)
+      {
+         return "<i>" + capture + "</i>"
+      }
+   )
+}
 \r
 /**\r
   * Renvoie une version courte de l'url.\r
@@ -930,10 +965,10 @@ function initialiserListeStyles(client)
 $(document).ready(
    function()
    {  
-      var util = new Util()
+      var formateur = new Formateur()
+      var util = new Util(formateur)
       var client = new Client(util)
-      var pages = new Pages()
-      var formateur = new Formateur()\r
+      var pages = new Pages()\r
       \r
       // connexion vers le serveur (utilise un cookie qui traine)\r
       client.connexionCookie()
index 9091d6d..cb7f51e 100644 (file)
@@ -8,6 +8,8 @@ function PageAdmin(client, formateur, util)
    this.formateur = formateur
    this.util = util
    
+   this.pageEvent = new PageEvent("admin", this.util)
+   
    this.timeoutIDmajIPs = null
 }
 
@@ -15,7 +17,7 @@ PageAdmin.prototype.contenu = function()
 {
    return '<h1>Trolls</h1>\
    <p>Un troll est un sujet à débat, en général une question.</p>\
-   <p>Chaque semaine un troll est choisit au hasard parmis les trolls proposés et devient le troll de la semaine.</p>\
+   <p>Chaque semaine untrolls troll est choisit au hasard parmis les trolls proposés et devient le troll de la semaine.</p>\
    <form action="" id="nouveauTroll">\
       <p>\
          <input class="troll" name="troll" type="text" maxlength="500" value=""></input>\
@@ -34,7 +36,7 @@ PageAdmin.prototype.charger = function()
    var thisPage = this
    
    this.trolls = new Trolls(this.client, this.util, this.formateur)
-   this.trolls.rafraichirTrolls()
+   this.waitEvent()
    
    this.majIPs()
    
@@ -50,7 +52,7 @@ PageAdmin.prototype.charger = function()
 
 PageAdmin.prototype.decharger = function()
 {
-   this.trolls.pageEvent.stopAttenteCourante()
+   this.pageEvent.stopAttenteCourante()
 }
 
 PageAdmin.prototype.posterTroll = function()
@@ -98,7 +100,6 @@ PageAdmin.prototype.posterTroll = function()
    )
 }
 
-
 /**
   * Met à jour la liste des IP bannies.
   */
@@ -155,11 +156,11 @@ PageAdmin.prototype.majIPs = function()
                   $(".ban").each(
                      function()
                      {
-                        var ip = $(".ip").html()
+                        var ip = $(".ip", this).html()
                         $(".deban", this).click(
                            function()
                            {
-                              thisPageAdmin.util.messageDialogue("Êtes-vous sur de vouloir débannir l'IP " + ip + " ?", messageType.question,
+                              thisPageAdmin.util.messageDialogue("Êtes-vous sur de vouloir débannir l'IP ''" + ip + "'' ?", messageType.question,
                                  {"Oui" : function()
                                     {
                                        thisPageAdmin.deban(ip)
@@ -213,7 +214,8 @@ PageAdmin.prototype.deban = function(ip)
                      thisPageAdmin.util.messageDialogue(data["error_message"])
                      break
                   case "ok" :
-                     thisPageAdmin.majIPs()
+                     // obsolète : plus besoin
+                     /* thisPageAdmin.majIPs() */ 
                      break 
                }
             }
@@ -221,6 +223,36 @@ PageAdmin.prototype.deban = function(ip)
    )
 }
 
+PageAdmin.prototype.waitEvent = function()
+{
+   var thisPageAdmin = this
+         
+   this.pageEvent.waitEvent(
+      function() { return { "last_troll" : thisPageAdmin.trolls.dernierTroll }},
+      function(data)
+      {
+         switch (data["reply"])
+         {
+            case "troll_added" :
+               thisPageAdmin.trolls.ajouterTrollEvent(data)
+               break
+            case "troll_modified" :
+               thisPageAdmin.trolls.modifierTrollEvent(data)
+               break
+            case "troll_deleted" :
+               thisPageAdmin.trolls.supprimerTrollEvent(data)
+               break
+            case "banned_ips_refresh" :
+               thisPageAdmin.majIPs()
+               break
+            case "error" :
+               thisTrolls.util.messageDialogue(data["error_message"])
+               break
+         }
+      }
+   )
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
@@ -240,11 +272,107 @@ function Trolls(client, util, formateur)
    this.util = util
    this.formateur = formateur
    this.dernierTroll = 0
-   this.pageEvent = new PageEvent("admin", this.util)
    
    this.trolls = {}
 }
 
+Trolls.prototype.ajouterTrollEvent = function(data)
+{
+   var thisTrolls = this
+
+   var XHTML = ""
+   for (var i = 0; i < data["trolls"].length; i++)
+   {
+      var troll = new Troll(data["trolls"][i]["content"], data["trolls"][i]["author"])
+      var trollId = data["trolls"][i]["troll_id"]
+      thisTrolls.trolls[trollId] = troll
+   
+      XHTML +=
+         '<div id="troll' + trollId + '" class="troll">' +
+         '<span class="content">' + thisTrolls.formateur.traitementComplet(troll.content, troll.author) + '</span>' +
+         '<span class="author"> - ' + thisTrolls.formateur.traitementComplet(troll.author) + '</span>' +
+         (data["trolls"][i]["author_id"] == thisTrolls.client.id ? '<span class="editTroll">éditer</span><span class="delTroll">Supprimer</span>' : '') +
+         '</div>'
+   }
+   $("#trolls").append(XHTML)
+   $("#trolls .troll").filter(function(){return parseInt($(this).attr("id").substr(5)) > thisTrolls.dernierTroll}).each(
+      function()
+      {
+         var troll = this
+         var id = parseInt($(this).attr("id").substr(5))
+         
+         $("a[@rel*=lightbox]", this).lightBox()
+         
+         $(this).keypress(
+            function(e)
+            {
+               if (e.which == 13) // return
+                  $(".modifier", this).click()
+            }
+         )
+         $(".delTroll", this).click(
+            function()
+            {
+               thisTrolls.util.messageDialogue(
+                  "Êtes-vous sur de vouloir supprimer le troll \"" + thisTrolls.trolls[id].content + "\" ?",
+                  messageType.question,
+                  {
+                     "oui" : function()
+                        {
+                           thisTrolls.supprimer(id)
+                        },
+                     "non" : function(){}
+                  }
+               )
+            }
+         )
+         $(".editTroll", this).click(
+            function()
+            {
+               $("span", troll).css("display", "none")
+               $(troll).append(
+                  '<form><p><input class="content" type="text" size="50" maxlength="500" value="' +
+                  thisTrolls.trolls[id].content +
+                  '"></input><span class="modifier">modifier</span><span class="annuler">annuler</span></p></form>'
+               )
+               $("form input.content").focus()
+               
+               var virerLeFormulaire = function()
+               {
+                  $('form', troll).remove()
+                  $('span', troll).css("display", "inline")
+               }
+               $("span.modifier", troll).click(
+                  function()
+                  {
+                     var content = $("form input.content", troll).val()
+                     virerLeFormulaire()
+                     thisTrolls.modifier(id, content)
+                  }
+               )
+               $("span.annuler", troll).click( virerLeFormulaire )
+               $("form", troll).submit(function(){ return false})
+            }  
+         )
+      }
+   )
+   
+   if (data["trolls"].length > 0)
+      thisTrolls.dernierTroll = data["trolls"][data["trolls"].length - 1]["troll_id"]
+}
+
+Trolls.prototype.modifierTrollEvent = function(data)
+{
+   var thisTrolls = this
+   $("#trolls #troll" + data["troll_id"] + " .content").html(thisTrolls.formateur.traitementComplet(data["content"], thisTrolls.trolls[data["troll_id"]].author))
+   $("#trolls #troll" + data["troll_id"] + " a[@rel*=lightbox]").lightBox()
+   thisTrolls.trolls[data["troll_id"]].content = data["content"]
+}
+
+Trolls.prototype.supprimerTrollEvent = function(data)
+{
+   $("#trolls #troll"+data["troll_id"]).remove()
+}
 
 Trolls.prototype.modifier = function(id, content)
 {
@@ -311,114 +439,3 @@ Trolls.prototype.supprimer = function(id)
       }
    )
 }
-
-Trolls.prototype.rafraichirTrolls = function()
-{
-   var thisTrolls = this
-         
-   this.pageEvent.waitEvent(
-      function() { return { "last_troll" : thisTrolls.dernierTroll }},
-      function(data)
-      {
-         switch (data["reply"])
-         {
-            case "troll_added" :
-               var XHTML = ""
-               for (var i = 0; i < data["trolls"].length; i++)
-               {
-                  var troll = new Troll(data["trolls"][i]["content"], data["trolls"][i]["author"])
-                  var trollId = data["trolls"][i]["troll_id"]
-                  thisTrolls.trolls[trollId] = troll
-               
-                  XHTML +=
-                     '<div id="troll' + trollId + '" class="troll">' +
-                     '<span class="content">' + thisTrolls.formateur.traitementComplet(troll.content, troll.author) + '</span>' +
-                     '<span class="author"> - ' + thisTrolls.formateur.traitementComplet(troll.author) + '</span>' +
-                     (data["trolls"][i]["author_id"] == thisTrolls.client.id ? '<span class="editTroll">éditer</span><span class="delTroll">Supprimer</span>' : '') +
-                     '</div>'
-               }
-               $("#trolls").append(XHTML)
-               $("#trolls .troll").filter(function(){return parseInt($(this).attr("id").substr(5)) > thisTrolls.dernierTroll}).each(
-                  function()
-                  {
-                     var troll = this
-                     var id = parseInt($(this).attr("id").substr(5))
-                     
-                     $("a[@rel*=lightbox]", this).lightBox()
-                     
-                     $(this).keypress(
-                        function(e)
-                        {
-                           if (e.which == 13) // return
-                              $(".modifier", this).click()
-                        }
-                     )
-                     $(".delTroll", this).click(
-                        function()
-                        {
-                           thisTrolls.util.messageDialogue(
-                              "Êtes-vous sur de vouloir supprimer le troll \"" + $("#trolls .troll .content").html() + "\" ?",
-                              messageType.question,
-                              {
-                                 "oui" : function()
-                                    {
-                                       thisTrolls.supprimer(id)
-                                    },
-                                 "non" : function(){}
-                              }
-                           )
-                        }
-                     )
-                     $(".editTroll", this).click(
-                        function()
-                        {
-                           $("span", troll).css("display", "none")
-                           $(troll).append(
-                              '<form><p><input class="content" type="text" size="50" maxlength="500" value="' +
-                              thisTrolls.trolls[id].content +
-                              '"></input><span class="modifier">modifier</span><span class="annuler">annuler</span></p></form>'
-                           )
-                           $("form input.content").focus()
-         
-                           var virerLeFormulaire = function()
-                           {
-                              $("form", troll).remove()
-                              $('span', troll).css("display", "inline")
-                           }
-                           $("span.modifier", troll).click(
-                              function()
-                              {
-                                 var content = $("form input.content", troll).val()
-                                 virerLeFormulaire()
-                                 thisTrolls.modifier(id, content)
-                              }
-                           )
-                           $("span.annuler", troll).click( virerLeFormulaire )
-                           $("form", troll).submit(function(){ return false})
-                        }  
-                     )
-                  }
-               )
-               
-               if (data["trolls"].length > 0)
-                  thisTrolls.dernierTroll = data["trolls"][data["trolls"].length - 1]["troll_id"]
-               break
-            case "troll_modified" :
-               $("#trolls #troll" + data["troll_id"] + " .content").html(thisTrolls.formateur.traitementComplet(data["content"], thisTrolls.trolls[data["troll_id"]].author))
-               $("#trolls #troll" + data["troll_id"] + " a[@rel*=lightbox]").lightBox()
-               thisTrolls.trolls[data["troll_id"]].content = data["content"]
-               break
-            case "troll_deleted" :
-               $("#trolls #troll"+data["troll_id"]).remove()
-               break
-            case "majIPs" :
-               // TODO : mettre l'attente au niveau de la page et pas au niveau des trolls
-               // thisPageAdmin.majIPs()
-               break
-            case "error" :
-               thisTrolls.util.messageDialogue(data["error_message"])
-               break
-         }
-      }
-   )
-}
\ No newline at end of file
index 541c980..e006f3c 100755 (executable)
@@ -514,9 +514,9 @@ Conversation.prototype.flush = function(funClickOuvrirConv)
             "\">" +
                "<div class=\"extraire\">&gt;</div>" +
                "[<span class=\"date\">" + message.date + "</span>]" +
-               "<span class=\"pseudo\"><span class=\"id\" style=\"display: none\">" + message.auteurId + "</span>" + identifiant + "</span>:" +
+               "<span class=\"pseudo\"><span class=\"id\" style=\"display: none\">" + message.auteurId + "</span class=\"ident\">" + identifiant + "</span>:" +
                XHTMLrepondA +
-               "<span class=\"contenu\">" + (message.systeme ? this.formateur.remplacerBalisesHTML(message.contenu) : this.formateur.traitementComplet(message.contenu, message.pseudo)) + "</span>" +
+               "<span class=\"contenu\">" + this.formateur.traitementComplet(message.contenu, message.pseudo) + "</span>" +
             "</div>"
             
          messagePair = !messagePair
@@ -531,7 +531,7 @@ Conversation.prototype.flush = function(funClickOuvrirConv)
       $("#conversations #" + this.getId() + " .message").slice(this.nbMessageMax, nbMessagesAffiche).empty()
 
    // ajoute les événements liés à chaque nouveau message
-   $("#conversations #" + this.getId() + " .message").filter(function(){return parseInt($(this).attr("id").substr(4), 36) > thisConversation.idDernierMessageAffiche}).each(
+   $("#conversations #" + this.getId() + " .message").filter(function(){ return parseInt($(this).attr("id").substr(4), 36) > thisConversation.idDernierMessageAffiche }).each(
       function()
       {
          $(".lienConv", this).click(
@@ -599,7 +599,7 @@ Conversation.prototype.flush = function(funClickOuvrirConv)
             
                var valCourant = $("input.message").val()
                if (valCourant == undefined) valCourant = ""
-               var tag = $(".pseudo", this).text()  + "{" + idMess + "}" + ">"
+               var tag = $(".pseudo span.ident", this).text()  + "{" + idMess + "}" + ">"
                if (valCourant.indexOf(tag, 0) == -1)
                   $("input.message").val(tag + " " + valCourant)
                thisConversation.util.setCaretToEnd($("form input.message")[0])
index be43e59..9de83fb 100755 (executable)
@@ -54,7 +54,6 @@
    % trolls :
    trolls/0,
    trolls/1,
-   trolls_attente/1,
    put_troll/2,
    mod_troll/2,
    del_troll/1,
@@ -388,7 +387,7 @@ nouveau_message(Mess, Auteur_id, Repond_A) ->
             % est-ce que l'auteur à trop floodé ?
             if Auteur#user.indice_flood =/= ?INDICE_SPAM_MAX, Auteur_maj#user.indice_flood =:= ?INDICE_SPAM_MAX, Delta =< ?DUREE_BLOCAGE_SPAM ->
                mnesia:write(Auteur#user{indice_flood = Auteur_maj#user.indice_flood}),
-               nouveau_message_sys(Auteur#user.pseudo ++ if Auteur#user.login =/= [] -> " (" ++ Auteur#user.login ++ ")"; true -> "" end ++ " est bloqué pour " ++ integer_to_list(trunc(?DUREE_BLOCAGE_SPAM / 1000)) ++ " secondes pour cause de flood.");
+               nouveau_message_sys("''" ++ Auteur#user.pseudo ++ if Auteur#user.login =/= [] -> " (" ++ Auteur#user.login ++ ")"; true -> "" end ++ "'' est bloqué pour " ++ integer_to_list(trunc(?DUREE_BLOCAGE_SPAM / 1000)) ++ " secondes pour cause de flood.");
             Auteur#user.indice_flood =:= ?INDICE_SPAM_MAX, Delta =< ?DUREE_BLOCAGE_SPAM ->
                {erreur, "Bloqué pour cause de flood"};
             true ->     
@@ -655,58 +654,11 @@ trolls() ->
 % Renvoie les trolls manquants posté après Last_id.
 trolls(Last_id) ->
    resultat_transaction(mnesia:transaction(
-      e(q([T || T <- qlc:keysort(2, mnesia:table(troll)), T#troll.id > Last_id, T#troll.date_post =:= undefined]))
+      fun() ->
+         e(q([T || T <- qlc:keysort(2, mnesia:table(troll)), T#troll.id > Last_id, T#troll.date_post =:= undefined]))
+      end
    )).
    
-   
-% Renvoie les trolls manquants posté après Last_id.
-% Si pas de trolls alors attend un événement tel qu'un ajout, une modification ou une suppression.
-% renvoie :
-%  {mod, Troll}
-% ou {add, [Trolls]}
-% ou {del, Troll_id}
-% ou timeout
-trolls_attente(Last_id) ->
-   case mnesia:subscribe({table, troll, detailed}) of
-      {error, E} = E ->
-         E;
-      _ ->
-         R = case resultat_transaction(mnesia:transaction(
-               fun() ->
-                  e(q([T || T <- qlc:keysort(2, mnesia:table(troll)), T#troll.id > Last_id, T#troll.date_post =:= undefined]))
-               end
-            )) of
-               [] -> % pas de trolls
-                  attend_evenement_troll();
-               Trolls ->
-                  {add, Trolls}
-         end,
-         mnesia:unsubscribe({table, troll, detailed}),
-         R
-   end.
-   
-attend_evenement_troll() ->
-   % s'il n'y a pas de trolls que l'utilisateur n'a pas connaissance alors on attend un événement
-   receive
-      % cas où un troll est choisit comme courant
-      {mnesia_table_event, {write, troll, Troll, [Old_troll | _], _}} when Old_troll#troll.date_post =:= undefined, Troll#troll.date_post =/= undefined ->
-         {del, Troll#troll.id};
-      {mnesia_table_event, {write, troll, Troll, [_Old_troll | _], _}} ->
-         {mod, Troll};
-      {mnesia_table_event, {write, troll, Troll, [], _}} ->
-         {add, [Troll]};
-      {mnesia_table_event, {delete, troll, {troll, Id}, _, _}} ->
-         {del, Id};
-      {tcp_closed, _} ->
-         exit(normal);
-      _ ->
-         attend_evenement_troll()
-   % 60 minutes de timeout (on ne sais jamais)
-   % Après 60 minutes de connexion, le client doit donc reétablir une connexion
-   after 1000 * 60 * 60 -> 
-      timeout
-   end.
-   
  
  % Renvoie l'id du nouveau troll
  % ou max_troll_reached_per_user si le nombre de troll posté par l'utilisateur max a été atteind
index cfb9df4..8056f6b 100755 (executable)
@@ -153,7 +153,13 @@ wait_event([{page, "chat"} | Data]) ->
          R
    end;
 wait_event([{page, "admin"}, {last_troll, Last_troll}]) ->
-   case euphorik_bd:trolls_attente(Last_troll) of
+   case wait_event_page_admin(Last_troll) of
+      banned_ips_refresh ->
+         {struct, 
+            [
+               {reply, "banned_ips_refresh"}
+            ]
+         };
       {mod, Troll} ->
          {struct,
             [
@@ -280,7 +286,59 @@ wait_event_bd_page_chat() ->
    % Après 60 minutes de connexion, le client doit donc reétablir une connexion
    after 1000 * 60 * 60 -> 
       timeout
-   end.           
+   end.        
+
+
+% Attent un événement concernant la page admin
+% Renvoie les trolls manquants posté après Last_id ou banned_ips_refresh.
+% Si pas de trolls alors attend un événement tel qu'un ajout, une modification ou une suppression.
+% renvoie :
+%  {mod, Troll}
+% ou {add, [Trolls]}
+% ou {del, Troll_id}
+% ou banned_ips_refresh
+% ou timeout
+wait_event_page_admin(Last_id) ->
+   case {mnesia:subscribe({table, troll, detailed}), mnesia:subscribe({table, ip_table, detailed})} of
+      {{error, E}, _ } -> E;
+      {_, {error, E}} -> E;
+      _ ->
+         R = case euphorik_bd:trolls(Last_id) of
+               [] -> % pas de trolls
+                  wait_event_page_admin();
+               Trolls ->
+                  {add, Trolls}
+         end,
+         mnesia:unsubscribe({table, troll, detailed}),
+         mnesia:unsubscribe({table, ip_table, detailed}),
+         R
+   end.
+   
+wait_event_page_admin() ->
+   % s'il n'y a pas de trolls que l'utilisateur n'a pas connaissance alors on attend un événement
+   receive
+      % cas où un troll est choisit comme courant
+      {mnesia_table_event, {write, troll, Troll, [Old_troll | _], _}}
+         when Old_troll#troll.date_post =:= undefined, Troll#troll.date_post =/= undefined ->
+         {del, Troll#troll.id};
+      {mnesia_table_event, {write, troll, Troll, [_Old_troll | _], _}} ->
+         {mod, Troll};
+      {mnesia_table_event, {write, troll, Troll, [], _}} ->
+         {add, [Troll]};
+      {mnesia_table_event, {delete, troll, {troll, Id}, _, _}} ->
+         {del, Id};
+      {mnesia_table_event, {write, ip_table, IP, [Old_IP | _], _}}
+         when Old_IP#ip_table.ban =/= IP#ip_table.ban; Old_IP#ip_table.ban_duration =/= IP#ip_table.ban_duration ->
+         banned_ips_refresh;
+      {tcp_closed, _} ->
+         exit(normal);
+      _ ->
+         wait_event_page_admin()
+   % 60 minutes de timeout (on ne sais jamais)
+   % Après 60 minutes de connexion, le client doit donc reétablir une connexion
+   after 1000 * 60 * 60 -> 
+      timeout
+   end.
          
          
 % Un utilisateur envoie un message
@@ -332,10 +390,10 @@ ban(
                   erreur("Il n'est pas possible de s'auto bannir");
                {ok, User2 = #user{ek_master = false}} ->
                   euphorik_bd:ban(User2#user.last_ip, Duration),
-                  euphorik_bd:nouveau_message_sys(lists:flatten(io_lib:format("~s ~s est ~s pour ~s.~s",
+                  euphorik_bd:nouveau_message_sys(lists:flatten(io_lib:format("''~s~s'' est ~s pour ~s.~s",
                      [
                         User2#user.pseudo,
-                        if User2#user.login =:= [] -> ""; true -> "(" ++ User2#user.login ++ ")" end,
+                        if User2#user.login =:= [] -> ""; true -> " (" ++ User2#user.login ++ ")" end,
                         if Duration =< 15 -> "kické"; true -> "banni" end,
                         format_minutes(Duration),
                         if Reason =/= [] -> " - Raison: " ++ Reason; true -> "" end ++ "."
@@ -544,7 +602,7 @@ format_minutes(Min) ->
    if Minutes == 0 ->
          "";
       true ->
-         integer_to_list(Minutes) ++ " minute"  ++ if Minutes > 1 -> "s"; true -> "" end
+         " " ++ integer_to_list(Minutes) ++ " minute"  ++ if Minutes > 1 -> "s"; true -> "" end
    end.
    
    \r