[extensions-web] Move extension comments client-side



commit b4b8bd6d5c70d670593f8299fd15dd56370014eb
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue Sep 25 18:31:26 2012 -0300

    Move extension comments client-side

 .../extensions/templates/extensions/comments.html  |   24 +------------
 sweettooth/extensions/templatetags/gravatar.py     |   13 +------
 sweettooth/ratings/models.py                       |    3 ++
 sweettooth/ratings/urls.py                         |    1 +
 sweettooth/ratings/views.py                        |   26 ++++++++++++++
 sweettooth/static/js/main.js                       |   36 ++++++++++++++-----
 .../js/templates/extensions/comment.mustache       |   14 ++++++++
 .../js/templates/extensions/comments_list.mustache |    7 ++++
 sweettooth/static/js/templates/templatedata.js     |    2 +
 sweettooth/utils.py                                |   11 ++++++
 10 files changed, 94 insertions(+), 43 deletions(-)
---
diff --git a/sweettooth/extensions/templates/extensions/comments.html b/sweettooth/extensions/templates/extensions/comments.html
index e7ecf3a..7e023ea 100644
--- a/sweettooth/extensions/templates/extensions/comments.html
+++ b/sweettooth/extensions/templates/extensions/comments.html
@@ -1,27 +1,6 @@
 <div id="comments">
   <h4>User comments</h4>
-  {% load comments %}
-  {% load gravatar %}
-  {% get_comment_list for extension as comments %}
-  {% for comment in comments reversed %}
-  <div class="comment">
-  {% if comment.user == extension.creator %}
-    <div class="extension-creator-badge">Author</div>
-  {% endif %}
-    <img src="{% gravatar_url request comment.email %}" class="gravatar">
-    <div class="rating-author">
-      {% if comment.rating != -1 %}
-      <div class="rating" data-rating-value="{{ comment.rating }}"></div> by
-      {% endif %}
-      <a class="comment-author" href="{% url auth-profile user=comment.user.username %}">{{ comment.user }}</a>
-    </div>
-    <p>{{ comment.comment }}</p>
-    <time title="{{ comment.submit_date|date:"c" }}Z">{{ comment.submit_date|date:"F j, Y" }}</time>
-  </div>
-  <hr>
-  {% empty %}
-  There are no comments.
-  {% endfor %}
+  <p>Loading comments...</p>
 </div>
 <div id="opinion_form">
   <h4>Your opinion</h4>
@@ -33,6 +12,7 @@
     <a href="{% url errorreports.views.report_error pk=extension.pk %}">Bug report</a>
   </div>
   <div id="rating_form">
+    {% load comments %}
     {% render_comment_form for extension %}
   </div>
   {% else %}
diff --git a/sweettooth/extensions/templatetags/gravatar.py b/sweettooth/extensions/templatetags/gravatar.py
index 887a0a1..bc614f5 100644
--- a/sweettooth/extensions/templatetags/gravatar.py
+++ b/sweettooth/extensions/templatetags/gravatar.py
@@ -1,14 +1,5 @@
 from django import template
-import urllib, hashlib
+from utils import gravatar_url
 
 register = template.Library()
-
-GRAVATAR_BASE = "https://secure.gravatar.com/avatar/%s?%s";
-
- register simple_tag
-def gravatar_url(request, email, size=70):
-    email_md5 = hashlib.md5(email.lower()).hexdigest()
-    default = request.build_absolute_uri("/static/images/nobody.png")
-    options = urllib.urlencode(dict(d=default, s=size))
-
-    return GRAVATAR_BASE % (email_md5, options)
+register.simple_tag(gravatar_url)
diff --git a/sweettooth/ratings/models.py b/sweettooth/ratings/models.py
index af31923..6d0ddd4 100644
--- a/sweettooth/ratings/models.py
+++ b/sweettooth/ratings/models.py
@@ -1,9 +1,12 @@
 
 from django.db import models
 from django.contrib.comments.models import Comment
+from django.contrib.comments.managers import CommentManager
 from django.contrib.comments.signals import comment_will_be_posted
 
 class RatingComment(Comment):
+    objects = CommentManager()
+
     rating = models.IntegerField(blank=True, default=-1)
 
 def make_sure_user_was_authenticated(sender, comment, request, **kwargs):
diff --git a/sweettooth/ratings/urls.py b/sweettooth/ratings/urls.py
index 06b83e4..319674e 100644
--- a/sweettooth/ratings/urls.py
+++ b/sweettooth/ratings/urls.py
@@ -4,4 +4,5 @@ from ratings import views
 
 urlpatterns = patterns('',
     url(r'^posted/$', views.comment_done, name='comments-comment-done'),
+    url(r'^all/$', views.get_comments),
 )
