ADD troll sur la page principale
authorGreg Burri <greg.burri@gmail.com>
Thu, 15 May 2008 21:19:21 +0000 (21:19 +0000)
committerGreg Burri <greg.burri@gmail.com>
Thu, 15 May 2008 21:19:21 +0000 (21:19 +0000)
css/1/euphorik.css
css/1/pageMinichat.css
doc/TODO.txt
doc/protocole3.txt
js/pageAdmin.js
js/pageMinichat.js
modules/erl/euphorik_bd.erl
modules/erl/euphorik_deamon.erl [new file with mode: 0755]
modules/erl/euphorik_minichat_conversation.erl
modules/erl/euphorik_protocole.erl

index c3a4ace..61a755f 100755 (executable)
@@ -14,7 +14,7 @@ body {
    font-family: sans-serif;\r
    font-size: 12px;
    color: #EEEEEE;\r
-   text-align: center; /* uniquement pour IE */\r
+   /*text-align: center;*/ /* uniquement pour IE */\r
    background-color: #DFDFDF;\r
    background-image: url(../../img/css1/fond.png)\r
 }\r
@@ -34,7 +34,6 @@ body {
        left: 300px;
        font-size: 11px;
        background-color: #000000;
-       text-align: left;
 }
 #menu div {    
        cursor: pointer;        
@@ -62,7 +61,6 @@ body {
    position: relative;
    font-size: 12px;
    background-color: #000000;
-   text-align : left;
    padding: 30px 10px 15px 10px;
 }
 
@@ -124,7 +122,8 @@ body {
        border-style: none;\r
 }\r
 \r
-div#info {\r
+div#info {
+       text-align: center;\r
        width:100%;\r
        position: fixed;\r
        left: 0px;\r
index a753ba5..f4e1e5a 100755 (executable)
@@ -1,6 +1,5 @@
 #page.minichat {
    padding: 25px 0px 15px 0px;
-   text-align: center
 }
 
 #page.minichat img {
        margin-left: 1px
 }
 
+#page.minichat #trollCourant {
+       border-top: 1px solid;
+       border-bottom: 1px solid;
+       border-color: #253f18;
+       background-color: #0c2003;
+       margin-top: 4px;
+       margin-bottom: 8px;
+       padding : 1px 0px 1px 10px
+}
+
+#page.minichat #trollCourant .troll {
+       font-style: italic;
+       color: #FFFF88
+}
+
 #page.minichat .titreSmiles:hover {
        background-color: #2d8800;
 }
 
 #page.minichat form {
-   text-align: left;
    margin-bottom: 15px;
    padding-left: 10px;
 }
        border-left-width: 5px;
        border-left-style: solid;
        border-color: transparent;
-       text-align: left;
        padding-right: 5px;
        padding-left: 4px;
        cursor: pointer;
 }
 
 #page.minichat #conversations .titre {
+       text-align: center;
        padding-right: 8px;
        background-color: #4b4215
 }
index da163ae..9cd64c8 100755 (executable)
@@ -2,7 +2,10 @@
 \r
 === v1.0 ===
 
