mirror of
https://github.com/viq/NewsBlur.git
synced 2025-09-18 21:43:31 +00:00
Adding paging to blurblogs. Fancy animations and color changes make for a funner experience.
This commit is contained in:
parent
afb102e4e7
commit
75c7d1960c
8 changed files with 276 additions and 76 deletions
|
@ -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 {
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -950,3 +950,67 @@ header {
|
|||
-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;
|
||||
}
|
|
@ -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)
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -83,83 +83,25 @@
|
|||
</header>
|
||||
|
||||
{% for story in stories %}
|
||||
<div class="NB-mark">
|
||||
<div class="NB-divider"></div>
|
||||
<div class="NB-feed NB-feed-{{ story.feed.favicon_text_color }}" style="
|
||||
background-image: -webkit-gradient( linear, left bottom, left top, color-stop(0.16, #{{ story.feed.favicon_color }}), color-stop(0.84, #{{ story.feed.favicon_fade }}) );
|
||||
background-image: -moz-linear-gradient( center bottom, #{{ story.feed.favicon_color }} 16%, #{{ story.feed.favicon_fade }} 84% );
|
||||
border: 1px solid #{{ story.feed.favicon_border }};
|
||||
">
|
||||
{% if story.feed %}
|
||||
<div class="NB-feed-favicon">
|
||||
<img src="{{ story.feed.favicon_url }}" />
|
||||
</div>
|
||||
<div class="NB-feed-title">
|
||||
<a href="/site/{{ story.feed.id }}/">{{ story.feed.feed_title }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="NB-story-header-wrapper">
|
||||
<div class="NB-story-header">
|
||||
{% if story.story_authors %}
|
||||
<div class="NB-story-author">{{ story.story_authors }}</div>
|
||||
{% endif %}
|
||||
{% if story.story_tags %}
|
||||
<div class="NB-story-tags">
|
||||
{% for story_tag in story.story_tags %}
|
||||
<div class="NB-story-tag">{{ story_tag }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="NB-story-title">
|
||||
<a href="{{ story.story_permalink }}">{{ story.story_title }}</a>
|
||||
</div>
|
||||
<div class="NB-story-date">
|
||||
{% if story.has_modifications %}
|
||||
<div class="NB-story-modifications-button" title="Show story changes"></div>
|
||||
{% endif %}
|
||||
|
||||
{{ story.shared_date|date:"D F j<\s\u\p>S</\s\u\p>, Y"|safe }}
|
||||
<span class="NB-story-date-break"></span>
|
||||
<small>at</small>
|
||||
{{ story.shared_date|date:"g:i A"|safe }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="NB-story {% if story.saved %}NB-story-saved{% endif %} {% if story.shared_by_user %}NB-story-shared{% endif %}" data-feed-id="{{ story.story_feed_id }}" data-story-id="{{ story.id }}" {% if story.user_comments %}data-user-comments="{{ story.user_comments }}"{% endif %}>
|
||||
<div class="NB-story-content">
|
||||
{{ story.story_content|safe }}
|
||||
<div class="NB-feed-story-sideoptions-container">
|
||||
{% if user.is_authenticated %}
|
||||
<div class="NB-sideoption NB-feed-story-save">
|
||||
<div class="NB-sideoption-icon"> </div>
|
||||
<div class="NB-sideoption-title">{% if story.saved %}Saved{% else %}Save this story{% endif %}</div>
|
||||
</div>
|
||||
<div class="NB-sideoption NB-feed-story-share">
|
||||
<div class="NB-sideoption-icon"> </div>
|
||||
<div class="NB-sideoption-title">{% if story.shared_by_user %}Shared{% else %}Post to Blurblog{% endif %}</div>
|
||||
</div>
|
||||
<div class="NB-feed-story-share-container"></div>
|
||||
{% else %}
|
||||
<div class="NB-sideoption NB-feed-story-login">
|
||||
<div class="NB-sideoption-icon"> </div>
|
||||
<div class="NB-sideoption-title">Login to share</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="NB-story-comments-container">
|
||||
{% if story.share_count %}
|
||||
{% render_story_share story %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% render_social_story story %}
|
||||
{% endfor %}
|
||||
|
||||
{% if has_next_page %}
|
||||
<div class="NB-page-controls">
|
||||
<div class="NB-page-controls-next">
|
||||
<div class="NB-page-controls-text NB-page-controls-text-next">
|
||||
Next Page of Stories
|
||||
</div>
|
||||
<div class="NB-page-controls-text NB-page-controls-text-loading"></div>
|
||||
<div class="NB-page-controls-text NB-page-controls-text-loaded">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<footer>
|
||||
NewsBlur
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
{% include_javascripts "blurblog" %}
|
||||
|
|
18
templates/social/social_stories.xhtml
Normal file
18
templates/social/social_stories.xhtml
Normal file
|
@ -0,0 +1,18 @@
|
|||
{% load social_tags %}
|
||||
|
||||
{% for story in stories %}
|
||||
{% render_social_story story %}
|
||||
{% endfor %}
|
||||
|
||||
{% if has_next_page %}
|
||||
<div class="NB-page-controls">
|
||||
<div class="NB-page-controls-next">
|
||||
<div class="NB-page-controls-text NB-page-controls-text-next">
|
||||
Next Page of Stories
|
||||
</div>
|
||||
<div class="NB-page-controls-text NB-page-controls-text-loading"></div>
|
||||
<div class="NB-page-controls-text NB-page-controls-text-loaded">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
77
templates/social/social_story.xhtml
Normal file
77
templates/social/social_story.xhtml
Normal file
|
@ -0,0 +1,77 @@
|
|||
{% load utils_tags social_tags %}
|
||||
|
||||
<div class="NB-mark">
|
||||
<div class="NB-divider"></div>
|
||||
<div class="NB-feed NB-feed-{{ story.feed.favicon_text_color }}" style="
|
||||
background-image: -webkit-gradient( linear, left bottom, left top, color-stop(0.16, #{{ story.feed.favicon_color }}), color-stop(0.84, #{{ story.feed.favicon_fade }}) );
|
||||
background-image: -moz-linear-gradient( center bottom, #{{ story.feed.favicon_color }} 16%, #{{ story.feed.favicon_fade }} 84% );
|
||||
border: 1px solid #{{ story.feed.favicon_border }};
|
||||
">
|
||||
{% if story.feed %}
|
||||
<div class="NB-feed-favicon">
|
||||
<img src="{{ story.feed.favicon_url }}" />
|
||||
</div>
|
||||
<div class="NB-feed-title">
|
||||
<a href="/site/{{ story.feed.id }}/">{{ story.feed.feed_title }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="NB-story-header-wrapper">
|
||||
<div class="NB-story-header">
|
||||
{% if story.story_authors %}
|
||||
<div class="NB-story-author">{{ story.story_authors }}</div>
|
||||
{% endif %}
|
||||
{% if story.story_tags %}
|
||||
<div class="NB-story-tags">
|
||||
{% for story_tag in story.story_tags %}
|
||||
<div class="NB-story-tag">{{ story_tag }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="NB-story-title">
|
||||
<a href="{{ story.story_permalink }}">{{ story.story_title }}</a>
|
||||
</div>
|
||||
<div class="NB-story-date">
|
||||
{% if story.has_modifications %}
|
||||
<div class="NB-story-modifications-button" title="Show story changes"></div>
|
||||
{% endif %}
|
||||
|
||||
{{ story.shared_date|date:"D F j<\s\u\p>S</\s\u\p>, Y"|safe }}
|
||||
<span class="NB-story-date-break"></span>
|
||||
<small>at</small>
|
||||
{{ story.shared_date|date:"g:i A"|safe }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="NB-story {% if story.saved %}NB-story-saved{% endif %} {% if story.shared_by_user %}NB-story-shared{% endif %}" data-feed-id="{{ story.story_feed_id }}" data-story-id="{{ story.id }}" {% if story.user_comments %}data-user-comments="{{ story.user_comments }}"{% endif %}>
|
||||
<div class="NB-story-content">
|
||||
{{ story.story_content|safe }}
|
||||
<div class="NB-feed-story-sideoptions-container">
|
||||
{% if user.is_authenticated %}
|
||||
<div class="NB-sideoption NB-feed-story-save">
|
||||
<div class="NB-sideoption-icon"> </div>
|
||||
<div class="NB-sideoption-title">{% if story.saved %}Saved{% else %}Save this story{% endif %}</div>
|
||||
</div>
|
||||
<div class="NB-sideoption NB-feed-story-share">
|
||||
<div class="NB-sideoption-icon"> </div>
|
||||
<div class="NB-sideoption-title">{% if story.shared_by_user %}Shared{% else %}Post to Blurblog{% endif %}</div>
|
||||
</div>
|
||||
<div class="NB-feed-story-share-container"></div>
|
||||
{% else %}
|
||||
<div class="NB-sideoption NB-feed-story-login">
|
||||
<div class="NB-sideoption-icon"> </div>
|
||||
<div class="NB-sideoption-title">Login to share</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="NB-story-comments-container">
|
||||
{% if story.share_count %}
|
||||
{% render_story_share story %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Loading…
Add table
Reference in a new issue