diff --git a/sweettooth/ratings/views.py b/sweettooth/ratings/views.py
index 2a910dc..1eb91bd 100644
--- a/sweettooth/ratings/views.py
+++ b/sweettooth/ratings/views.py
@@ -1,10 +1,36 @@
 
+from django.core.urlresolvers import reverse
 from django.contrib import comments
 from django.contrib.messages import info
 from django.shortcuts import redirect
+from django.utils.dateformat import format as format_date
+
+from extensions import models
+from decorators import ajax_view, model_view
+from utils import gravatar_url
 
 def comment_done(request):
     pk = request.GET['c']
     comment = comments.get_model().objects.get(pk=pk)
     info(request, "Thank you for your comment")
     return redirect(comment.get_content_object_url())
+
+def comment_details(request, comment):
+    extension = comment.content_object
+    gravatar = gravatar_url(request, comment.email)
+    is_extension_creator = (comment.user == extension.creator)
+
+    return dict(gravatar = gravatar,
+                is_extension_creator = is_extension_creator,
+                rating = comment.rating,
+                comment = comment.comment,
+                author = dict(username=comment.user.username,
+                              url=reverse('auth-profile', kwargs=dict(user=comment.user.username))),
+                date = dict(timestamp = comment.submit_date.isoformat(),
+                            standard = format_date(comment.submit_date, 'F j, Y')))
+
+ ajax_view
+def get_comments(request):
+    extension = models.Extension.objects.get(pk=request.GET['pk'])
+    comment_list = comments.get_model().objects.for_model(extension)
+    return [comment_details(request, comment) for comment in comment_list]
diff --git a/sweettooth/static/js/main.js b/sweettooth/static/js/main.js
index 0370944..ee5048a 100644
--- a/sweettooth/static/js/main.js
+++ b/sweettooth/static/js/main.js
@@ -4,10 +4,10 @@
 require.s.contexts._.defined['jquery'] = jQuery;
 
 define(['jquery', 'messages', 'modal', 'hashParamUtils',
-        'extensions', 'uploader', 'fsui',
+        'templates', 'extensions', 'uploader', 'fsui',
         'jquery.cookie', 'jquery.jeditable',
         'jquery.timeago', 'jquery.raty'],
-function($, messages, modal, hashParamUtils) {
+function($, messages, modal, hashParamUtils, templates) {
     "use strict";
 
     if (!$.ajaxSettings.headers)
@@ -162,14 +162,30 @@ function($, messages, modal, hashParamUtils) {
             return false;
         });
 
-        var pk = $('.extension.single-page.can-edit').data('epk');
-        if (pk) {
-            var inlineEditURL = '/ajax/edit/' + pk;
-            $('#extension_name, #extension_url').csrfEditable(inlineEditURL);
-            $('#extension_description').csrfEditable(inlineEditURL, {type: 'textarea'});
+        $('.extension.single-page').each(function() {
+            var pk = $(this).data('epk');
+            if ($(this).hasClass('can-edit')) {
+                var inlineEditURL = '/ajax/edit/' + pk;
+                $('#extension_name, #extension_url').csrfEditable(inlineEditURL);
+                $('#extension_description').csrfEditable(inlineEditURL, {type: 'textarea'});
 
-            $('.screenshot.upload').uploadify('/ajax/upload/screenshot/'+pk);
-            $('.icon.upload').uploadify('/ajax/upload/icon/'+pk);
-        }
+                $('.screenshot.upload').uploadify('/ajax/upload/screenshot/'+pk);
+                $('.icon.upload').uploadify('/ajax/upload/icon/'+pk);
+            }
+
+            $(this).find('#comments').each(function() {
+                var $loadingText = $(this).find('p');
+                $.ajax({
+                    type: 'GET',
+                    dataType: 'json',
+                    data: { pk: pk },
+                    url: '/comments/all/',
+                }).done(function(comments) {
+                    var $newContent = $(templates.extensions.comments_list(comments));
+                    $newContent.find('time').timeago();
+                    $loadingText.replaceWith($newContent);
+                });
+            });
+        });
     });
 });
