mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
Dynamically updating feed icons as they load.
This commit is contained in:
parent
7424dc9715
commit
58ae33fd50
5 changed files with 115 additions and 3 deletions
|
@ -152,7 +152,7 @@ def load_feeds(request):
|
|||
'active': sub.active,
|
||||
'favicon': sub.feed.icon.data,
|
||||
'favicon_color': sub.feed.icon.color,
|
||||
'favicon_finding': bool(not (sub.feed.icon.not_found or sub.feed.icon.data))
|
||||
'favicon_fetching': bool(not (sub.feed.icon.not_found or sub.feed.icon.data))
|
||||
}
|
||||
|
||||
if not sub.feed.fetched_once:
|
||||
|
@ -240,6 +240,7 @@ def refresh_feeds(request):
|
|||
feeds = {}
|
||||
user_subs = UserSubscription.objects.select_related('feed', 'feed__data').filter(user=user, active=True)
|
||||
UNREAD_CUTOFF = datetime.datetime.utcnow() - datetime.timedelta(days=settings.DAYS_OF_UNREAD)
|
||||
favicons_fetching = [int(f) for f in request.POST.getlist('favicons_fetching')]
|
||||
|
||||
for sub in user_subs:
|
||||
if (sub.needs_unread_recalc or
|
||||
|
@ -258,6 +259,10 @@ def refresh_feeds(request):
|
|||
feeds[sub.feed.pk]['exception_code'] = sub.feed.exception_code
|
||||
if request.POST.get('check_fetch_status', False):
|
||||
feeds[sub.feed.pk]['not_yet_fetched'] = not sub.feed.fetched_once
|
||||
if sub.feed.pk in favicons_fetching:
|
||||
feeds[sub.feed.pk]['favicon'] = sub.feed.icon.data
|
||||
feeds[sub.feed.pk]['favicon_color'] = sub.feed.icon.color
|
||||
feeds[sub.feed.pk]['favicon_fetching'] = bool(not (sub.feed.icon.not_found or sub.feed.icon.data))
|
||||
|
||||
return {'feeds': feeds}
|
||||
|
||||
|
|
89
apps/rss_feeds/migrations/0040_null_icon_data.py
Normal file
89
apps/rss_feeds/migrations/0040_null_icon_data.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
# 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):
|
||||
|
||||
# Changing field 'FeedIcon.data'
|
||||
db.alter_column('rss_feeds_feedicon', 'data', self.gf('django.db.models.fields.TextField')(null=True))
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Changing field 'FeedIcon.data'
|
||||
db.alter_column('rss_feeds_feedicon', 'data', self.gf('django.db.models.fields.TextField')())
|
||||
|
||||
|
||||
models = {
|
||||
'rss_feeds.duplicatefeed': {
|
||||
'Meta': {'object_name': 'DuplicateFeed'},
|
||||
'duplicate_address': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
|
||||
'duplicate_feed_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||
'feed': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'duplicate_addresses'", 'to': "orm['rss_feeds.Feed']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'rss_feeds.feed': {
|
||||
'Meta': {'ordering': "['feed_title']", 'object_name': 'Feed', 'db_table': "'feeds'"},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}),
|
||||
'active_subscribers': ('django.db.models.fields.IntegerField', [], {'default': '-1', 'db_index': 'True'}),
|
||||
'average_stories_per_month': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'creation': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'days_to_trim': ('django.db.models.fields.IntegerField', [], {'default': '90'}),
|
||||
'etag': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'exception_code': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'feed_address': ('django.db.models.fields.URLField', [], {'unique': 'True', 'max_length': '255'}),
|
||||
'feed_link': ('django.db.models.fields.URLField', [], {'default': "''", 'max_length': '1000', 'null': 'True', 'blank': 'True'}),
|
||||
'feed_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'fetched_once': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'has_feed_exception': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
|
||||
'has_page_exception': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_load_time': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'last_modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'last_update': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
|
||||
'min_to_decay': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'next_scheduled_update': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
|
||||
'num_subscribers': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
||||
'premium_subscribers': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
||||
'queued_date': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
|
||||
'stories_last_month': ('django.db.models.fields.IntegerField', [], {'default': '0'})
|
||||
},
|
||||
'rss_feeds.feeddata': {
|
||||
'Meta': {'object_name': 'FeedData'},
|
||||
'feed': ('utils.fields.AutoOneToOneField', [], {'related_name': "'data'", 'unique': 'True', 'to': "orm['rss_feeds.Feed']"}),
|
||||
'feed_tagline': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'popular_authors': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'}),
|
||||
'popular_tags': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'story_count_history': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'rss_feeds.feedicon': {
|
||||
'Meta': {'object_name': 'FeedIcon'},
|
||||
'color': ('django.db.models.fields.CharField', [], {'max_length': '6', 'null': 'True', 'blank': 'True'}),
|
||||
'data': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'feed': ('utils.fields.AutoOneToOneField', [], {'related_name': "'icon'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['rss_feeds.Feed']"}),
|
||||
'icon_url': ('django.db.models.fields.CharField', [], {'max_length': '2000', 'null': 'True', 'blank': 'True'}),
|
||||
'not_found': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
|
||||
},
|
||||
'rss_feeds.feedloadtime': {
|
||||
'Meta': {'object_name': 'FeedLoadtime'},
|
||||
'date_accessed': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'feed': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rss_feeds.Feed']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'loadtime': ('django.db.models.fields.FloatField', [], {})
|
||||
},
|
||||
'rss_feeds.feedupdatehistory': {
|
||||
'Meta': {'object_name': 'FeedUpdateHistory'},
|
||||
'average_per_feed': ('django.db.models.fields.DecimalField', [], {'max_digits': '4', 'decimal_places': '1'}),
|
||||
'fetch_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'number_of_feeds': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'seconds_taken': ('django.db.models.fields.IntegerField', [], {})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['rss_feeds']
|
|
@ -728,7 +728,7 @@ class FeedData(models.Model):
|
|||
class FeedIcon(models.Model):
|
||||
feed = AutoOneToOneField(Feed, primary_key=True, related_name='icon')
|
||||
color = models.CharField(max_length=6, blank=True, null=True)
|
||||
data = models.TextField()
|
||||
data = models.TextField(blank=True, null=True)
|
||||
icon_url = models.CharField(max_length=2000, blank=True, null=True)
|
||||
not_found = models.BooleanField(default=False)
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@ NEWSBLUR.AssetModel.Reader = function() {
|
|||
this.starred_stories = [];
|
||||
this.starred_count = 0;
|
||||
this.read_stories_river_count = 0;
|
||||
this.flags = {
|
||||
'favicons_fetching': false
|
||||
};
|
||||
|
||||
this.DEFAULT_VIEW = NEWSBLUR.Preferences.default_view || 'page';
|
||||
};
|
||||
|
@ -196,6 +199,7 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
_.each(subscriptions.feeds, function(feed, feed_id) {
|
||||
if (_.contains(valid_feeds, parseInt(feed_id, 10))) {
|
||||
self.feeds[feed_id] = feed;
|
||||
if (feed.favicon_fetching) self.flags['favicons_fetching'] = true;
|
||||
}
|
||||
});
|
||||
self.folders = subscriptions.folders;
|
||||
|
@ -339,6 +343,12 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
updated = true;
|
||||
self.feeds[f]['has_exception'] = !!feed['has_exception'];
|
||||
}
|
||||
if (feed['favicon']) {
|
||||
self.feeds[f]['favicon'] = feed['favicon'];
|
||||
self.feeds[f]['favicon_color'] = feed['favicon_color'];
|
||||
self.feeds[f]['favicon_fetching'] = false;
|
||||
updated = true;
|
||||
}
|
||||
if (updated && !(f in updated_feeds)) {
|
||||
updated_feeds.push(f);
|
||||
}
|
||||
|
@ -350,6 +360,14 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
if (has_unfetched_feeds) {
|
||||
data['check_fetch_status'] = has_unfetched_feeds;
|
||||
}
|
||||
if (this.flags['favicons_fetching']) {
|
||||
var favicons_fetching = _.compact(_.map(NEWSBLUR.reader.model.feeds, function(feed, k) {
|
||||
if (feed.favicon_fetching && feed.active) return k;
|
||||
}));
|
||||
if (favicons_fetching.length) {
|
||||
data['favicons_fetching'] = favicons_fetching;
|
||||
}
|
||||
}
|
||||
|
||||
if (NEWSBLUR.Globals.is_authenticated) {
|
||||
this.make_request('/reader/refresh_feeds', data, pre_callback);
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
'river_feeds_with_unreads': [],
|
||||
'mouse_position_y': parseInt(this.model.preference('lock_mouse_indicator'), 10)
|
||||
};
|
||||
this.FEED_REFRESH_INTERVAL = (1000 * 60) * 1; // 1 minute
|
||||
this.FEED_REFRESH_INTERVAL = (1000 * 60) * 1/4; // 1/2 minute
|
||||
|
||||
// ==================
|
||||
// = Event Handlers =
|
||||
|
|
Loading…
Add table
Reference in a new issue