-* Est-ce que client.dernierMessageErreur est vraiment utile ??\r
+* Est-ce que client.dernierMessageErreur est vraiment utile ??
+* Problème des images dans les trolls
+* Finir l'édition (mémoriser le contenu) des trolls
+* marquer <aucun login> lors de l'affichage des login dans le chat pour les personnes n'en ayant pas\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
index 8c383c7..2646a4b 100644 (file)
@@ -156,7 +156,7 @@ La premi
 L'ordre des conversation est le même que celui des données de l'utilisateur.\r
 Le format de la date n'est pas formel.\r
    {\r
-      "reply" : "new_messages",\r
+      "reply" : "new_message",\r
       "conversations" : [\r
          {\r
             "last_page" : true | false,\r
index 4c34f58..fd1ddd4 100644 (file)
@@ -208,12 +208,14 @@ Trolls.prototype.rafraichirTrolls = function()
                         {
                            $("span", troll).css("display", "none")
                            $(troll).append(
-                              '<form><p><input class="content" type="text" size="50" maxlength="500" value="' + $(".content", troll).html() + '"></input><span class="modifier">modifier</span><span class="annuler">annuler</span></p></form>'
+                              '<form><p><input class="content" type="text" size="50" maxlength="500" value="' +
+                              $(".contentPasFormate", troll).html() +
+                              '"></input><span class="modifier">modifier</span><span class="annuler">annuler</span></p></form>'
                            )
                            var virerLeFormulaire = function()
                            {
                               $("form", troll).remove()
-                              $("span", troll).css("display", "inline")
+                              $('span', troll).css("display", "inline")
                            }
                            $("span.modifier", troll).click(
                               function()
@@ -234,7 +236,8 @@ Trolls.prototype.rafraichirTrolls = function()
                   thisTrolls.dernierTroll = data["trolls"][data["trolls"].length - 1]["troll_id"]
                break
             case "troll_modified" :
-               $("#trolls #troll" + data["troll_id"] + " .content").html(data["content"])
+               $("#trolls #troll" + data["troll_id"] + " .content").html(thisTrolls.formateur.traitementComplet(data["content"], $("#trolls #troll" + data["troll_id"] + " .author").html()))
+               $("#trolls #troll" + data["troll_id"] + " .contentPasFormat").html(data["content"])
                break
             case "troll_deleted" :
                $("#trolls #troll"+data["troll_id"]).remove()
index ed0321c..1f6a118 100755 (executable)
@@ -15,6 +15,7 @@ function PageMinichat(client, formateur, util)
 PageMinichat.prototype.contenu = function()
 {
    return '\
+<div id="trollCourant">Troll de la semaine : <span class="troll"></span></div>\
 <form method="post" action="">\
    <p>\
       <input class="captcha" name="captcha" type="text" size="8" maxlength="8"></input>\
@@ -671,6 +672,8 @@ function Messages(client, formateur, util)
    this.conversations = new Array() // les conversations, la première représente la conversation principale
    this.nouvelleConversation(0)
    
+   this.trollIdCourant = 0
+   
    this.pageEvent = new PageEvent("chat", this.util)
 }
 
@@ -682,10 +685,11 @@ Messages.prototype.getJSONrafraichirMessages = function()
    var mess =  {
       "message_count" : conf.nbMessageAffiche,
       "main_page" : this.client.pagePrincipale,
-      "conversations" : this.getJSONConversations()
+      "conversations" : this.getJSONConversations(),
+      "troll_id" : this.trollIdCourant
    }
    
-   if (this.client.cookie != null) mess["cookie"] = this.client.cookie;
+   if (this.client.cookie != null) mess["cookie"] = this.client.cookie
    mess["last_message_id"] = this.conversations[0].idDernierMessageAffiche
    
    return mess
@@ -894,21 +898,32 @@ Messages.prototype.rafraichirMessages = function(vider)
       function() { return thisMessages.getJSONrafraichirMessages() },
       function(data)
       {
-            if (vider)
-            {
-               thisMessages.viderMessages()
-               vider = false
-            }
-            
-            // ajoute les messages reçus à leur conversation respective
-            for (var numConv = 0; numConv < data["conversations"].length; numConv++)
-            {
-               if (! thisMessages.ajouterMessages(data["conversations"][numConv], numConv))
+         if (vider)
+         {
+            thisMessages.viderMessages()
+            vider = false
+         }
+               
+         // en fonction du message
+         switch(data["reply"])
+         {
+            case "new_troll" :
+               thisMessages.trollIdCourant = data["troll_id"]
+               $("#trollCourant .troll").html(thisMessages.formateur.traitementComplet(data["content"]))
+               break
+               
+            case "new_messages" :                        
+               // ajoute les messages reçus à leur conversation respective
+               for (var numConv = 0; numConv < data["conversations"].length; numConv++)
                {
-                  thisMessages.util.messageDialogue("La conversation {" + thisMessages.client.conversations[numConv -1].root.toString(36) + "} n'existe pas")
-                  thisMessages.client.supprimerConversation(numConv - 1) 
+                  if (! thisMessages.ajouterMessages(data["conversations"][numConv], numConv))
+                  {
+                     thisMessages.util.messageDialogue("La conversation {" + thisMessages.client.conversations[numConv -1].root.toString(36) + "} n'existe pas")
+                     thisMessages.client.supprimerConversation(numConv - 1) 
+                  }
                }
-            }
+               break
+         }
       }
    )
 }
index e10ef2a..d354c21 100755 (executable)
    % trolls :
    trolls/0,
    trolls/1,
+   trolls_attente/1,
    put_troll/2,
    mod_troll/2,
    del_troll/1,
    troll_by_id/1,
+   current_troll/0,
+   elire_troll/0,
    
    % versions :
    update_version/1,
    
    % utiles :
    resultat_transaction/1\r
-]).\r
+]).
+
+-import(qlc, [e/1, e/2, q/1, cursor/1]).\r
 \r
 -include("../include/euphorik_bd.hrl").
 -include("../include/euphorik_defines.hrl").\r