diff --git a/sweettooth/static/js/templates/extensions/comment.mustache b/sweettooth/static/js/templates/extensions/comment.mustache
new file mode 100644
index 0000000..d4a61db
--- /dev/null
+++ b/sweettooth/static/js/templates/extensions/comment.mustache
@@ -0,0 +1,14 @@
+<div class="comment">
+  {{#is_extension_creator}}
+  <div class="extension-creator-badge">Author</div>
+  {{/is_extension_creator}}
+  <img src="{{gravatar}}" class="gravatar">
+  <div class="rating-author">
+    {{#has_rating}}
+      <div class="rating" data-rating-value="{{rating}}"></div> by
+    {{/has_rating}}
+    <a class="comment-author" href="{{author.url}}">{{author.username}}</a>
+    <p>{{comment}}</p>
+    <time datetime="{{date.timestamp}}Z">{{date.standard}}</time>
+  </div>
+</div>
diff --git a/sweettooth/static/js/templates/extensions/comments_list.mustache b/sweettooth/static/js/templates/extensions/comments_list.mustache
new file mode 100644
index 0000000..9738c7f
--- /dev/null
+++ b/sweettooth/static/js/templates/extensions/comments_list.mustache
@@ -0,0 +1,7 @@
+{{#.}}
+  {{>extensions.comment}}
+  <hr>
+{{/.}}
+{{^.}}
+  <p>There are no comments. Be the first!</p>
+{{/.}}
diff --git a/sweettooth/static/js/templates/templatedata.js b/sweettooth/static/js/templates/templatedata.js
index 06edb50..cf738bd 100644
--- a/sweettooth/static/js/templates/templatedata.js
+++ b/sweettooth/static/js/templates/templatedata.js
@@ -3,6 +3,8 @@
 
 define({
   "extensions": {
+    "comment": "<div class=\"comment\">\n  {{#is_extension_creator}}\n  <div class=\"extension-creator-badge\">Author</div>\n  {{/is_extension_creator}}\n  <img src=\"{{gravatar}}\" class=\"gravatar\">\n  <div class=\"rating-author\">\n    {{#has_rating}}\n      <div class=\"rating\" data-rating-value=\"{{rating}}\"></div> by\n    {{/has_rating}}\n    <a class=\"comment-author\" href=\"{{author.url}}\">{{author.username}}</a>\n    <p>{{comment}}</p>\n    <time datetime=\"{{date.timestamp}}Z\">{{date.standard}}</time>\n  </div>\n</div>", 
+    "comments_list": "{{#.}}\n  {{>extensions.comment}}\n  <hr>\n{{/.}}\n{{^.}}\n  <p>There are no comments. Be the first!</p>\n{{/.}}", 
     "error_report_template": "What's wrong?\n\n\n\nWhat have you tried?\n\n\n\nAutomatically detected errors:\n\n{{#errors}}\n  {{.}}\n\n================\n{{/errors}}\n{{^errors}}\nGNOME Shell Extensions did not detect any errors with this extension.\n{{/errors}}\n\nVersion information:\n\n    Shell version: {{sv}}\n    Extension version: {{#ev}}{{ev}}{{/ev}}{{^ev}}Unknown{{/ev}}", 
     "info": "<div class=\"extension\" data-uuid=\"{{uuid}}\">\n  {{>extensions.info_contents}}\n</div>", 
     "info_contents": "<div class=\"switch\"></div>\n<div class=\"extra-buttons\">\n  <div class=\"upgrade-button\" title=\"Upgrade this extension\"></div>\n  <div class=\"configure-button\" title=\"Configure this extension\"></div>\n</div>\n<h3 class=\"extension-name\">\n  {{#link}}\n    <a href=\"{{link}}\" class=\"title-link\"> <img src=\"{{icon}}\" class=\"icon\"> {{name}} </a>\n  {{/link}}\n  {{^link}}\n  {{name}}\n  {{/link}}\n</h3>\n{{#creator}}\n  <span class=\"author\">by <a href=\"{{creator_url}}\"> {{creator}} </a></span>\n{{/creator}}\n<p class=\"description\">{{first_line_of_description}}</p>\n{{#want_uninstall}}\n  <button class=\"uninstall\" title=\"Uninstall\">Uninstall</button>\n{{/want_uninstall}}", 
diff --git a/sweettooth/utils.py b/sweettooth/utils.py
index 5f87004..bf7fa1f 100644
--- a/sweettooth/utils.py
+++ b/sweettooth/utils.py
@@ -1,6 +1,17 @@
 
+import urllib
+import hashlib
+
 from django.shortcuts import render_to_response
 from django.template import RequestContext
 
 def render(req, *args, **kwargs):
     return render_to_response(context_instance=RequestContext(req), *args, **kwargs)
+
+GRAVATAR_BASE = "https://secure.gravatar.com/avatar/%s?%s";
+
+def gravatar_url(request, email, size=70):
+    email_md5 = hashlib.md5(email.lower()).hexdigest()
+    default = request.build_absolute_uri("/static/images/nobody.png")
+    options = urllib.urlencode(dict(d=default, s=size))
+    return GRAVATAR_BASE % (email_md5, options)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]