Journal Socialite, une web-app avec Meteor

Posté par  . Licence CC By‑SA.
Étiquettes :
17
25
juil.
2013

Chers amis,

C'est avec une émotion difficilement contrôlable que je vous présente aujourd'hui mon nouveau projet: Socialite.

C'est une "web-app" à-la facebook, développée avec Meteor, la super plateforme tendance open-source en JavaScript.

Ma motivation principale était de jouer avec Meteor tout en essayent de construire un projet cohérent et à peu près fonctionnel. Cela explique pourquoi le design laisse vraiment a désirer parce que je n'ai vraiment aucun talent pour ça et que, soyons honnête, ca m'emmerde énormément de m'en occuper (du coup j'ai utilisé un thème Bootstrap, et dans la foulée publié le paquet Meteor Bootstrap Themes, qui permet non seulement de choisir son thème, mais aussi d'avoir les versions en .less pour grave se simplifier la personnalisation).

Au menu des fonctionnalités:
- les trucs classiques, inscriptions, relation d'amitié, photos, messagerie.
- géolocalisation des utilisateurs pour mettre en relation les gens physiquement proche.
- un moyen facile de générer des formulaires, questions et leur validation (serveur/client) pour les profils utilisateur.
- réactivité complète. La plupart des évènements du site sont en "temps réel", parce que c'est la force de Meteor.

