Jusque là, on est arrivé à faire pas mal de choses avec un simple appel XHR vers SoundCloud. Pour permettre à notre utilisateur de découvrir d’autres personnes qui ont aussi apprécié la chanson, on va charger les commentaires associés puis on fera un lieu au click sur un commentaire vers la page de l’utilisateur en question plus tard.
Ajout de la ListView dans le DOM
Maintenant, vous savez faire ;):
<div id="secondColumn"> <div class="comments" data-win-control="WinJS.UI.ListView" data-win-options="{layout: WinJS.UI.ListLayout, selectionMode: 'none'}"></div> </div>
Chargement des commentaires
On va ajouter une fonction dans notre SoundCloudService pour récupérer les commentaires qui sont accessibles à l’URL:
https://api.soundcloud.com/tracks/ » + trackId + « /comments.json?client_id=…
Voici l’appel complet:
SoundCloudService.prototype.getComments = function (trackId, success, error) { var url = SoundCloudService.API_BASE_URL + "tracks/" + trackId + "/comments.json?" + SoundCloudService.CLIENT_ID; WinJS.xhr({ url: url }).then(function (request) { var data = JSON.parse(request.responseText); var items = []; for (var i = 0, l = data.length; i < l; i++) { items.push(SoundCloudService.formatComment(data[i])); } success(items); }, error); };
Puis on ajoute encore un post-traitement pour que la donnée soit plus simple à afficher plus tard:
SoundCloudService.formatComment = function (item) { item.avatar_url = item.user.avatar_url; item.username = item.user.username; item.timing = Utils.getTiming(item.timestamp); item.body = window.toStaticHTML(Utils.linkify(item.body));
return item; };
Ici, j’utilise deux nouvelles fonctions « utilitaires ». La première « getTiming » permet à partir du timestamp de récupérer une chaîne du type « at 04:40 ». La deuxième permet de mettre des balises <a> autour des liens HTTP présents dans le contenu du commentaire. Cela permettra de mettre en évidence directement les liens dans les commentaires (les liens HTML ont un style par défaut, soulignés et d’une autre couleur).
A noter la méthode window.toStaticHTML qui vient de WinJS et qui permet d’éviter les injections de code HTML (tags script dans le commentaire par exemple).
Aucun mérite pour ces fonctions, je les ai trouvé sur le net, merci StackOverflow :)
Voici le code de ces 2 fonctions utilitaires à placer dans utils.js:
Utils.getTiming = function(timestamp) { if (!timestamp || timestamp == 0) { return ""; } var x = timestamp / 1000; var seconds = x % 60; x /= 60; var minutes = x % 60; seconds = Math.floor(seconds); minutes = Math.floor(minutes); var secondsAsString = seconds > 9 ? seconds : "0" + seconds; var minutesAsString = minutes > 9 ? minutes : "0" + minutes; return "at " + minutesAsString + ":" + secondsAsString; }; /* http://stackoverflow.com/questions/37684/how-to-replace-plain-urls-with-links */ Utils.linkify = function(inputText) { var replacedText, replacePattern1, replacePattern2, replacePattern3; //URLs starting with http://, https://, or ftp:// replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim; replacedText = inputText.replace(replacePattern1, '<a href="$1" target="_blank">$1</a>'); //URLs starting with "www." (without // before it, or it'd re-link the ones done above). replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim; replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" target="_blank">$2</a>'); //Change email addresses to mailto:: links. replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim; replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>'); replacedText = replacedText.replace(/\r\n/gim, "<br />"); return replacedText; };
Appel et affichage dans la liste
Encore une fois, très facile, on va créer une WinJS.Binding.List() puis assigner la propriété itemDataSource de notre liste:
onComments: function (data) { var list = new WinJS.Binding.List(data); var listView = document.querySelector(".comments"); WinJS.UI.setOptions(listView.winControl, { itemDataSource: list.dataSource }); }, ready: function (element, options) { this.track = options.selectedTrack; document.getElementById("trackPageArtist").textContent = this.track.user.username; document.getElementById("releaseDate").textContent = Utils.parseTwitterDate(this.track.created_at); document.getElementById("avatarUrl").src = this.track.user.avatar_url; document.getElementById("artworkImgBig").src = this.track.artwork_url ? this.track.artwork_url.replace("large", "crop") : null; document.getElementById("commentCount").innerHTML = this.track.comment_count; document.getElementById("playCount").innerHTML = this.track.playback_count; document.getElementById("favoriteCount").innerHTML = this.track.favoritings_count; window.soundCloudService.getComments(this.track.id, this.onComments); },
Et on obtient comme d’habitude notre liste sans template:
Création du template de commentaire
On commence par dire à notre liste que l’on veut utiliser notre template:
<div class="comments" data-win-control="WinJS.UI.ListView" data-win-options="{layout: WinJS.UI.ListLayout, selectionMode: 'none', itemTemplate: select('.commentTemplate')}"></}"></div>
Puis on retourne dans default.html créer notre template:
Finalisation et style
Pour éviter que ce soit trop brutal, on va ajouter un titre h1:
<div id="secondColumn"> <h1>Comments</h1>
Un peu de CSS:
#secondColumn { -ms-grid-column: 2; padding-left:20px; } .comments { height:90%; }
Et le résultat devient convenable:
Conclusion
Si vous avez suivi les premiers articles, vous avez vu que l’on a créé notre liste de la même manière, avec une ListView et le retour de l’appel XHR.
Mais vous avez peut-être aussi remarqué autre chose. Le service SoundCloud ne répond pas forcement très vite et la première page peut mettre assez longtemps à s’afficher. Avant de travailler sur le lecteur audio, on va ajouter un mode « local » qui va télécharger un fichier JSON sur le disque plutôt que par l’API. Cela permettra d’arriver sur la page du titre dans attendre.
Ping : Windows Metro – Clouder! (9) – Chargement d’un fichier JSON au lieu d’un appel XHR pour améliorer sa productivité | HTML5 Tutorial
Ping : Windows 8 – Utiliser un template différent selon l’élément affiché dans une ListView | HTML5 Tutorial
Ping : Windows 8 – Réaliser une ListView avec pagination intégrée | HTML5 Tutorial