From cded85bdaf899cef1ba38d2ee6fd24c67f2abc52 Mon Sep 17 00:00:00 2001 From: Greg Burri Date: Fri, 11 Apr 2008 20:14:31 +0000 Subject: [PATCH] ADD support des conversations (pas fini) --- css/1/pageMinichat.css | 43 +++++++++---- doc/TODO.txt | 6 ++ doc/protocole2.txt | 26 +++++--- doc/technique.txt | 36 +++++++++-- js/euphorik.js | 47 +++++++++++--- js/pageMinichat.js | 99 +++++++++++++++++++++--------- modules/erl/euphorik_bd.erl | 3 +- modules/erl/euphorik_protocole.erl | 6 ++ modules/include/euphorik_bd.hrl | 2 +- sessions/doc.session | 16 +++-- sessions/erl.session | 18 +++--- sessions/js.session | 27 +++++--- 12 files changed, 239 insertions(+), 90 deletions(-) diff --git a/css/1/pageMinichat.css b/css/1/pageMinichat.css index d031b7f..182b9b0 100755 --- a/css/1/pageMinichat.css +++ b/css/1/pageMinichat.css @@ -44,9 +44,15 @@ background-repeat: no-repeat; background-position: 5px 2px; vertical-align: top; +} + +#page.minichat #conversations .conversation { + border-width: 2px; + border-style: solid; + border-color: white } -#page.minichat #messages div.message { +#page.minichat #conversations div.message { border-left-width: 5px; border-left-style: solid; border-color: transparent; @@ -56,26 +62,26 @@ cursor: pointer; } -#page.minichat #messages div.messageImpair { +#page.minichat #conversations div.messageImpair { background-color: #05002c; } -#page.minichat #messages div.messagePair { +#page.minichat #conversations div.messagePair { background-color: #080047; } /* Il n'y a plus de mise en evidence -#page.minichat #messages div.miseEnEvidenceReponse { +#page.minichat #conversations div.miseEnEvidenceReponse { background-color: #bd7a11; } -#page.minichat #messages div.miseEnEvidenceCourant { +#page.minichat #conversations div.miseEnEvidenceCourant { background-color: #bd1129; } -#page.minichat #messages div.miseEnEvidenceConversation { +#page.minichat #conversations div.miseEnEvidenceConversation { background-color: #b711bd; }*/ -#page.minichat #messages div.cache { +#page.minichat #conversations div.cache { opacity: 0.3; /* Hack IE 7 */ @@ -83,16 +89,16 @@ zoom: 1 } -#page.minichat #messages div.reponse { +#page.minichat #conversations div.reponse { border-color: #bd7a11 } -#page.minichat #messages div.repondu { +#page.minichat #conversations div.repondu { border-color: #b711bd } -#page.minichat #messages div.proprietaire { +#page.minichat #conversations div.proprietaire { border-color: #bd1129 } -#page.minichat #messages div.systeme { +#page.minichat #conversations div.systeme { background-color: #555555 } @@ -126,14 +132,25 @@ height:100px; }*/ -#page.minichat #messages .repondA { +#page.minichat #conversations .repondA { display: inline; margin-left: 4px; color: #bd7a11 } -#page.minichat #messages .contenu { +#page.minichat #conversations .contenu { display: inline; +} + +#page.minichat #conversations .extraire { + float: right; + padding-right: 2px; + padding-left: 2px; + background-color: #4f5519; +} + +#page.minichat #conversations .extraire:hover { + background-color: #818c27 } #page.minichat #pages { diff --git a/doc/TODO.txt b/doc/TODO.txt index ca05506..b0288c7 100755 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -55,6 +55,11 @@ [ok] Ne pas afficher la css dans le profile [ok] Ne pas effacer le message (dans le ) si l'on recoit un "pas ok" lors de l'envoie +* Conversations : + a) implémenter coté serveur et client la sauvegarde et la restauration des conversations + b) Supprimer l'envoie de la description des conversations lors du refresh ainsi que modifié la manière de créer les conversations (maj des diagrammes de séquence) + c) Navigation vers les pages précédentes + c) Mettre à jour l'HTML/CSS de chaque skin en fonction * Utiliser une listbox pour la liste des css * Ralentir volontairement le connexion lors d'un mauvais login (ou après n mauvais login) * Pouvoir switcher entre un affichage "pseudo" ou "pseudo (login)" @@ -156,6 +161,7 @@ A : Abandonné [4] Bot de traduction [4] Bot de jeu (jeu du pendu par exemple) [4] RSS +[4] Système de vote sur les messages, + ou - qui donne des points aux messages... [4] Voir les personnes connectées [4] Avoir une liste d'amis [4] Restreindre la consultation d'un message posté à un ou plusieurs utilisateurs définis. Les messages de la conversation ne sont alors vus que par cet ensemble d'utilisateurs. diff --git a/doc/protocole2.txt b/doc/protocole2.txt index c8ae1a6..704dc6a 100644 --- a/doc/protocole2.txt +++ b/doc/protocole2.txt @@ -17,7 +17,7 @@ Authentification: Rafraichissement: * Le client envoie une demande au serveur avec l'id du dernier message (via XMLHttpRequest ou un function de JQuery) * Le serveur maintient la connexion bloqué si le client est à jour. - * Dès qu'un nouveau message arrive, le serveurs débloque la connexion est envoie le ou les messages manquants. + * Dès qclientu'un nouveau message arrive, le serveurs débloque la connexion est envoie le ou les messages manquants. C. Protocole @@ -55,6 +55,13 @@ s -> c paul49 paul@pierre.com css/lite.css + + + + 4 + 1 + + blabla @@ -78,12 +85,17 @@ c -> s Paul paul@pierre.com css/dark.css + + 4 + 1 + + s -> c ok|pas ok - balbla> + balbla @@ -91,19 +103,15 @@ C.4. Refresh messages --------------------- Si dernierMessageId est absent alors le client ne possède pas de message. -Page peut être omis, il a alors la valeur 1 (première page) -dernierMessageId est en base 36 (l'histoire de rigoler un peu) +Page peut être omis, il a alors la valeur 1 (première page). +dernierMessageId est en base 36 (l'histoire de rigoler un peu). +Les conversations données sont définies dans le profile. c -> s LKJDLAKSJBFLKASN 10 6ZR - 1 - - RE - 1 - diff --git a/doc/technique.txt b/doc/technique.txt index f44639a..ea0ef37 100644 --- a/doc/technique.txt +++ b/doc/technique.txt @@ -1,13 +1,18 @@ Euphorik - doc technique -== Page message == -Classes : + +== euphorik.js == +Sequences : + * Chargement d'une page + +== pageMinichat.js == +=== Classes === * Messages * Conversation * Message -Sequences : +=== Séquences === * Attente de nouveaux messages a) Messages.rafraichirMessages b) pour chaque conversation @@ -17,5 +22,26 @@ Sequences : * Ajout d'un message PageMinichat.envoyerMessage(pseudo, message) : requête AJAX - * Création d'une conversation - * Suppression d'une conversation \ No newline at end of file + * Extraction d'une conversation + a) Conversation.click + b) Messages.ExtraireConversation(numMess) + c) User.ajouterConversation(numMess) + d) Messages.rafraichirMessages(true) + + * Suppression d'une conversation + +=== Exemple de conversation === +Utilisé lors des tests + +m1 +m2 -> m1 +m3 -> m1 +m4 -> m2 +m5 -> m3 +m6 -> m3 +m7 + + + + + diff --git a/js/euphorik.js b/js/euphorik.js index e56acde..fafa854 100755 --- a/js/euphorik.js +++ b/js/euphorik.js @@ -411,7 +411,12 @@ Client.prototype.resetDonneesPersonnelles = function() this.login = "" this.password = "" this.email = "" - this.css = jQuery("link#cssPrincipale").attr("href") + this.css = jQuery("link#cssPrincipale").attr("href") + + // les conversations, une conversation est un objet possédant les attributs suivants : + // - racine (entier) + // - page (entier) + this.conversations = new Array() } Client.prototype.setCss = function(css) @@ -422,14 +427,20 @@ Client.prototype.setCss = function(css) this.css = css jQuery("link#cssPrincipale").attr("href", this.css) this.majMenu() - - /* enregistement automatique.. - if (!this.identifie()) - if (!this.enregistrement()) - return - */ + if (this.identifie()) this.flush() +} + +/** + * Ajoute une conversation à la vue de l'utilisateur. + * Le profile de l'utilisateur est directement sauvegardé sur le serveur. + * @param racines la racine de la conversation + */ +Client.prototype.ajouterConversation = function(racine) +{ + this.conversations.push({racine : racine, page : 1}) + this.flush() } Client.prototype.getXMLlogin = function(login, password) @@ -531,6 +542,26 @@ Client.prototype.getXMLProfile = function() nodeCSS.appendChild(XMLDocument.createTextNode(this.css)) XMLDocument.documentElement.appendChild(nodeCSS) + // mémorise les conversations affichées + if (this.conversations.length > 0) + { + var nodeConversations = XMLDocument.createElement("conversations") + XMLDocument.documentElement.appendChild(nodeConversations) + for (var i = 0; i < this.conversations.length; i++) + { + var nodeConv = XMLDocument.createElement("conversation") + nodeConversations.appendChild(nodeConv) + + var nodeRacine = XMLDocument.createElement("racine") + nodeRacine.appendChild(XMLDocument.createTextNode(this.conversations[i].racine)) + nodeConv.appendChild(nodeRacine) + + var nodePage = XMLDocument.createElement("page") + nodePage.appendChild(XMLDocument.createTextNode(this.conversations[i].page)) + nodeConv.appendChild(nodePage) + } + } + return XMLDocument } @@ -703,7 +734,7 @@ Client.prototype.chargerDonnees = function(data) Client.prototype.flush = function() { thisClient = this - //thisClient.util.log(this.util.xmlVersAction(this.getXMLProfile()).action) + //thisClient.util.log(this.util.xmlVersAction(this.getXMLProfile()).action) jQuery.ajax( { async: true, diff --git a/js/pageMinichat.js b/js/pageMinichat.js index c8a099a..9d4d329 100755 --- a/js/pageMinichat.js +++ b/js/pageMinichat.js @@ -10,17 +10,16 @@ function PageMinichat(client, formateur, util) this.regexMessageTagMatch = /\{.*?\}>/g this.regexMessageTagReplace = /^(.*?\{.*?\}>)*/ - - this.messages = new Messages(this.client, this.formateur, this.util) } PageMinichat.prototype.contenu = function() { +// \ return '\
\
\ -