@@ -239,7 +244,7 @@ update_pseudo_user(UserId, Pseudo) ->
 % Renvoie tous les users.
 users() ->
    resultat_transaction(mnesia:transaction(fun() ->
-      qlc:e(qlc:q([E || E <- mnesia:table(user)]))
+      e(q([E || E <- mnesia:table(user)]))
    end)).   
    
 
@@ -248,7 +253,7 @@ users() ->
 user_by_cookie(Cookie) ->
    resultat_transaction(mnesia:transaction(
       fun() ->
-         case qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.cookie =:= Cookie])) of
+         case e(q([E || E <- mnesia:table(user), E#user.cookie =:= Cookie])) of
             [User] -> {ok, User};
             _ -> erreur
          end
@@ -259,7 +264,7 @@ user_by_cookie(Cookie) ->
 user_by_id(ID) ->
    resultat_transaction(mnesia:transaction(
       fun() ->
-         case qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.id =:= ID])) of
+         case e(q([E || E <- mnesia:table(user), E#user.id =:= ID])) of
             [User] -> {ok, User};
             _ -> erreur
          end
@@ -270,7 +275,7 @@ user_by_id(ID) ->
 user_by_login(Login) ->\r
    resultat_transaction(mnesia:transaction(\r
       fun() ->\r
-         Users = qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.login =:= Login])),\r
+         Users = e(q([E || E <- mnesia:table(user), E#user.login =:= Login])),\r
          case Users of\r
             [User] -> {ok, User};\r
             _ -> erreur\r
@@ -282,7 +287,7 @@ user_by_login(Login) ->
 toggle_ek_master(User_id) ->
    resultat_transaction(mnesia:transaction(
       fun() ->
-         Users = qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.id =:= User_id])),
+         Users = e(q([E || E <- mnesia:table(user), E#user.id =:= User_id])),
          case Users of
             [User] ->
                mnesia:write(User#user{ek_master = not User#user.ek_master});
@@ -295,7 +300,7 @@ toggle_ek_master(User_id) ->
 user_by_login_password(Login, Password) ->
    resultat_transaction(mnesia:transaction(
       fun() ->
-         case qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.login =:= Login, E#user.password =:= Password])) of
+         case e(q([E || E <- mnesia:table(user), E#user.login =:= Login, E#user.password =:= Password])) of
             [User | _] -> {ok, User};
             _ -> erreur
          end
@@ -307,7 +312,7 @@ user_by_login_password(Login, Password) ->
 user_by_mess(Id) ->
    resultat_transaction(mnesia:transaction(
       fun() ->
-         case qlc:e(qlc:q([U || U <- mnesia:table(user), M <- mnesia:table(minichat), M#minichat.id =:= Id, M#minichat.auteur_id =:= U#user.id])) of
+         case e(q([U || U <- mnesia:table(user), M <- mnesia:table(minichat), M#minichat.id =:= Id, M#minichat.auteur_id =:= U#user.id])) of
             [User | _] -> {ok, User};
             _ -> erreur
          end
@@ -320,9 +325,9 @@ user_by_mess(Id) ->
 nouveau_message(Mess, Auteur_id, Repond_A) ->
    % regarde si les id 'Repond_A' existent
    F = fun() ->   
-      Nb_id_trouve = length(qlc:e(qlc:q([E#minichat.id || E <- mnesia:table(minichat), lists:member(E#minichat.id, Repond_A)]))),
+      Nb_id_trouve = length(e(q([E#minichat.id || E <- mnesia:table(minichat), lists:member(E#minichat.id, Repond_A)]))),
       % est-ce que l'auteur existe ?
-      Auteur = case qlc:e(qlc:q([E || E <- mnesia:table(user), E#user.id =:= Auteur_id])) of
+      Auteur = case e(q([E || E <- mnesia:table(user), E#user.id =:= Auteur_id])) of
          [A] -> A;
          _ -> throw("L'auteur du message est introuvable")
       end,
@@ -380,7 +385,7 @@ messages(N) ->
 % Renvoie N messages se trouvant sur la page P
 messages(N, P) ->  
    F = fun() ->
-      C = qlc:cursor(qlc:q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, descending}])])),
+      C = cursor(q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, descending}])])),
       if P > 1 -> qlc:next_answers(C, N * (P - 1));
          true -> ok
       end,
@@ -401,7 +406,7 @@ messages(Id, N, P) ->
 message_by_id(Id) ->
    case resultat_transaction(mnesia:transaction(
       fun() ->
-         qlc:e(qlc:q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, ascending}]), Id =:= E#minichat.id]))
+         e(q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, ascending}]), Id =:= E#minichat.id]))
       end
    )) of
       [M] -> {ok, M};
@@ -414,8 +419,8 @@ messages_by_ids(Ids) ->
    resultat_transaction(mnesia:transaction(
       fun() ->
          % TODO : optimisations ? serait-ce du O(n) ?
-         Query = qlc:q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, ascending}]), lists:any(fun(Id) -> Id =:= E#minichat.id end, Ids)]),
-         qlc:e(Query)
+         Query = q([E || E <- qlc:keysort(2, mnesia:table(minichat), [{order, ascending}]), lists:any(fun(Id) -> Id =:= E#minichat.id end, Ids)]),
+         e(Query)
       end
    )).
    
@@ -424,14 +429,14 @@ messages_by_ids(Ids) ->
 % TODO : ya pas plus simple ?
 message_existe(Id) ->
    resultat_transaction(mnesia:transaction(fun() ->
-      length(qlc:e(qlc:q([E#minichat.id || E <- mnesia:table(minichat), E#minichat.id =:= Id]))) =:= 1
+      length(e(q([E#minichat.id || E <- mnesia:table(minichat), E#minichat.id =:= Id]))) =:= 1
    end)).
    
    
 % Renvoie les reponses (utilisé normalement uniquement pendant le debug).
 reponses() ->
    F = fun() ->
-      qlc:e(qlc:q([E || E <- mnesia:table(reponse_minichat)]))
+      e(q([E || E <- mnesia:table(reponse_minichat)]))
    end,
    resultat_transaction(mnesia:transaction(F)).
    
@@ -440,7 +445,7 @@ reponses() ->
 repond_a(M_id) ->
    resultat_transaction(mnesia:transaction(
       fun() ->
-         qlc:e(qlc:q(
+         e(q(
             [M || E <- mnesia:table(reponse_minichat),
             M <- mnesia:table(minichat),
             E#reponse_minichat.repondant =:= M_id,
@@ -453,7 +458,7 @@ repond_a(M_id) ->
 est_une_reponse_a_user(Id_user, Id_mess) ->
    case mnesia:transaction(
             fun() ->
-               qlc:e(qlc:q([
+               e(q([
                   M#minichat.auteur_id || M <- mnesia:table(minichat), R <- mnesia:table(reponse_minichat),
                   M#minichat.auteur_id =:= Id_user, M#minichat.id =:= R#reponse_minichat.cible, R#reponse_minichat.repondant =:= Id_mess
                ]), [{unique_all, true}])
@@ -468,7 +473,7 @@ est_une_reponse_a_user(Id_user, Id_mess) ->
 a_repondu_a_message(Id_user, Id_mess) ->
    case mnesia:transaction(
             fun() ->
-               qlc:e(qlc:q([
+               e(q([
                   M#minichat.auteur_id || M <- mnesia:table(minichat), R <- mnesia:table(reponse_minichat),
                   R#reponse_minichat.cible =:= Id_mess, R#reponse_minichat.repondant =:= M#minichat.id, M#minichat.auteur_id =:= Id_user
                ]), [{unique_all, true}])
@@ -483,7 +488,7 @@ a_repondu_a_message(Id_user, Id_mess) ->
 possede_message(Id_user, Id_mess) ->
    case mnesia:transaction(
             fun() ->
-               qlc:e(qlc:q([E#minichat.auteur_id || E <- mnesia:table(minichat), E#minichat.id =:= Id_mess]))
+               e(q([E#minichat.auteur_id || E <- mnesia:table(minichat), E#minichat.id =:= Id_mess]))
             end
          ) of
       {atomic, [Id_user | []]} -> true;
@@ -494,7 +499,7 @@ possede_message(Id_user, Id_mess) ->
 ip_table() ->
    resultat_transaction(mnesia:transaction(
       fun() ->
-         qlc:e(qlc:q([IP || IP <- mnesia:table(ip_table)]))
+         e(q([IP || IP <- mnesia:table(ip_table)]))
       end
    )).
 
@@ -523,7 +528,7 @@ deban(IP) ->
 est_banni(User_id) ->
    resultat_transaction(mnesia:transaction(
       fun() ->
-         case qlc:e(qlc:q([
+         case e(q([
             {IP#ip_table.ban, IP#ip_table.ban_duration} ||
             U <- mnesia:table(user),
             U#user.id =:= User_id,
@@ -560,7 +565,7 @@ date_plus_minutes(Ban, Ban_duration) ->
 can_register(IP) ->
    resultat_transaction(mnesia:transaction(
       fun() ->
-         case qlc:e(qlc:q([I || I <- mnesia:table(ip_table), I#ip_table.ip =:= IP])) of
+         case e(q([I || I <- mnesia:table(ip_table), I#ip_table.ip =:= IP])) of
             [] -> 
                mnesia:write(#ip_table{ip = IP, date_last_try_register = now()}),
                true;
@@ -585,10 +590,18 @@ can_register(IP) ->
 trolls() ->
    resultat_transaction(mnesia:transaction(
       fun() ->
-         qlc:e(qlc:q([T || T <- qlc:keysort(2, mnesia:table(troll))]))
+         e(q([T || T <- qlc:keysort(2, mnesia:table(troll))]))
       end
    )).
    
+   
+% 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]))
+   )).
+   
+   
 % 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 :
@@ -596,26 +609,31 @@ trolls() ->
 % ou {add, [Trolls]}
 % ou {del, Troll_id}
 % ou timeout
-trolls(Last_id) ->
+trolls_attente(Last_id) ->
    case mnesia:subscribe({table, troll, detailed}) of
       {error, E} = E ->
          E;
       _ ->
-         case resultat_transaction(mnesia:transaction(
+         R = case resultat_transaction(mnesia:transaction(
                fun() ->
-                  qlc:e(qlc:q([T || T <- qlc:keysort(2, mnesia:table(troll)), T#troll.id > Last_id, T#troll.date_post =:= undefined]))
+                  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
+         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, [], _}} ->
@@ -637,14 +655,14 @@ put_troll(User_id, Content) ->
    resultat_transaction(mnesia:transaction(
       fun() ->
          % control le nombre de troll déjà posté
-         Nb_troll_poste_par_user = length(qlc:e(qlc:q(
+         Nb_troll_poste_par_user = length(e(q(
             [
                E#troll.id || E <- mnesia:table(troll),
                E#troll.id_user =:= User_id,
                E#troll.date_post =:= undefined
             ]
          ))),
-         Nb_troll_poste_total = length(qlc:e(qlc:q(
+         Nb_troll_poste_total = length(e(q(
             [
                E#troll.id || E <- mnesia:table(troll),
                E#troll.date_post =:= undefined
@@ -699,7 +717,7 @@ del_troll(Troll_id) ->
 troll_by_id(Troll_id) ->
    resultat_transaction(mnesia:transaction(
       fun() ->
-         case qlc:e(qlc:q([T || T <- mnesia:table(troll), T#troll.id =:= Troll_id])) of
+         case e(q([T || T <- mnesia:table(troll), T#troll.id =:= Troll_id])) of
             [T] -> {ok, T};
             _ ->
                erreur
@@ -707,6 +725,44 @@ troll_by_id(Troll_id) ->
       end
    )).
    
+
+% Renvoie le troll actuel qui se trouve sur la page principale.
+% Renvois aucun si pas de troll courant.
+current_troll() ->
+   resultat_transaction(mnesia:transaction(
+      fun() ->
+         % TODO : ya pas moyen de désigner le champs plutot qu'avec un nombre pour le tri ?
+         C = cursor(q([T || T <- qlc:keysort(5, mnesia:table(troll), [{order, descending}]), T#troll.date_post =/= undefined])),
+         R = case qlc:next_answers(C, 1) of
+            [T] -> T;
+            _ -> aucun
+         end,
+         qlc:delete_cursor(C),
+         R
+      end
+   )).
+
+
+% Elit un troll au hasard parmis les trolls en attente (leur date_post =:= undefined)
+% met à jour sa date de post.
+% renvoie plus_de_trolls si il n'y a aucun troll en attente.
+elire_troll() ->       
+   {A1,A2,A3} = now(),
+   random:seed(A1, A2, A3),
+   mnesia:transaction(
+      fun() ->
+         case e(q([T || T <- mnesia:table(troll), T#troll.date_post =:= undefined])) of
+            [] ->
+               plus_de_trolls;
+            Trolls ->
+               Troll = lists:nth(random:uniform(length(Trolls)), Trolls),
+               Troll2 = Troll#troll{date_post = now()},
+               mnesia:write(Troll2)
+         end
+      end
+   ).
+   
+   
    
 update_version(1) ->
    mnesia:transform_table(
diff --git a/modules/erl/euphorik_deamon.erl b/modules/erl/euphorik_deamon.erl
new file mode 100755 (executable)
index 0000000..0689203
--- /dev/null
@@ -0,0 +1,22 @@
+% Module tournant en background s'occupant periodiquement de certaines tâches.\r
+% Auteur : G.Burri\r
+% Date : 05.11.2007\r
+\r
+-module(euphorik_deamon).
+-export([start/1]).
+
+-include("../include/euphorik_defines.hrl").\r
+
+
+% Démarre le démon
+start(A) ->\r
+   loop(A).
+
+\r
+loop(A) ->
+   euphorik_bd:elire_troll(),\r
+   timer:sleep(1000),\r
+   loop(A).
+\r
+
+
index d5f486f..0ce113c 100755 (executable)
 % Chaque conversation est un tuple {[{Message, Parents}], Plus} où
 % Message est le message de type #minichat et Parents une liste d'Id.
 % Plus est un bool. Si Plus vaut true alors il y a encore des messages.
-% Si il n'y a pas de nouveaux message alors la fonction est bloquante et attend un nouveau message.
+% Si il n'y a pas de nouveaux message alors vide est renvoyé.
 % @spec conversations([{integer(), integer(), integer()}], integer(), integer(), integer()) -> [Conversation()]
 conversations(Racines, N, D, P) ->
-   % écoute des nouveaux messages
-   case mnesia:subscribe({table, minichat, simple}) of
-      {error, E} = E ->
-         E;
-      _ ->
-         % demande des conversations
-         Conversations = conversations_detailees(Racines, N, D, P),
-         % si les conversations sont vides alors on attend un nouveau message
-         Vide = not any(
-            fun(C) ->
-               case C of
-                  {[], _} -> false;
-                  {_, [], _, _} -> false;
-                  _ -> true
-               end
-            end,
-            Conversations
-         ),
-         Conversations_mises_en_forme = mise_en_forme_conversations(
-            if Vide ->
-               attend_nouveau_message(),
-               conversations_detailees(Racines, N, D, P);
-            true ->
-               Conversations
+      Conversations = conversations_detailees(Racines, N, D, P),
+      % si les conversations sont vides alors on attend un nouveau message
+      Vide = not any(
+         fun(C) ->
+            case C of
+               {[], _} -> false;
+               {_, [], _, _} -> false;
+               _ -> true
             end
-         ),
-         mnesia:unsubscribe({table, minichat, simple}),
-         Conversations_mises_en_forme
-   end.
+         end,
+         Conversations
+      ),
+      if Vide ->
+            vide;
+         true ->
+            mise_en_forme_conversations(Conversations)
+      end.
    
    
 % Ecoute les événements de modification d'une table.
@@ -86,22 +74,23 @@ conversations(Racines, N, D, P) ->
  
 % Attend qu'un nouveau message arrive, function bloquante.
 % Renvoie le nouveau message.
+% Obsolète
 % @spec attend_nouveau_message() -> #minichat | timeout
-attend_nouveau_message() ->
-   receive % attente d'un post
-      {mnesia_table_event, {write, Message, _}} ->
-         Message;
-         %file:close(F);
+%~ attend_nouveau_message() ->
+   %~ receive % attente d'un post
+      %~ {mnesia_table_event, {write, Message, _}} ->
+         %~ Message;
+         %~ %file:close(F);
       %~ {tcp_closed, _} ->
          %~ mnesia:unsubscribe({table, minichat, simple});      
-      _ ->
-         attend_nouveau_message()
+      %~ _ ->
+         %~ attend_nouveau_message()
    % 60 minutes de timeout (le cas ou il n'y a que des consultations et jamais de post)
    % Après 60 minutes de connexion, le client doit donc reétablir une connexion
    % TODO : pour être mieux : quand le socket se ferme alors un message devrait être envoyé et débloquer ce receive (demande en cours sur la mailing list de yaws)
-   after 1000 * 60 * 60 -> 
-      timeout
-   end.   
+   %~ after 1000 * 60 * 60 -> 
+      %~ timeout
+   %~ end.   
      
 
 % Mise en forme des conversations pour l'utilisateur du module.
index fcce9c3..cdd0f6b 100755 (executable)
@@ -66,10 +66,9 @@ loginUser({ok, User}, IP) ->
    euphorik_bd:update_date_derniere_connexion(User#user.id),
    json_reponse_login_ok(User);
 loginUser(_, _) ->
-   % ajoute un délais d'attente (TODO : un autre moyen plus élégant ?)
-   receive after 1000 ->
-      erreur("Erreur login")
-   end.
+   % ajoute un délais d'attente
+   timer:sleep(1000),
+   erreur("Erreur login").
    
    \r
 % Renvoie un string() représentant un cookie en base 36. Il y a 10^32 possibillités.\r
@@ -124,12 +123,14 @@ profile(
 % Renvoie les messages appropriés.
 % last_message id et cookie sont facultatifs
 wait_event([{page, "chat"} | Data]) ->
+   % traitement des inputs
    Cookie = case lists:keysearch(cookie, 1, Data) of {value, {_, C}} -> C; _ -> inconnu end,
    Last_message_id = case lists:keysearch(last_message_id, 1, Data) of {value, {_, Id}} -> Id; _ -> 0 end,
    {value, {_, Message_count}} = lists:keysearch(message_count, 1, Data),
    Main_page = case lists:keysearch(main_page, 1, Data) of {value, {_, P}} -> P; _ -> 1 end,
+   Troll_id = case lists:keysearch(troll_id, 1, Data) of {value, {_, T}} -> T; _ -> 0 end,
    {value, {_, {array, Conversations_json}}} = lists:keysearch(conversations, 1, Data),
-   Conversations = lists:map(
+   Racines_conversations = lists:map(
       fun({struct, [{root, Racine}, {page, Page} | Reste]}) ->
          Last_mess_conv  = case Reste of [{last_message_id, L}] -> L; _ -> 0 end,
          {Racine, Page, Last_mess_conv}
@@ -139,60 +140,19 @@ wait_event([{page, "chat"} | Data]) ->
    User = case euphorik_bd:user_by_cookie(Cookie) of\r
       {ok, U} -> U;\r
       _ -> inconnu\r
-   end,\r
-   {struct, [\r
-      {reply, "new_message"},\r
-      {conversations, {array,
-         % accrochez-vous ca va siouxer ;)
-         lists:map(
-            fun({Conv, Plus}) ->
-               {struct, [
-                  {last_page, not Plus},
-                  {messages, {array, 
-                     lists:map(
-                        fun({Mess, Repond_a}) ->                                 
-                           Est_proprietaire = User =/= inconnu andalso User#user.id =:= Mess#minichat.auteur_id,
-                           A_repondu_a_message = User =/= inconnu andalso euphorik_bd:a_repondu_a_message(User#user.id, Mess#minichat.id),
-                           Est_une_reponse_a_user = User =/= inconnu andalso euphorik_bd:est_une_reponse_a_user(User#user.id, Mess#minichat.id),
-                           {ok, User_mess } = euphorik_bd:user_by_id(Mess#minichat.auteur_id),
-                           {struct, [
-                              {id, Mess#minichat.id},
-                              {user_id, User_mess#user.id},
-                              {date, format_date(Mess#minichat.date)},
-                              {system, Mess#minichat.auteur_id =:= 0},
-                              {owner, Est_proprietaire},
-                              {answered, A_repondu_a_message},
-                              {is_a_reply, Est_une_reponse_a_user},
-                              {nick, Mess#minichat.pseudo},
-                              {login, User_mess#user.login},
-                              {content, Mess#minichat.contenu},
-                              {answer_to, {array, lists:map(
-                                 fun(Id_mess) ->                   
-                                    {ok, M} = euphorik_bd:message_by_id(Id_mess),
-                                    {ok, User_reponse} = euphorik_bd:user_by_mess(M#minichat.id),
-                                    {struct, [{id, M#minichat.id}, {nick, M#minichat.pseudo}, {login, User_reponse#user.login}]}
-                                 end,
-                                 Repond_a
-                              )}},
-                              {ek_master, User_mess#user.ek_master}
-                           ]}
-                        end,
-                        Conv
-                     )
-                  }}
-               ]}
-            end,
-            euphorik_minichat_conversation:conversations(
-               Conversations,
-               Message_count,
-               Last_message_id,
-               Main_page
-            )
-         )\r
-      }}\r
-   ]};
+   end,
+   case {mnesia:subscribe({table, minichat, detailed}), mnesia:subscribe({table, troll, detailed})} of
+      {{error, E}, _} -> E;
+      {_, {error, E}} -> E;
+      _ ->
+         % attente d'événements
+         R = wait_event_page_chat(User, Racines_conversations, Message_count, Last_message_id, Main_page, Troll_id),
+         mnesia:unsubscribe({table, minichat, detailed}),
+         mnesia:unsubscribe({table, troll, detailed}),
+         R
+   end;
 wait_event([{page, "admin"}, {last_troll, Last_troll}]) ->
-   case euphorik_bd:trolls(Last_troll) of
+   case euphorik_bd:trolls_attente(Last_troll) of
       {mod, Troll} ->
          {struct,
             [
@@ -235,7 +195,91 @@ wait_event([{page, "admin"}, {last_troll, Last_troll}]) ->
    end;
 wait_event(_) ->
    erreur("Page inconnue").
-            
+
+
+wait_event_page_chat(User, Racines_conversations, Message_count, Last_message_id, Main_page, Troll_id) ->
+   % est-ce qu'il y a des nouveaux messages ?
+   case euphorik_minichat_conversation:conversations(Racines_conversations, Message_count, Last_message_id, Main_page) of
+      vide ->
+         % est-ce que le troll est à jour ?
+         case euphorik_bd:current_troll() of
+            Current when is_record(Current, troll), Current#troll.id =/= Troll_id ->
+               {struct, [
+                  {reply, "new_troll"},
+                  {troll_id, Current#troll.id},
+                  {content, Current#troll.content}
+               ]};
+            _ ->
+               wait_event_bd_page_chat(),
+               % TODO : l'appel est-il bien tail-recursive  ?
+               wait_event_page_chat(User, Racines_conversations, Message_count, Last_message_id, Main_page, Troll_id)
+         end;
+      Conversations ->
+         % accrochez-vous ca va siouxer ;)
+         {struct, [
+            {reply, "new_messages"},
+            {conversations, {array,
+               lists:map(
+                  fun({Conv, Plus}) ->
+                     {struct, [
+                        {last_page, not Plus},
+                        {messages, {array, 
+                           lists:map(
+                              fun({Mess, Repond_a}) ->                                 
+                                 Est_proprietaire = User =/= inconnu andalso User#user.id =:= Mess#minichat.auteur_id,
+                                 A_repondu_a_message = User =/= inconnu andalso euphorik_bd:a_repondu_a_message(User#user.id, Mess#minichat.id),
+                                 Est_une_reponse_a_user = User =/= inconnu andalso euphorik_bd:est_une_reponse_a_user(User#user.id, Mess#minichat.id),
+                                 {ok, User_mess } = euphorik_bd:user_by_id(Mess#minichat.auteur_id),
+                                 {struct, [
+                                    {id, Mess#minichat.id},
+                                    {user_id, User_mess#user.id},
+                                    {date, format_date(Mess#minichat.date)},
+                                    {system, Mess#minichat.auteur_id =:= 0},
+                                    {owner, Est_proprietaire},
+                                    {answered, A_repondu_a_message},
+                                    {is_a_reply, Est_une_reponse_a_user},
+                                    {nick, Mess#minichat.pseudo},
+                                    {login, User_mess#user.login},
+                                    {content, Mess#minichat.contenu},
+                                    {answer_to, {array, lists:map(
+                                       fun(Id_mess) ->                   
+                                          {ok, M} = euphorik_bd:message_by_id(Id_mess),
+                                          {ok, User_reponse} = euphorik_bd:user_by_mess(M#minichat.id),
+                                          {struct, [{id, M#minichat.id}, {nick, M#minichat.pseudo}, {login, User_reponse#user.login}]}
+                                       end,
+                                       Repond_a
+                                    )}},
+                                    {ek_master, User_mess#user.ek_master}
+                                 ]}
+                              end,
+                              Conv
+                           )
+                        }}
+                     ]}
+                  end,
+                  Conversations
+               )
+            }}
+         ]}
+   end.
+
+
+% Attend un événement lié à la page 'chat'.
+wait_event_bd_page_chat() ->
+   receive % attente d'un post
+      {mnesia_table_event, {write, minichat, _Message, [], _}} ->
+         ok;
+      {mnesia_table_event, {write, troll, Troll, [Old_troll | _], _}} when Troll#troll.date_post =/= undefined, Old_troll#troll.date_post == undefined ->
+         ok;
+      _ ->
+         wait_event_bd_page_chat()
+   % 60 minutes de timeout (le cas ou il n'y a que des consultations et jamais de post)
+   % Après 60 minutes de connexion, le client doit donc reétablir une connexion
+   % TODO : pour être mieux : quand le socket se ferme alors un message devrait être envoyé et débloquer ce receive (demande en cours sur la mailing list de yaws)
+   after 1000 * 60 * 60 -> 
+      timeout
+   end.           
+         
          
 % Un utilisateur envoie un message
 put_message(