À propos de Meteor, on en a peu parlé ici je pense (j'ai retrouvé ça et ça), je me suis beaucoup amusé à apprendre et utiliser cette plateforme. La prise en main et les concepts de base ne sont pas vraiment évident (je recommande chaudement le livre—payant, et en anglais—Discover Meteor), mais une fois les premières heures passées, c'est très fun. On construit rapidement ses collections et ses publications, le plus relou à mon avis reste le rendu côté client. Dans les défauts, c'est parfois une grosse prise de tête pour rendre certains contenu non-réactifs, ou réactif seulement dans certains cas. Il y a deux ou trois exemples dans le code d'astuce pour contourner ces problèmes (notamment pour la recherche de profils).

C'est la première fois que je publie un projet libre "complet" (mes précédentes contributions se limitent à des correctifs de projets existants), déchainez la fureur; Mitch.

C'est par là : socialite

  • # En lisant trop rapidement

    Posté par  (site web personnel) . Évalué à 2.

    J'ai cru que ton projet était d'être socialiste.

    Sinon, il n'y a pas une petite démo ?

    • [^] # Re: En lisant trop rapidement

      Posté par  . Évalué à 2.

      Ben j'ai regardé pour la demo, mais ça va me couter des sous à héberger où que ce soit, pour un truc que je ne vais pas administrer et où les gens vont inévitablement poster des photos de pénis.

      Donc non, pas de demo pour le moment, mais ça devrait tourner super facilement en local, il faut juste node.js et npm, les dépendances devraient être résolues automatiquement.

      • [^] # Re: En lisant trop rapidement

        Posté par  . Évalué à 4.

        une demo, ca peut etre un code à jour,avec une base de données d'exemples
        qui se recharge toutes les nuits afin de ne pas garder trop de truc indesirable.

        et ca donnerait une idée du produit.

      • [^] # Re: En lisant trop rapidement

        Posté par  (site web personnel) . Évalué à 1. Dernière modification le 25 juillet 2013 à 10:39.

        Heroku te permet de déployer une application web via git et de l'héberger gratuitement, sans aucune administration nécessaire.
        C'est parfait pour des démos de ce genre.

  • # La même chose avec Django

    Posté par  . Évalué à 1.

    J'ai beau faire, c'est bien foutu, mais nodejs ça ne passe pas. Meteor se rapproche-t-il plus d'un approche Django, guidée, unifiée et bien foutue ?

    • [^] # Re: La même chose avec Django

      Posté par  . Évalué à 1.

      (desole, qwerty).

      Aucune idee, je n'ai jamais utilise Django.

      Ce que je peux te dire de l'approche de Meteor, c'est:
      - se reposer sur des librairies/framework existant, pour ne pas reinventer la roue (typiquement LESS/HandlebarJS)
      - un systeme de publication/inscription bien foutu, avec une base de donnee simplifiee cote client, alimentee/synchronisee par la "vraie" base de donnee cote serveur. Le client a donc son propre jeu de donnee qu'il manipule comme il veut, tout le rendu se fait cote client, le serveur se borne principalement a delivrer les bonnes informations. Ce pourquoi c'est une "webapp" et pas un site web. En gros le client recoit l'application + les donnees du serveur, et construit son site web tout seul.
      - c'est reactif. Si A change un truc qui affecte B, B est mis a jour tres rapidement. Seul les parties concernes dans le rendu de B est mis a jour. C'est la partie un peu technique et difficile a manipuler a mon avis. Typiquement dans Socialite, si A envoie un message a B, B recoit une notification immediatement. Ca se base sur websocket & Co.

      Pour le reste, ce n'est pas un framework a proprement parler. Il impose peu de structure ou de convention, et beaucoup de l'API expose concerne en fait des framework integre avec Meteor, pas Meteor en soit.

  • # Demo

    Posté par  . Évalué à 4.

    Elle est la, c'est tout chaud.

    La demo

    • [^] # Re: Demo

      Posté par  . Évalué à 1. Dernière modification le 25 juillet 2013 à 12:14.

      Marche pas …
      Impossible de selectionner la "location" et l'auto detection ne fonctionne pas…
      Chrome 28 linux

      Auto detect :
      Uncaught SyntaxError: Unexpected token ILLEGAL data:image/gif;base64,R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7:1

      Point on map :
      Uncaught ReferenceError: google is not defined 3f369ec723181dc29777ddd6507f9006a9ce5c15.js:16

      • [^] # Re: Demo

        Posté par  . Évalué à 1.

        Fonctionne sous firefox

    • [^] # Re: Demo

      Posté par  (site web personnel) . Évalué à 2. Dernière modification le 25 juillet 2013 à 12:29.

      J'ai un gros

      Welcome
      You are not logged in :/

      au milieu de l'écran, rien d'autre.

      Edit :
      Je viens de voir que j'ai une erreur sur la récupération du fichier JS http://api.filepicker.io/v1/filepicker.js , la page est bloquée par mon proxy d'entreprise avec un tag Category: File Sharing and Storage.

    • [^] # Re: Demo

      Posté par  . Évalué à 1.

      Projet intéressant !

      Wouhou, j'ai créé mon compte.
      Bugs découverts :
      - l'ajout d'amis ne semble pas fonctionner (à moins que tu es reçu une demande d'ami ?)
      - Si je vais directement sur une page de profil, uniquement la bar bleu s'affiche (sans les boutons à coté de mon pseudo). Par exemple en allant sur cette page : http://socialite.meteor.com/profile/sxeZ6vesgp6rpgvSW .
      - "compose a new message" ne fait rien (peut etre parceque je n'ai pas d'amis)
      - si je ne rajoute pas de lieu d'habitation, je ne pouvais pas me créer de compte

      Il pourrait etre intéressant que tu racontes un peu ton expérience sur la création de cette webapp. Les choses faciles, les compliqués, ce qui ta surpris… surtout que le framework meteor à l'air original !

      • [^] # Re: Demo

        Posté par  . Évalué à 1.

        Ouais, la demo deconne pas mal et il y a enormement de bugs que je ne retrouve pas sur les versions locales (testees sur differentes configuration). C'est le serveur de deployment gratuit de Meteor, je pense que le debit et la latence pose probleme.

      • [^] # Re: Demo

        Posté par  . Évalué à 10.

        À propos de l'experience et de mes motivations. 1000 excuses, c'est pas super bien écrit et il manque plein d'accents, je suis au boulot je peux difficilement passer plus de temps sur ce pavé).

        J'ai malgré moi dû me convertir au developpement web il y a quelques années pour manger (je ne suis pas vraiment developpeur). J'ai découvert des horreurs (PHP) et des technos super cool (MODx—meme si c'est du PHP, et Javascript/Node.js) qui m'ont vraiment éclaté.

        Ça faisait longtemps que je voulais faire quelque chose avec les nouvelles technos client/serveur completement en Javascript, et Meteor s'est imposé comme la techno que je voulais utiliser. J'avais testé Express (autre framework pour Node.js) que j'avais trouvé fascinant mais qui m'avait vite decouragé, parce qu'il y a énormement de travail de plomberie avant d'acceder au code metier. Meteor n'a pas ce defaut: il permet vraiment d'attaquer directement la partie qui importe (et pour un programmeur, la partie juteuse du projet, celle qui motive).

        Sur les difficultés rencontrées: d'abord je suis une merde en HTML/CSS et c'est vraiment un truc qui me rebute (et ça se voit plutot pas mal dans ce projet). Autant le reste du code était un bonheur à écrire, autant j'ai eu l'impression de perdre des heures à le connecter pour en faire une interface utilisateur. Pour le coup ce n'est pas de la faute de Meteor, qui simplifie enormement la tache en proposant une version adaptée de Handlebar.js.

        Les concepts de Meteor sont un peu difficile à appréhender au debut. Il laisse beaucoup de liberté pour organiser son projet comme on veut, et ça peut vite devenir le bordel (ce n'est pas un framework). Le principe des publications/inscriptions, très puissant, est aussi un peu difficile à comprendre au debut. Dans l'idée, le serveur met a disposition du client des informations de la base de donnée. Le client a sa propre base de donnée et son propre systeme de base de donnee, minimongo—un mongodb simplifié. Du coup, il faut generalement refaire les mêmes requêtes côté client et côté serveur. Au debut on a l'impression que c'est redondant et peu efficace, mais c'est un chouilla plus subtil.

        Les publications (la mise a disposition d'information côté serveur) permettent de sécuriser un peu ce que l'utilisateur peut voir sur le site en fonction du contexte. Par exemple, dans mon projet il y a différentes publications qui mettent à disposition des informations provenant de la meme base de donnée. Ainsi, lorsqu'un client est sur la page d'accueil, il a acces a son propre document (son propre profil), à la liste de ses amis (une version tres light des profils, surtout pour recuperer le nom et la photo de profil), à ses amis en ligne (qui intersecte necessairement avec la liste de ses amis). Vous pouvez le testez vous meme: allez voir la demo et tapez Meteor.users.find({}).fetch() pour voir quels infos de la base Meteor.users vous pouvez voir. Du coup, côté client il faut organiser ces informations et refaire des requêtes pour séparer ses amis de soit-même lorsqu'on manipule les informations.
        Si je visite le profil de quelqu'un, le contexte change et une publication me donne les informations pour ce profil.

        En gros, on fournit au client les données et la logique, et il se demerde pour faire le rendu. Si vous voulez jouer, tester Collection.find({}).fetch() dans la console, em remplacant Collection par, au choix, Friends, Messages, Conversations, Notifications… pour voir quels informations sont dans votre BDD.

        Maintenant, lorsqu'un document est ajouté/retiré/mis-à-jour dans la base de donnée, et que je suis inscrit a une publication qui diffuse ce document, ma mini-base de donnée côté client est automatiquement mise-à-jour. C'est là ou ca devient un peu compliqué: il y a tout un système de dépendence entre les Templates (bout de DOM utilise pour generer le rendu) et la base de donnée. En gros, si j'ai une Template qui utilise des informations de la BDD, Meteor va décider ou non de refaire le rendu de la Template, de la mettre a jour ou de ne rien faire lorsque la BDD est mise-à-jour. C'est de là que viens la réactivité, mais ça peut aussi etre terriblement chiant. Par exemple pour la création de profil, quand on clique sur "Save", le document de l'utilisateur est modifié , et ca devrait donc refaire le rendu de la page, puisque les champs de formulaire dependent de la valeur du profile utilisateur si elle existe. Du coup il m'a fallu déclarer que les informations que je récupere sont non-réactive, pour bloquer la mise-à-jour automatique de cette Template en particulier (jetez un oeil a client/views/includes/form/form_fields.js, la fonction en haut retourne la valeur a mettre pour un champ lorsqu'on génère un formulaire, notez que la dependance est bloquée en utilisant reactive: false).

        Autre exemple un peu tordu qui m'a pris un peu de temps à concevoir, lors de la recherche d'utilisateur. Dans à peut prêt n'importe quel autre système, le client fait une requête du genre "Envoie moi tous les gens qui sont X et Y", le serveur fait la recherche puis renvoie une liste au client. Cette facon de faire serait tres inefficace avec Meteor, puisqu'il est très possible que certains utilisateurs soient dejà dans la base de donnée côté client, mais aussi parce que le serveur devrait retourner une liste d'utilisateur sous forme de liste qu'il faudra ensuite manipuler côté client—pourquoi faire ça alors que le client dispose de sa propre BDD? Du coup l'astuce consiste à demander au serveur de metter a jour une publication (qui, comme les templates précedemment, depend cette fois d'une variable de Session 'searchQuery'—si cette variable change, la publication est recalculée), lorsque le serveur a finit de mettre a jour la publication, il met a jour une autre variable de Session côté client ('searchQueryDone'). Côté client, j'ai une template qui depend de cette variable (et non pas des donnees, sinon ma page de recherche clignoterait a chaque fois qu'un nouvel utilisateur se creerait un profil par exemple), qui va donc se mettre a jour en utilisant les informations de la base de donnée ET refaire la requete locallement.

        Là où Meteor brille, c'est qu'il s'occupe comme un grand d'optimiser tout ça, d'envoyer les bonnes informations au client, de refaire le rendu des parties concernées par les changements. Quand ça marche, c'est magique et vraiment super simple a faire fonctionner. Quand une heuristique foire (typiquement, dependance un peu severe, ou tout simplement lorsque Meteor n'arrive pas a faire un diff propre d'un bout de DOM avant/après), ca devient une super prise de tête.

        Un dernier exemple pour la route, parce que ma matinee est foutue de toute facon. Imaginons que l'on veuille rajouter un nouveau widget qui affiche la liste des amis communs entre soit-meme et la personne dont on regarde le profil. La liste de mes amis est deja publie et disponible. La liste des amis de ma cible est publie lorsque je visite son profil, j'ai donc toutes les informations a disposition, rien besoin de changer cote serveur. La collection "Friends" indique que A est en relation avec B (et il y a un document de B vers A si la relation est reciproque). Bout de JS que vous devriez pouvoir tester chez vous avec firebug ou la console de Chrome:

        var myFriends = Friends.find({me: Meteor.userId()}).fetch(); // mes amis a moi.
        
        // 'currentUserProfile': variable de Session contextuellement mis a jour pour indiquer quel profil on visite.
        var hisFriends = Friends.find({me: Session.get('currentUserProfile')}).fetch() // Ses amis a lui.
        
        var myTargetIds = [], hisTargetIds = [];
        myFriends.forEach(function(f){ myTargetIds.push(f.target) }) // la liste des _id de mes amis
        hisFriends.forEach(function(f){ hisTargetIds.push(f.target) }) // la liste des _id de ses amis.
        
        var commonFriendsIds = _.intersection(myTargetIds, hisTargetIds); // _ -> underscore.js, propose ce genre de fonctions pratiques.
        
        // De la, on fait ce qu'on veut, par exemple:
        var commonFriends = Friends.find({_id: { $in : commonFriendsIds}}) ; // Extrait de la base de donnee les amis communs, retourne un pointeur facile a manipuler.

        Et voila! Le mega-pavé.

        • [^] # Re: Demo

          Posté par  (site web personnel) . Évalué à 4.

          Merci beaucoup pour ce retour d'experience.

          Ça fait parti du contenu que les lecteurs souhaitent voir plus souvent sur linuxfr, enfin moi ça me fait plaisir de lire de tels journaux.

          J'ai encore pas mal de difficultés à appréhender ces concepts de push, je suis encore désespérément ancré dans le paradigme précédent. Je crois que le meilleur moyen, c'est de se lancer, mais ça implique tellement de nouvelle techno (MongoDB par exemple pour moi …)

          Si je me reserve un peu de temps de lecture, je verrai pour le livre Discover Meteor

    • [^] # Re: Demo

      Posté par  (site web personnel) . Évalué à 5.

      La geolocalisation obligatoire, c'est un peu violent…

      Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

      • [^] # Re: Demo

        Posté par  . Évalué à 0.

        Je me suis fait la même remarque… Mais finalement, si j'ai bien compris, le but premier de ce réseau est de rencontrer des gens. Alors certes il y a la recherche par genre et âge… mais je pense que s'il n'y a pas de recherche géographique, le réseau perd aussi de son intérêt. Puis la géolocalisation se fait au niveau du département, c'est un peu moins pire ^ et rien ne t'empêche de mettre un département au hasard (c'est typiquement ce que je fais quand on me demande mon âge sur Internet d'ailleurs)

        En résumé, oui la géolocalisation obligatoire c'est violent… mais si c'est dans les "gênes" du réseau (rencontre de personnes), on ne peut pas non plus lui en vouloir.

        • [^] # Re: Demo

          Posté par  . Évalué à 3.

          Oui et non. D'un cote, je voulais la mettre pour l'interet technique, il n'y a pas vraiment de strategie sur ce projet (c'est vraiment un prototype, il y a 2 questions et le formulaire de recherche est spartiate). C'est aussi effectivement pour ca que le zoom est bloque et que je n'indique que le departement. Ca permet de regrouper les gens par proximite, mais je me moque de leur adresse exacte.

          Mais je note le probleme, je n'imaginais pas vraiment. J'avais surtout peur que ce soit un peu complique pour beaucoup de gens (pas le public local hein, des vrais gens).

          Puisque j'y suis, merci a tous pour les retours. Je m'attendais un peu a me faire exploser comme c'est la tradition quand quelqu'un presente un projet ici :)

          • [^] # Re: Demo

            Posté par  (site web personnel) . Évalué à 3.

            Je m'attendais un peu a me faire exploser comme c'est la tradition

            Les pénibles doivent être en vacances!

            Que vas-tu faire du projet? Continuer à jouer avec Meteor ou partir dans une direction plus sérieuse?

            Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

            • [^] # Commentaire supprimé

              Posté par  . Évalué à -10. Dernière modification le 27 juillet 2013 à 12:46.

              Ce commentaire a été supprimé par l’équipe de modération.

            • [^] # Re: Demo

              Posté par  . Évalué à 2.

              Pour le moment pas grand chose, c'est vraiment une preuve de concept, et je n'ai pas l'intention de remplir ce qui manque (design, lexique, …) pour en faire un truc complet, pour la bonne raison que je n'ai aucune intention de lancer un 2000eme reseau social, donc aucune raison de mettre ca en production.

              Honnetement, dans l'idee de presenter mon projet ici, je voulais un peu me frotter aux moules: je ne suis pas developpeur initialement, je n'ai pas vraiment idee de la valeur/qualite de ce que j'ai fait. Je ne sais pas si l'absence de lynchage vient de l'absence de grincheux ou de l'absence de defaut flagrant dans la realisation :) Je me plait a rever que c'est un peu des deux.

              (toujours qwerty, cette fois ci sans meme un layout alternatif, peut pas repasser ajouter les accents, desole!)

  • # bug ?

    Posté par  (site web personnel) . Évalué à 3.

    Je n'arrive pas à mettre une photo de mon pénis. Est-ce normal? Un correctif est-il prévu?

    • [^] # Re: bug ?

      Posté par  (site web personnel) . Évalué à 2.

      Si c'est pour la photo de profil, essaye de dessiner des yeux, un nez et une bouche. On sait jamais.

    • [^] # Re: bug ?

      Posté par  (site web personnel) . Évalué à 5.

      Ça me dit « trop gros, passera pas ! ».

      • [^] # Re: bug ?

        Posté par  . Évalué à 4.

        Pas Object Not Found?

        Depending on the time of day, the French go either way.

    • [^] # Re: bug ?

      Posté par  (site web personnel) . Évalué à 3.

      Chez la plupart des gens ça marche, mais pour certains il faudra attendre la prise en charge du zoom webcam par HTML5.

      Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

  • # Report Bug

    Posté par  . Évalué à 0.

    Tu devrais mettre un petit formulaire de report de bug, le journal ne me parais pas le meilleur support pour ça, et c'est plus simple que de demander au utilisateur de t'envoyer des mails.
    Perso j'ai eu 6 bug depuis mon arrivé, jusqu'à la fin de mon inscription. ce qui est normal sur un truc en développement, c'est pas un reproche hein.
    Alors oui y a la gestion des bug de github, mais tout les utilisateur n'ont pas nu compte github, puis c'est plus facile quand t'as un bug qui surviens tu clique sur report la t'as une boite de dialogue qui pop, tu la remplis avec le bug et puis paf c'est envoyer.
    Et puis en plus tu peux mettre des info en plus que l'utilisateur mettra pas , comme la page exacte ou d'autre choses.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.