\ - \ +

\ + \ \ \ \ @@ -35,7 +34,10 @@ PageMinichat.prototype.charger = function() jQuery("form input.pseudo").val(this.client.pseudo) - this.messages.rafraichirMessages(true) + // cet appel ne doit pas être fait avant l'appel à 'charger' + this.messages = new Messages(this.client, this.formateur, this.util) + + this.messages.rafraichirMessages(true) this.util.setCaretToEnd(jQuery("form input.message")[0]) @@ -260,9 +262,11 @@ Message.prototype.setRepondA = function(element) } /** - * @return les id des messages qui ont été mis en evidence sous la forme d'un objet + * Renvoie les messages faisant partie d'une conversation. + * @param messages l'ensemble des messages de la conversation + * @return les id des messages qui ont été mis en evidence sous la forme d'un hash (object) {id => bool} */ -Message.prototype.afficherConversation = function(messages) +Message.prototype.getConversation = function(messages) { // les messages faisant partie de la conversation var messagesEnEvidence = {} @@ -298,26 +302,27 @@ Message.prototype.afficherConversation = function(messages) * @param numConv le numéro (appelé id) de la conversation * @param formateur outil permettant la mise en forme du texte des messages */ -function Conversation(numConv, formateur) +function Conversation(numConv, formateur, util) { var thisConversation = this this.id = numConv this.messageOver = null // le message sur lequel se trouve le curseur this.formateur = formateur + this.util = util this.messages = new Array() this.messagesParId = new Object() - this.idDernierMesssage = null // la racine de la conversation (string), null = conversation principale + this.idDernierMesssage = null this.page = 1 // par défaut on se trouve sur la première page - + jQuery("#conversations").append( - "

