diff --git a/apps/social/templatetags/social_tags.py b/apps/social/templatetags/social_tags.py
index 922a616cd..d90c9319a 100644
--- a/apps/social/templatetags/social_tags.py
+++ b/apps/social/templatetags/social_tags.py
@@ -2,6 +2,13 @@ from django import template
register = template.Library()
+@register.inclusion_tag('social/social_story.xhtml')
+def render_social_story(story, has_next_story=False):
+ return {
+ 'story': story,
+ 'has_next_story': has_next_story
+ }
+
@register.inclusion_tag('social/story_share.xhtml')
def render_story_share(story):
return {
diff --git a/apps/social/views.py b/apps/social/views.py
index ddb990a9b..4bd840ab4 100644
--- a/apps/social/views.py
+++ b/apps/social/views.py
@@ -163,22 +163,26 @@ def load_social_stories(request, user_id, username=None):
"classifiers": classifiers,
}
-@render_to('social/social_page.xhtml')
def load_social_page(request, user_id, username=None):
user = request.user
social_user_id = int(user_id)
social_user = get_object_or_404(User, pk=social_user_id)
offset = int(request.REQUEST.get('offset', 0))
- limit = int(request.REQUEST.get('limit', 12))
+ limit = int(request.REQUEST.get('limit', 6))
page = request.REQUEST.get('page')
+ format = request.REQUEST.get('format', None)
+ has_next_page = False
if page: offset = limit * (int(page) - 1)
user_social_profile = None
if user.is_authenticated():
user_social_profile = MSocialProfile.objects.get(user_id=user.pk)
social_profile = MSocialProfile.objects.get(user_id=social_user_id)
- mstories = MSharedStory.objects(user_id=social_user.pk).order_by('-shared_date')[offset:offset+limit]
+ mstories = MSharedStory.objects(user_id=social_user.pk).order_by('-shared_date')[offset:offset+limit+1]
stories = Feed.format_stories(mstories)
+ if len(stories) > limit:
+ has_next_page = True
+ stories = stories[:-1]
if not stories:
return {
@@ -220,9 +224,15 @@ def load_social_page(request, user_id, username=None):
'social_profile': social_profile.page(),
'feeds' : feeds,
'user_profile' : hasattr(user, 'profile') and user.profile,
+ 'has_next_page' : has_next_page,
}
- return params
+ if format == 'html':
+ template = 'social/social_stories.xhtml'
+ else:
+ template = 'social/social_page.xhtml'
+
+ return render_to_response(template, params, context_instance=RequestContext(request))
def story_public_comments(request):
format = request.REQUEST.get('format', 'json')
diff --git a/assets.yml b/assets.yml
index 9cc15cc92..5b515b370 100644
--- a/assets.yml
+++ b/assets.yml
@@ -92,6 +92,7 @@ javascripts:
- media/js/vendor/jquery.corners.js
blurblog:
- media/js/vendor/jquery-*.js
+ - media/js/vendor/jquery.color.js
- media/js/vendor/underscore-*.js
- media/js/vendor/underscore.string.js
- media/js/vendor/backbone-*.js
diff --git a/media/css/social/social_page.css b/media/css/social/social_page.css
index f04f008f2..cc823137c 100644
--- a/media/css/social/social_page.css
+++ b/media/css/social/social_page.css
@@ -949,4 +949,68 @@ header {
-moz-box-shadow: 2px 2px 0 #95AB76;
-webkit-box-shadow: 2px 2px 0 #95AB76;
box-shadow: 2px 2px 0 #95AB76;
+}
+
+/* ================= */
+/* = Page Controls = */
+/* ================= */
+
+.NB-page-controls {
+ border-top: 2px solid #8B8B8B;
+ border-bottom: 2px solid #8B8B8B;
+ padding: 1px 0;
+ cursor: pointer;
+ text-align: center;
+ margin: 0 auto 36px;
+ width: 800px;
+ border-radius: 8px;
+ overflow: hidden;
+}
+.NB-page-controls-next {
+ background-color: #506CB1;
+ color: white;
+ text-shadow: 0 1px 0 #2B478C;
+ font-weight: bold;
+ text-transform: uppercase;
+ font-size: 20px;
+ padding: 20px 28px 20px;
+ overflow: hidden;
+ border-radius: 8px;
+ height: 20px;
+ position: relative;
+ -webkit-transition: all .12s ease-out;
+ -moz-transition: all .12s ease-out;
+ -o-transition: all .12s ease-out;
+ -ms-transition: all .12s ease-out;
+}
+.NB-page-controls-next.NB-loading {
+ -webkit-transition: none;
+ -moz-transition: none;
+ -o-transition: none;
+ -ms-transition: none;
+ cursor: wait;
+}
+.NB-page-controls-next.NB-loaded {
+ cursor: default;
+}
+.NB-page-controls:hover .NB-page-controls-next {
+ background-color: #2B478C;
+ background-image: none;
+ text-shadow: 0 1px 0 #141F48;
+}
+.NB-page-controls .NB-page-controls-next b {
+ padding: 0 1px;
+ font-size: 12px;
+}
+.NB-page-controls .NB-page-controls-next .NB-page-controls-text {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ height: 20px;
+ text-align: center;
+ bottom: 20px;
+}
+.NB-page-controls .NB-page-controls-next .NB-page-controls-text-loading,
+.NB-page-controls .NB-page-controls-next .NB-page-controls-text-loaded {
+ bottom: 64px;
}
\ No newline at end of file
diff --git a/media/js/newsblur/social_page/social_page.js b/media/js/newsblur/social_page/social_page.js
index 2edc58313..f6d95d8ba 100644
--- a/media/js/newsblur/social_page/social_page.js
+++ b/media/js/newsblur/social_page/social_page.js
@@ -2,6 +2,12 @@ NEWSBLUR.Views.SocialPage = Backbone.View.extend({
el: 'body',
+ page: 1,
+
+ events: {
+ "click .NB-page-controls-next:not(.NB-loaded):not(.NB-loading)" : "next_page"
+ },
+
initialize: function() {
NEWSBLUR.assets = new NEWSBLUR.SocialPageAssets();
this.initialize_stories();
@@ -13,6 +19,81 @@ NEWSBLUR.Views.SocialPage = Backbone.View.extend({
$('.NB-story', $stories).each(function() {
new NEWSBLUR.Views.SocialPageStory({el: $(this)});
});
+ },
+
+ // ===========
+ // = Actions =
+ // ===========
+
+ post_next_page: function(data) {
+ var $controls = this.$('.NB-page-controls').last();
+ var $button = $('.NB-page-controls-next', $controls);
+ var $loading = $('.NB-page-controls-text-loading', $controls);
+ var $loaded = $('.NB-page-controls-text-loaded', $controls);
+ var height = $controls.height();
+ var innerheight = $button.height();
+
+ $button.removeClass('NB-loading').addClass('NB-loaded');
+
+ $loaded.text('Page ' + this.page).css('bottom', height).animate({'bottom': innerheight}, {
+ 'duration': 500,
+ 'easing': 'easeInOutQuint',
+ 'queue': false
+ });
+ $loading.animate({'bottom': -1 * innerheight}, {
+ 'duration': 500,
+ 'easing': 'easeInOutQuint',
+ 'queue': false
+ });
+
+ clearInterval(this.feed_stories_loading);
+ $button.stop().animate({'backgroundColor': '#86B86B'}, {'duration': 750, 'queue': false});
+
+ $controls.after($(data));
+ },
+
+ // ==========
+ // = Events =
+ // ==========
+
+ next_page: function(e) {
+ var $button = $(e.currentTarget);
+ var $next = $('.NB-page-controls-text-next', $button);
+ var $loading = $('.NB-page-controls-text-loading', $button);
+ var $loaded = $('.NB-page-controls-text-loaded', $button);
+ var height = this.$('.NB-page-controls').height();
+ var innerheight = $button.height();
+
+ $loading.text('Loading...').css('bottom', height).animate({'bottom': innerheight}, {
+ 'duration': 500,
+ 'easing': 'easeInOutQuint',
+ 'queue': false
+ });
+ $next.animate({'bottom': -1 * innerheight}, {
+ 'duration': 500,
+ 'easing': 'easeInOutQuint',
+ 'queue': false
+ });
+ $button.addClass('NB-loading');
+
+ $button.animate({'backgroundColor': '#5C89C9'}, 900);
+ this.feed_stories_loading = setInterval(function() {
+ if (!$button.hasClass('NB-loaded')) return;
+ $button.animate({'backgroundColor': '#2B478C'}, {'duration': 650})
+ .animate({'backgroundColor': '#5C89C9'}, 900);
+ }, 1500);
+
+ this.page += 1;
+
+ $.ajax({
+ url: '/',
+ method: 'GET',
+ data: {
+ 'page': this.page,
+ 'format': 'html'
+ },
+ success: _.bind(this.post_next_page, this)
+ });
}
});
diff --git a/templates/social/social_page.xhtml b/templates/social/social_page.xhtml
index 37eb3b924..382f6f64a 100644
--- a/templates/social/social_page.xhtml
+++ b/templates/social/social_page.xhtml
@@ -83,83 +83,25 @@
{% for story in stories %}
-
-
-
- {% if story.feed %}
-
-

-
-
- {% endif %}
-
-
-