Skip to content
Browse files

Adding paging on recommendations. Also moved out of profile preferenc…

…es, since it needs to be used by the base template when setting up the middle column (the column where recommended feeds go). Now a first-order column on user profiles.
  • Loading branch information...
1 parent 7a4a651 commit 4ab3904d52f2118862e06167a6472ef1ebc4382c @samuelclay committed Mar 13, 2011
View
5 apps/analyzer/views.py
@@ -25,7 +25,10 @@ def save_classifier(request):
payload = {}
# Mark subscription as dirty, so unread counts can be recalculated
- usersub = UserSubscription.objects.filter(user=request.user, feed=feed)
+ try:
+ usersub = UserSubscription.objects.get(user=request.user, feed=feed)
+ except UserSubscription.DoesNotExist:
+ usersub = None
if usersub and (not usersub.needs_unread_recalc or not usersub.is_trained):
usersub.needs_unread_recalc = True
usersub.is_trained = True
View
74 apps/profile/migrations/0011_feed_pane_size.py
@@ -0,0 +1,74 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding field 'Profile.feed_pane_size'
+ db.add_column('profile_profile', 'feed_pane_size', self.gf('django.db.models.fields.IntegerField')(default=240), keep_default=False)
+
+
+ def backwards(self, orm):
+
+ # Deleting field 'Profile.feed_pane_size'
+ db.delete_column('profile_profile', 'feed_pane_size')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'profile.profile': {
+ 'Meta': {'object_name': 'Profile'},
+ 'collapsed_folders': ('django.db.models.fields.TextField', [], {'default': "'[]'"}),
+ 'feed_pane_size': ('django.db.models.fields.IntegerField', [], {'default': '240'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_premium': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_seen_ip': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'last_seen_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'preferences': ('django.db.models.fields.TextField', [], {'default': "'{}'"}),
+ 'secret_token': ('django.db.models.fields.CharField', [], {'max_length': '12', 'null': 'True', 'blank': 'True'}),
+ 'timezone': ('utils.timezones.fields.TimeZoneField', [], {'default': "'America/New_York'", 'max_length': '100'}),
+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"}),
+ 'view_settings': ('django.db.models.fields.TextField', [], {'default': "'{}'"})
+ }
+ }
+
+ complete_apps = ['profile']
View
78 apps/profile/migrations/0012_feed_pane_size_json.py
@@ -0,0 +1,78 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+from utils import json_functions as json
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ for profile in orm.Profile.objects.all():
+ if 'feed_pane_size' in profile.preferences:
+ preferences = json.decode(profile.preferences)
+ feed_pane_size = int(preferences.get('feed_pane_size', 240))
+ del preferences['feed_pane_size']
+ print " --> User %s: %s" % (profile.user.username, feed_pane_size)
+ profile.feed_pane_size = feed_pane_size
+ profile.preferences = json.encode(preferences)
+ profile.save()
+
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'profile.profile': {
+ 'Meta': {'object_name': 'Profile'},
+ 'collapsed_folders': ('django.db.models.fields.TextField', [], {'default': "'[]'"}),
+ 'feed_pane_size': ('django.db.models.fields.IntegerField', [], {'default': '240'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_premium': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_seen_ip': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'last_seen_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'preferences': ('django.db.models.fields.TextField', [], {'default': "'{}'"}),
+ 'secret_token': ('django.db.models.fields.CharField', [], {'max_length': '12', 'null': 'True', 'blank': 'True'}),
+ 'timezone': ('utils.timezones.fields.TimeZoneField', [], {'default': "'America/New_York'", 'max_length': '100'}),
+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"}),
+ 'view_settings': ('django.db.models.fields.TextField', [], {'default': "'{}'"})
+ }
+ }
+
+ complete_apps = ['profile']
View
1 apps/profile/models.py
@@ -20,6 +20,7 @@ class Profile(models.Model):
preferences = models.TextField(default="{}")
view_settings = models.TextField(default="{}")
collapsed_folders = models.TextField(default="[]")
+ feed_pane_size = models.IntegerField(default=240)
last_seen_on = models.DateTimeField(default=datetime.datetime.now)
last_seen_ip = models.CharField(max_length=50, blank=True, null=True)
timezone = TimeZoneField(default="America/New_York")
View
2 apps/profile/views.py
@@ -12,7 +12,7 @@
from apps.profile.models import Profile, change_password
from apps.reader.models import UserSubscription
-SINGLE_FIELD_PREFS = ('timezone',)
+SINGLE_FIELD_PREFS = ('timezone','feed_pane_size')
SPECIAL_PREFERENCES = ('old_password', 'new_password',)
@ajax_login_required
View
6 apps/reader/views.py
@@ -729,6 +729,10 @@ def delete_feed(request):
user_sub_folders = get_object_or_404(UserSubscriptionFolders, user=request.user)
user_sub_folders.delete_feed(feed_id, in_folder)
+ feed = Feed.objects.filter(pk=feed_id)
+ if feed:
+ feed[0].count_subscribers()
+
return dict(code=1)
@ajax_login_required
@@ -793,7 +797,7 @@ def add_feature(request):
@json.json_view
def load_features(request):
page = int(request.POST.get('page', 0))
- logging.user(request.user, "~FBBrowse features: Page #%s" % (page+1))
+ logging.user(request.user, "~FBBrowse features: ~SBPage #%s" % (page+1))
features = Feature.objects.all()[page*3:(page+1)*3+1].values()
features = [{
'description': f['description'],
View
6 apps/recommendations/templatetags/recommendations_tags.py
@@ -7,12 +7,14 @@
@register.inclusion_tag('recommendations/render_recommended_feed.xhtml', takes_context=True)
def render_recommended_feed(context, recommended_feed):
user = get_user(context['user'])
-
+
usersub = UserSubscription.objects.filter(user=user, feed=recommended_feed.feed)
if recommended_feed.feed:
return {
'recommended_feed': recommended_feed,
'usersub': usersub,
'user': context['user'],
- }
+ 'has_next_page': True
+ }
+
View
6 apps/recommendations/urls.py
@@ -0,0 +1,6 @@
+from django.conf.urls.defaults import *
+from apps.recommendations import views
+
+urlpatterns = patterns('',
+ url(r'^load_recommended_feed', views.load_recommended_feed, name='load-recommended-feed'),
+)
View
27 apps/recommendations/views.py
@@ -1 +1,26 @@
-# Create your views here.
+from utils import log as logging
+from django.template import RequestContext
+from django.shortcuts import render_to_response
+from apps.recommendations.models import RecommendedFeed
+from apps.reader.models import UserSubscription
+# from utils import json_functions as json
+from utils.user_functions import get_user
+
+
+def load_recommended_feed(request):
+ user = get_user(request)
+ page = int(request.REQUEST.get('page', 0))
+ usersub = None
+
+ recommended_feeds = RecommendedFeed.objects.all()[page:page+2]
+ if recommended_feeds:
+ usersub = UserSubscription.objects.filter(user=user, feed=recommended_feeds[0].feed)
+ print recommended_feeds, len(recommended_feeds)
+ logging.user(request.user, "~FBBrowse recommended feed: ~SBPage #%s" % (page+1))
+
+ return render_to_response('recommendations/render_recommended_feed.xhtml', {
+ 'recommended_feed' : recommended_feeds and recommended_feeds[0],
+ 'usersub' : usersub,
+ 'has_next_page' : len(recommended_feeds) > 1,
+ 'has_previous_page' : page != 0,
+ }, context_instance=RequestContext(request))
View
59 media/css/reader.css
@@ -673,24 +673,24 @@ body.NB-theme-serif #story_pane .NB-feed-story-content {
text-shadow: none;
}
-.NB-feedlist-hide-read-feeds .feed {
+.NB-feedlist-hide-read-feeds #feed_list .feed {
display: none;
}
-.NB-feedlist-hide-read-feeds .unread_view_positive .unread_positive {
+.NB-feedlist-hide-read-feeds #feed_list.unread_view_positive .unread_positive {
display: block;
}
-.NB-feedlist-hide-read-feeds .unread_view_neutral .unread_positive,
-.NB-feedlist-hide-read-feeds .unread_view_neutral .unread_neutral {
+.NB-feedlist-hide-read-feeds #feed_list.unread_view_neutral .unread_positive,
+.NB-feedlist-hide-read-feeds #feed_list.unread_view_neutral .unread_neutral {
display: block;
}
-.NB-feedlist-hide-read-feeds .unread_view_negative .unread_positive,
-.NB-feedlist-hide-read-feeds .unread_view_negative .unread_neutral,
-.NB-feedlist-hide-read-feeds .unread_view_negative .unread_negative {
+.NB-feedlist-hide-read-feeds #feed_list.unread_view_negative .unread_positive,
+.NB-feedlist-hide-read-feeds #feed_list.unread_view_negative .unread_neutral,
+.NB-feedlist-hide-read-feeds #feed_list.unread_view_negative .unread_negative {
display: block;
}
-.NB-feedlist-hide-read-feeds .feed.NB-empty {
+.NB-feedlist-hide-read-feeds #feed_list .feed.NB-empty {
display: block;
}
@@ -1878,7 +1878,7 @@ background: transparent;
color: #FFF;
height: 15px;
font-size: 11px;
- padding: 2px 6px 2px 0;
+ padding: 0 0 2px 0;
text-transform: uppercase;
text-shadow: 0 1px 0 #303030;
border-bottom: 1px solid #E9E9E9;
@@ -1897,6 +1897,7 @@ background: transparent;
.NB-feeds-header .NB-feeds-header-left {
float: left;
color: #FFF;
+ padding-top: 1px;
}
.NB-feeds-header .NB-feeds-header-count {
@@ -1922,6 +1923,12 @@ background: transparent;
.NB-feeds-header .NB-feeds-header-sites {
float: right;
cursor: pointer;
+ padding-right: 16px;
+ padding-top: 1px;
+ background: transparent url('../img/icons/silk/bullet_orange.png') no-repeat right 0;
+}
+.NB-feedlist-hide-read-feeds .NB-feeds-header .NB-feeds-header-sites {
+ background-image: url('../img/icons/silk/bullet_blue.png');
}
.NB-feeds-header .NB-feeds-header-sites:hover {
color: #5E7B88;
@@ -1931,7 +1938,7 @@ background: transparent;
}
.NB-feeds-header .NB-feeds-header-home {
display: none;
- padding: 0 0 0 4px;
+ padding: 1px 0 0 4px;
color: #7493C7;
}
.NB-feeds-header.NB-active:hover {
@@ -3230,43 +3237,48 @@ background: transparent;
.NB-module .NB-module-direction {
display: block;
- width: 16px;
- height: 16px;
+ width: 24px;
+ height: 32px;
float: right;
- padding: 0 3px 0px;
+ margin: -8px 0;
+ padding: 0px;
}
.NB-module .NB-module-direction.NB-disabled {
opacity: .25;
}
.NB-module .NB-module-next-page {
- background: transparent url('../img/icons/silk/control_play_blue.png') no-repeat center center;
+ margin-right: -12px;
+ padding-right: 8px;
+
+ background: transparent url('../img/icons/silk/control_play_blue.png') no-repeat 4px center;
}
.NB-module .NB-module-next-page.NB-javascript {
opacity: .2;
}
.NB-module .NB-module-next-page:link {
- background: transparent url('../img/icons/silk/control_play.png') no-repeat center center;
+ background: transparent url('../img/icons/silk/control_play.png') no-repeat 4px center;
}
.NB-module .NB-module-next-page:hover {
- background: transparent url('../img/icons/silk/control_play_blue.png') no-repeat center center;
+ background: transparent url('../img/icons/silk/control_play_blue.png') no-repeat 4px center;
}
.NB-module .NB-module-next-page.NB-disabled:hover {
- background: transparent url('../img/icons/silk/control_play.png') no-repeat center center;
+ background: transparent url('../img/icons/silk/control_play.png') no-repeat 4px center;
cursor: default;
}
.NB-module .NB-module-previous-page {
- background: transparent url('../img/icons/silk/control_play_left_blue.png') no-repeat center center;
+ padding-left: 4px;
+ background: transparent url('../img/icons/silk/control_play_left_blue.png') no-repeat 8px center;
}
.NB-module .NB-module-previous-page:link {
- background: transparent url('../img/icons/silk/control_play_left.png') no-repeat center center;
+ background: transparent url('../img/icons/silk/control_play_left.png') no-repeat 8px center;
}
.NB-module .NB-module-previous-page:hover {
- background: transparent url('../img/icons/silk/control_play_left_blue.png') no-repeat center center;
+ background: transparent url('../img/icons/silk/control_play_left_blue.png') no-repeat 8px center;
}
.NB-module .NB-module-previous-page.NB-disabled:hover {
- background: transparent url('../img/icons/silk/control_play_left.png') no-repeat center center;
+ background: transparent url('../img/icons/silk/control_play_left.png') no-repeat 8px center;
cursor: default;
}
@@ -3551,9 +3563,8 @@ background: transparent;
/* ================== */
.NB-modules-center {
- margin-left: 284px;
- margin-right: 478px;
- padding: 24px;
+ margin: 55px 478px 0 284px;
+ padding: 24px;
}
/* ============================ */
View
4 media/js/newsblur/assetmodel.js
@@ -656,6 +656,10 @@ NEWSBLUR.AssetModel.Reader.prototype = {
this.make_request('/reader/load_features', {'page': page}, callback);
},
+ load_recommended_feed: function(page, callback) {
+ this.make_request('/recommendations/load_recommended_feed', {'page': page}, callback);
+ },
+
save_feed_order: function(folders, callback) {
this.make_request('/reader/save_feed_order', {'folders': $.toJSON(folders)}, callback);
},
View
49 media/js/newsblur/reader.js
@@ -43,7 +43,8 @@
'feature_page': 0,
'unfetched_feeds': 0,
'fetched_feeds': 0,
- 'page_fill_outs': 0
+ 'page_fill_outs': 0,
+ 'recommended_feed_page': 0
};
this.cache = {
'iframe_stories': {},
@@ -138,6 +139,10 @@
closable: false,
fxName: "scale",
fxSettings: { duration: 500, easing: "easeInOutQuint" },
+ north__paneSelector: ".left-north",
+ north__size: 18,
+ north__resizeable: false,
+ north__spacing_open: 0,
center__paneSelector: ".left-center",
center__resizable: false,
south__paneSelector: ".left-south",
@@ -3246,7 +3251,7 @@
$.make('div', { className: 'NB-feed-story-premium-only-divider'}),
$.make('div', { className: 'NB-feed-story-premium-only-text'}, [
'The full River of News is a ',
- $.make('a', { href: '#' }, 'premium feature'),
+ $.make('a', { href: '#', className: 'NB-splash-link' }, 'premium feature'),
'.'
])
]);
@@ -4122,10 +4127,10 @@
if (NEWSBLUR.Preferences['hide_read_feeds'] == 1) {
$hidereadfeeds_button.attr('title', 'Show all sites');
- $feed_list.parent().addClass('NB-feedlist-hide-read-feeds');
+ this.$s.$body.addClass('NB-feedlist-hide-read-feeds');
} else {
$hidereadfeeds_button.attr('title', 'Show only unread stories');
- $feed_list.parent().removeClass('NB-feedlist-hide-read-feeds');
+ this.$s.$body.removeClass('NB-feedlist-hide-read-feeds');
}
$hidereadfeeds_button.tipsy({
gravity: 'n',
@@ -4562,24 +4567,19 @@
var $next = $('.NB-module-features .NB-module-next-page');
var $previous = $('.NB-module-features .NB-module-previous-page');
- $module.removeClass('NB-loaded');
- _.delay(function() {
- if (!$module.hasClass('NB-loaded')) {
- $module.addClass('NB-loading');
- }
- }, 50);
+ $module.addClass('NB-loading');
if (direction == -1 && !this.counts['feature_page']) {
- $module.addClass('NB-loaded');
+ $module.removeClass('NB-loading');
return;
}
if (direction == 1 && this.flags['features_last_page']) {
- $module.addClass('NB-loaded');
+ $module.removeClass('NB-loading');
return;
}
this.model.get_features_page(this.counts['feature_page']+direction, function(features) {
- $('.NB-module-features').addClass('NB-loaded').removeClass('NB-loading');
+ $module.removeClass('NB-loading');
self.counts['feature_page'] += direction;
var $table = $.make('table', { cellSpacing: 0, cellPadding: 0 });
@@ -4796,12 +4796,19 @@
this.open_add_feed_modal({url: feed.feed_address});
},
- load_next_feed_in_recommended_feeds: function() {
-
- },
-
- load_previous_feed_in_recommended_feeds: function() {
+ load_recommended_feed: function(direction) {
+ var self = this;
+ var $module = $('.NB-module-recommended');
+ $module.addClass('NB-loading');
+ direction = direction || 0;
+ this.model.load_recommended_feed(this.counts['recommended_feed_page']+direction, function(resp) {
+ self.counts['recommended_feed_page'] += direction;
+
+ $module.removeClass('NB-loading');
+ $module.replaceWith(resp);
+ self.load_javascript_elements_on_page();
+ });
},
// ==========
@@ -5234,13 +5241,15 @@
$.targetIs(e, { tagSelector: '.NB-module-recommended .NB-module-next-page' }, function($t, $p){
e.preventDefault();
- self.load_next_feed_in_recommended_feeds();
+ if (!$t.hasClass('NB-disabled')) {
+ self.load_recommended_feed(1);
+ }
});
$.targetIs(e, { tagSelector: '.NB-module-recommended .NB-module-previous-page' }, function($t, $p){
e.preventDefault();
if (!$t.hasClass('NB-disabled')) {
- self.load_previous_feed_in_recommended_feeds();
+ self.load_recommended_feed(-1);
}
});
View
2 media/js/newsblur/reader_add_feed.js
@@ -250,6 +250,7 @@ NEWSBLUR.ReaderAddFeed.prototype = {
{
$loading.removeClass('NB-active');
NEWSBLUR.reader.load_feeds();
+ NEWSBLUR.reader.load_recommended_feed();
$.modal.close();
},
error: function (data, status, e)
@@ -303,6 +304,7 @@ NEWSBLUR.ReaderAddFeed.prototype = {
if (data.code > 0) {
NEWSBLUR.reader.load_feeds();
+ NEWSBLUR.reader.load_recommended_feed();
NEWSBLUR.reader.handle_mouse_indicator_hover();
$.modal.close();
} else {
View
56 templates/base.html
@@ -9,41 +9,41 @@
<script type="text/javascript" charset="utf-8">
var NEWSBLUR = {};
NEWSBLUR.Globals = {
- 'is_authenticated': {{ user.is_authenticated|yesno:"true,false" }},
- 'is_anonymous': {{ user.is_anonymous|yesno:"true,false" }},
- 'is_premium': {{ user.profile.is_premium|yesno:"true,false" }},
- 'secret_token': "{{ user.profile.secret_token }}",
- 'username': "{{ user.username|safe }}",
- 'google_favicon_url': 'http://www.google.com/s2/favicons?domain_url=',
- 'MEDIA_URL': "{{ MEDIA_URL }}"
+ 'is_authenticated' : {{ user.is_authenticated|yesno:"true,false" }},
+ 'is_anonymous' : {{ user.is_anonymous|yesno:"true,false" }},
+ 'is_premium' : {{ user.profile.is_premium|yesno:"true,false" }},
+ 'secret_token' : "{{ user.profile.secret_token }}",
+ 'username' : "{{ user.username|safe }}",
+ 'google_favicon_url' : 'http://www.google.com/s2/favicons?domain_url=',
+ 'MEDIA_URL' : "{{ MEDIA_URL }}"
};
NEWSBLUR.Flags = {
'start_import_from_google_reader': {{ start_import_from_google_reader|yesno:"true,false" }}
};
NEWSBLUR.Preferences = {
- 'unread_view': 0,
- 'lock_mouse_indicator': 0,
- 'feed_pane_size': 240,
- 'story_titles_pane_size': 168,
- 'new_window': 1,
- 'default_view': 'page',
- 'hide_read_feeds': 0,
- 'feed_view_single_story': 0,
- 'view_settings': {},
- 'collapsed_folders': [],
- 'story_styling': 'sans-serif',
- 'timezone': "{{ user_profile.timezone }}",
- 'story_share_twitter': true,
- 'story_share_facebook': true,
- 'story_share_readitlater': false,
- 'story_share_instapaper': true,
- 'story_share_readability': true
+ 'unread_view' : 0,
+ 'lock_mouse_indicator' : 0,
+ 'feed_pane_size' : {{ user_profile.feed_pane_size }},
+ 'story_titles_pane_size' : 168,
+ 'new_window' : 1,
+ 'default_view' : 'page',
+ 'hide_read_feeds' : 0,
+ 'feed_view_single_story' : 0,
+ 'view_settings' : {},
+ 'collapsed_folders' : [],
+ 'story_styling' : 'sans-serif',
+ 'timezone' : "{{ user_profile.timezone }}",
+ 'story_share_twitter' : true,
+ 'story_share_facebook' : true,
+ 'story_share_readitlater' : false,
+ 'story_share_instapaper' : true,
+ 'story_share_readability' : true
};
NEWSBLUR.URLs = {
- 'google-reader-authorize': "{% url google-reader-authorize %}",
- 'opml-upload': "{% url opml-upload %}",
- 'opml-export': "{% url opml-export %}",
- 'domain': "{% current_domain %}"
+ 'google-reader-authorize' : "{% url google-reader-authorize %}",
+ 'opml-upload' : "{% url opml-upload %}",
+ 'opml-export' : "{% url opml-export %}",
+ 'domain' : "{% current_domain %}"
};
</script>
View
27 templates/reader/feeds.xhtml
@@ -26,7 +26,7 @@ $(document).ready(function() {
</ul>
</div>
- <div class="NB-modules-center">
+ <div class="NB-modules-center" style="margin-left: {{ user.profile.feed_pane_size }}px">
{% if recommended_feed %}
{% render_recommended_feed recommended_feed %}
{% endif %}
@@ -329,23 +329,26 @@ $(document).ready(function() {
<div class="left-pane">
+
+ <div class="left-north">
+ <div class="NB-feeds-header">
+ <div class="NB-feeds-header-right">
+ <div class="NB-feeds-header-sites">&nbsp;</div>
+ </div>
+ <div class="NB-feeds-header-left">
+ <span class="NB-feeds-header-count NB-feeds-header-negative NB-empty">0</span>
+ <span class="NB-feeds-header-count NB-feeds-header-neutral NB-empty">0</span>
+ <span class="NB-feeds-header-count NB-feeds-header-positive NB-empty">0</span>
+ </div>
+ <div class="NB-feeds-header-home">Dashboard</div>
+ </div>
+ </div>
<div class="left-center">
<div class="left-center-content NB-feedlist">
<div id="NB-feeds-list-loader">Everything is on its way...</div>
<div class="NB-feeds-header-container">
- <div class="NB-feeds-header">
- <div class="NB-feeds-header-right">
- <div class="NB-feeds-header-sites">&nbsp;</div>
- </div>
- <div class="NB-feeds-header-left">
- <span class="NB-feeds-header-count NB-feeds-header-negative NB-empty">0</span>
- <span class="NB-feeds-header-count NB-feeds-header-neutral NB-empty">0</span>
- <span class="NB-feeds-header-count NB-feeds-header-positive NB-empty">0</span>
- </div>
- <div class="NB-feeds-header-home">Dashboard</div>
- </div>
<div class="NB-feeds-header-river-container">
<div class="NB-feeds-header-river NB-empty">
<div class="NB-feeds-header-river-count unread_count"></div>
View
4 templates/recommendations/render_recommended_feed.xhtml
@@ -2,8 +2,8 @@
<h5 class="NB-module-header">
Recommended Site
<div class="NB-module-header-right">
- <a href="#" class="NB-module-direction NB-module-next-page NB-javascript"></a>
- <a href="#" class="NB-module-direction NB-module-previous-page NB-disabled"></a>
+ <a href="#" class="NB-module-direction NB-module-next-page NB-javascript {% if not has_next_page %}NB-disabled{% endif %}"></a>
+ <a href="#" class="NB-module-direction NB-module-previous-page {% if not has_previous_page %}NB-disabled{% endif %}"></a>
<div class="NB-spinner NB-left"></div>
<div class="NB-module-recommended-date">
{{ recommended_feed.approved_date|date:"M j" }}
View
1 urls.py
@@ -10,6 +10,7 @@
(r'^profile/', include('apps.profile.urls')),
(r'^import/', include('apps.feed_import.urls')),
(r'^api/', include('apps.api.urls')),
+ (r'^recommendations/', include('apps.recommendations.urls')),
)
if settings.DEVELOPMENT:

0 comments on commit 4ab3904

Please sign in to comment.
Something went wrong with that request. Please try again.