" + "
" ) // enlève la mise en évidence pour la conversation - jQuery(this.getId()).hover( + jQuery("#conversations #" + this.getId()).hover( function(){}, function(event) { @@ -328,11 +333,11 @@ function Conversation(numConv, formateur) } /** - * Retourne l'id de la conversation sous la forme (par exemple) "#conv453" + * Retourne l'id de la conversation sous la forme (par exemple) "conv3". */ Conversation.prototype.getId = function() { - return "#" + this.id + return "conv" + this.id } Conversation.prototype.ajouterMessage = function(message) @@ -346,18 +351,19 @@ Conversation.prototype.ajouterMessage = function(message) Conversation.prototype.viderMessages = function() { this.messages = new Array() - jQuery("#conversations " + this.getId()).empty() + jQuery("#conversations #" + this.getId()).empty() } /** * Après l'ajout d'un ou plusieurs message cette méthode est appelée afin * d'afficher les messages non-affichés. + * @param funClickExtract fonction (fun(numMess)) appellée lors du clic sur un bouton "extraire" */ -Conversation.prototype.flush = function() +Conversation.prototype.flush = function(funClickExtract) { var thisConversation = this - var idDernierMessageAffiche = jQuery("#conversations " + this.getId() + " div:first").attr("id") + var idDernierMessageAffiche = jQuery("#conversations #" + this.getId() + " div:first").attr("id") if (idDernierMessageAffiche == undefined) idDernierMessageAffiche = "0" var XHTML = "" @@ -374,32 +380,54 @@ Conversation.prototype.flush = function() "
" + + "
>
" + "[
" + message.date + "
]" + "
" + this.formateur.traitementComplet(message.pseudo) + "
:" + XHTMLrepondA + - "
" + (message.systeme ? this.formateur.remplacerBalisesHTML(message.contenu) : this.formateur.traitementComplet(message.contenu, message.pseudo))+ "
" + + "
" + (message.systeme ? this.formateur.remplacerBalisesHTML(message.contenu) : this.formateur.traitementComplet(message.contenu, message.pseudo)) + "
" + "
" } - jQuery("#conversations " + this.getId()).prepend(XHTML) + //alert(this.getId()) + jQuery("#conversations #" + this.getId()).prepend(XHTML) + //alert(jQuery("#conversations").text()) + // mise à jour des images (LightBox) après l'ajout de message if (myLightbox != null) myLightbox.updateImageList() - var nbMessagesAffiche = jQuery("#conversations " + this.getId() + " .message").size() + var nbMessagesAffiche = jQuery("#conversations #" + this.getId() + " .message").size() if (nbMessagesAffiche > this.nbMessageMax) - jQuery("#conversations " + this.getId() + " .message").slice(this.nbMessageMax, nbMessagesAffiche).empty(); + jQuery("#conversations #" + this.getId() + " .message").slice(this.nbMessageMax, nbMessagesAffiche).empty(); - jQuery("#conversations " + this.getId() + " .message").filter(function(){return parseInt(jQuery(this).attr("id"), 36) > parseInt(idDernierMessageAffiche, 36)}).each( + // Ajoute les événements liés à chaque message + jQuery("#conversations #" + this.getId() + " .message").filter(function(){return parseInt(jQuery(this).attr("id"), 36) > parseInt(idDernierMessageAffiche, 36)}).each( function() { + /*jQuery(".extraire", this).click( + function(event) + { + funClickExtract() + return false + } + )*/ jQuery(this).click( function(event) { if (jQuery(event.target).is("a")) return + + // l'id du message + idMess = jQuery(this).attr("id") + + // extraction d'une conversation + if (jQuery(event.target).is(".extraire")) + { + funClickExtract(idMess) + return + } var valCourant = jQuery("input.message").val() if (valCourant == undefined) valCourant = "" - var tag = jQuery(".pseudo", this).text() + "{" + jQuery(this).attr("id") + "}" + ">" + var tag = jQuery(".pseudo", this).text() + "{" + idMess + "}" + ">" if (valCourant.indexOf(tag, 0) == -1) jQuery("input.message").val(tag + " " + valCourant) thisConversation.util.setCaretToEnd(jQuery("form input.message")[0]) @@ -433,10 +461,10 @@ Conversation.prototype.afficherConversation = function(element) var message = this.messagesParId[id] if (message == undefined) return - mess = message.afficherConversation(this) + mess = message.getConversation(this) // FIXME : cet appel est très lent - jQuery("#conversations " + this.getId() + " .message").each( + jQuery("#conversations #" + this.getId() + " .message").each( function() { var jq = jQuery(this) @@ -460,7 +488,7 @@ function Messages(client, formateur, util) this.util = util this.conversations = new Array() // les conversations, la première représente la conversation principale - this.conversations[0] = new Conversation(0, this.formateur) + this.conversations[0] = new Conversation(0, this.formateur, this.util) this.idDernierMesssage = null // l'id du dernier message connu @@ -501,17 +529,17 @@ Messages.prototype.getXMLrafraichirMessages = function() XMLDocument.documentElement.appendChild(nodePage) // les conversations - for (var i = 1; i < this.conversations.length; i++) + for (var i = 0; i < this.client.conversations.length; i++) { var nodeConversation = XMLDocument.createElement("conversation") XMLDocument.documentElement.appendChild(nodeConversation) var nodeRacine = XMLDocument.createElement("racine") - nodeRacine.appendChild(XMLDocument.createTextNode(this.conversation.racine)) + nodeRacine.appendChild(XMLDocument.createTextNode(this.client.conversations[i].racine)) nodeConversation.appendChild(nodeRacine) var nodePageConv = XMLDocument.createElement("page") - nodePageConv.appendChild(XMLDocument.createTextNode(this.conversation.page)) + nodePageConv.appendChild(XMLDocument.createTextNode(this.client.conversations[i].page)) nodeConversation.appendChild(nodePageConv) } @@ -556,6 +584,7 @@ Messages.prototype.ajouterMessage = function(element, numConversation) if (this.conversations[numConversation] == null) this.conversations[numConversation] = new Conversation(numConversation, this.formateur) + this.conversations[numConversation].ajouterMessage(message) } @@ -573,7 +602,17 @@ Messages.prototype.flushAll = function() */ Messages.prototype.flush = function(numConv) { - this.conversations[numConv].flush() + var thisMessages = this + + this.conversations[numConv].flush + ( + // fonction appellée lors de la demande d'extraction d'une conversation + function(idMess) + { + thisMessages.client.ajouterConversation(idMess) + thisMessages.rafraichirMessages(true) + } + ) } Messages.prototype.viderMessages = function() diff --git a/modules/erl/euphorik_bd.erl b/modules/erl/euphorik_bd.erl index 469e242..8eb90df 100755 --- a/modules/erl/euphorik_bd.erl +++ b/modules/erl/euphorik_bd.erl @@ -73,8 +73,7 @@ vers_version(4) -> end, record_info(fields, user), user - ). - + ). % exemple de peuplage de la BD, utilisé pour les tests peupler() -> diff --git a/modules/erl/euphorik_protocole.erl b/modules/erl/euphorik_protocole.erl index 57275fc..35bf993 100755 --- a/modules/erl/euphorik_protocole.erl +++ b/modules/erl/euphorik_protocole.erl @@ -112,6 +112,12 @@ profile(Action) -> Pseudo = case xmerl_xpath:string("pseudo", Action) of [#xmlElement{content = [#xmlText{value = P2}]}] -> P2; _ -> Login end, Email = case xmerl_xpath:string("email", Action) of [#xmlElement{content = [#xmlText{value = E}]}] -> E; _ -> undefined end, Css = case xmerl_xpath:string("css", Action) of [#xmlElement{content = [#xmlText{value = C}]}] -> C; _ -> undefined end, + Conversations = case xmerl_xpath:string("conversations", Action) of + Conversations -> + % extraction de chaque conversation + + _ -> [] + end, case euphorik_minichat:set_profile(Cookie, Login, Password, Pseudo, Email, Css) of ok -> xml_reponse_profile_ok(); diff --git a/modules/include/euphorik_bd.hrl b/modules/include/euphorik_bd.hrl index e998778..45be716 100755 --- a/modules/include/euphorik_bd.hrl +++ b/modules/include/euphorik_bd.hrl @@ -40,7 +40,7 @@ date_derniere_connexion, % erlang:now(), est mis à jour lors de n'importe quelle activitée (envoie de message par exemple) css = [], % string() indice_flood = 0, % integer() est incrémenté lorsque l'utilisateur envoie trop rapidement des messages. - conversations = [] % [integer()], la liste des messages correspondant au conversation + conversations = [] % [{integer(), integer()}], la liste des messages correspondant au conversation ainsi que la page affichée }). \ No newline at end of file diff --git a/sessions/doc.session b/sessions/doc.session index 65a9ac6..c000402 100755 --- a/sessions/doc.session +++ b/sessions/doc.session @@ -1,7 +1,11 @@ -buffer.1.path=../doc/TODO.txt -buffer.1.position=1 -buffer.1.current=1 - -buffer.2.path=../doc/protocole2.txt -buffer.2.position=1 +# SciTE session file +buffer.1.path=/home/gburri/projets/euphorik/doc/protocole2.txt +buffer.1.position=1 + +buffer.2.path=/home/gburri/projets/euphorik/doc/technique.txt +buffer.2.position=1 + +buffer.3.path=/home/gburri/projets/euphorik/doc/TODO.txt +buffer.3.position=1 +buffer.3.current=1 diff --git a/sessions/erl.session b/sessions/erl.session index c1a5360..e25e717 100755 --- a/sessions/erl.session +++ b/sessions/erl.session @@ -1,21 +1,23 @@ -buffer.1.path=../modules/include/euphorik_defines.hrl +# SciTE session file + +buffer.1.path=/home/gburri/projets/euphorik/modules/erl/euphorik_bd.erl buffer.1.position=1 -buffer.2.path=../modules/include/euphorik_bd.hrl +buffer.2.path=/home/gburri/projets/euphorik/modules/erl/euphorik_minichat.erl buffer.2.position=1 -buffer.3.path=../modules/erl/euphorik_bd.erl +buffer.3.path=/home/gburri/projets/euphorik/modules/erl/euphorik_minichat_conversation.erl buffer.3.position=1 -buffer.4.path=../modules/erl/euphorik_minichat.erl +buffer.4.path=/home/gburri/projets/euphorik/modules/erl/euphorik_protocole.erl buffer.4.position=1 -buffer.5.path=../modules/erl/euphorik_minichat_conversation.erl +buffer.5.path=/home/gburri/projets/euphorik/modules/erl/euphorik_requests.erl buffer.5.position=1 -buffer.5.current=1 -buffer.6.path=../modules/erl/euphorik_protocole.erl +buffer.6.path=/home/gburri/projets/euphorik/modules/include/euphorik_bd.hrl buffer.6.position=1 -buffer.7.path=../modules/erl/euphorik_requests.erl +buffer.7.path=/home/gburri/projets/euphorik/modules/include/euphorik_defines.hrl buffer.7.position=1 +buffer.7.current=1 diff --git a/sessions/js.session b/sessions/js.session index dc61b57..9c69bdc 100755 --- a/sessions/js.session +++ b/sessions/js.session @@ -1,12 +1,23 @@ -buffer.1.path=../js/euphorik.js -buffer.1.position=1 +# SciTE session file -buffer.2.path=../js/pageMinichat.js -buffer.2.position=1 -buffer.2.current=1 +buffer.1.path=/home/gburri/projets/euphorik/js/euphorik.js +buffer.1.position=7787 -buffer.3.path=../js/pageProfile.js -buffer.3.position=1 +buffer.2.path=/home/gburri/projets/euphorik/js/pageMinichat.js +buffer.2.position=1044 +buffer.2.current=1 -buffer.4.path=../js/pageRegister.js +buffer.3.path=/home/gburri/projets/euphorik/js/pageProfile.js +buffer.3.position=1 + +buffer.4.path=/home/gburri/projets/euphorik/js/pageRegister.js buffer.4.position=1 + +buffer.5.path=/home/gburri/projets/euphorik/css/1/euphorik.css +buffer.5.position=1 + +buffer.6.path=/home/gburri/projets/euphorik/css/1/pageMinichat.css +buffer.6.position=1 + +buffer.7.path=/home/gburri/projets/euphorik/css/1/pageProfileRegister.css +buffer.7.position=1 -- 2.45.2