mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-08-31 21:41:33 +00:00

* master: (24 commits) Skipping google alerts. Fixing a couple exceptions and turning off google news rss feeds temporarily. Moving goodies images out of css. New ReadKit image. Adding permalink blurblog option. Also adding feed title to unmessaged shares. Moving from X-Real-IP to X-Forwarded-For. Was using ad hoc and not in house provisioning profile. Switching provisioning profiles again. Switching to enterprise provisioning profile. Fixing provisioning profile. Putting out v2.4.4 as a RC. Fixing friend user ids when marking stories as read. Fixing auto-selection of feeds in feed chooser. Moving to simpler read story endpoint. Switching provisioning profiles for the year. New enterprise build -> 2.4.4. Can be considered an RC1. New notifier progress bar. Adding messaging to training while offline in both trainer view controller and story detail view controller. Users work while offline. Also adding messaging for offline sharing/replying errors. Fixing mismatch when marking stories as read when offline. Allowing single subscriber feeds to be seen, as it prevented tryfeeds from working. ...
429 lines
No EOL
15 KiB
JavaScript
429 lines
No EOL
15 KiB
JavaScript
NEWSBLUR.Models.Story = Backbone.Model.extend({
|
|
|
|
initialize: function() {
|
|
this.bind('change:selected', this.change_selected);
|
|
this.bind('change:shared_comments', this.populate_comments);
|
|
this.bind('change:comments', this.populate_comments);
|
|
this.bind('change:comment_count', this.populate_comments);
|
|
this.bind('change:starred', this.change_starred);
|
|
this.bind('change:user_tags', this.change_user_tags);
|
|
this.populate_comments();
|
|
this.story_permalink = this.get('story_permalink');
|
|
this.story_title = this.get('story_title');
|
|
},
|
|
|
|
populate_comments: function(story, collection) {
|
|
this.friend_comments = new NEWSBLUR.Collections.Comments(this.get('friend_comments'));
|
|
this.public_comments = new NEWSBLUR.Collections.Comments(this.get('public_comments'));
|
|
},
|
|
|
|
score: function() {
|
|
if (NEWSBLUR.reader.flags['starred_view']) {
|
|
return 1;
|
|
} else {
|
|
return NEWSBLUR.utils.compute_story_score(this);
|
|
}
|
|
},
|
|
|
|
score_name: function(score) {
|
|
score = !_.isUndefined(score) ? score : this.score();
|
|
var score_name = 'neutral';
|
|
if (score > 0) score_name = 'positive';
|
|
if (score < 0) score_name = 'negative';
|
|
return score_name;
|
|
},
|
|
|
|
has_modifications: function() {
|
|
if (this.get('story_content').indexOf('<ins') != -1 ||
|
|
this.get('story_content').indexOf('<del') != -1) {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
|
|
mark_read: function(options) {
|
|
return NEWSBLUR.assets.stories.mark_read(this, options);
|
|
},
|
|
|
|
open_story_in_new_tab: function(background) {
|
|
this.mark_read({skip_delay: true});
|
|
|
|
if (background && !$.browser.mozilla) {
|
|
var anchor, event;
|
|
|
|
anchor = document.createElement("a");
|
|
anchor.href = this.get('story_permalink');
|
|
event = document.createEvent("MouseEvents");
|
|
event.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, true, false, false, true, 0, null);
|
|
return anchor.dispatchEvent(event);
|
|
} else {
|
|
window.open(this.get('story_permalink'), '_blank');
|
|
window.focus();
|
|
}
|
|
},
|
|
|
|
open_share_dialog: function(e, view) {
|
|
if (view == 'title') {
|
|
var $story_title = this.story_title_view.$st;
|
|
this.story_title_view.mouseenter_manage_icon();
|
|
NEWSBLUR.reader.show_manage_menu('story', $story_title, {story_id: this.id});
|
|
NEWSBLUR.reader.show_confirm_story_share_menu_item(this.id);
|
|
} else {
|
|
var $story = this.latest_story_detail_view.$el;
|
|
this.latest_story_detail_view.share_view.toggle_feed_story_share_dialog({
|
|
animate_scroll: true
|
|
});
|
|
}
|
|
},
|
|
|
|
change_selected: function(model, selected) {
|
|
if (model.collection) {
|
|
model.collection.detect_selected_story(model, selected);
|
|
}
|
|
},
|
|
|
|
// =================
|
|
// = Saved Stories =
|
|
// =================
|
|
|
|
toggle_starred: function() {
|
|
this.set('user_tags', this.existing_tags(), {silent: true});
|
|
|
|
if (!this.get('starred')) {
|
|
NEWSBLUR.assets.starred_count += 1;
|
|
this.set('starred', true);
|
|
} else {
|
|
NEWSBLUR.assets.starred_count -= 1;
|
|
this.set('starred', false);
|
|
}
|
|
NEWSBLUR.reader.update_starred_count();
|
|
},
|
|
|
|
change_starred: function() {
|
|
if (this.get('starred')) {
|
|
NEWSBLUR.assets.mark_story_as_starred(this.id);
|
|
} else {
|
|
NEWSBLUR.assets.mark_story_as_unstarred(this.id);
|
|
}
|
|
},
|
|
|
|
change_user_tags: function(tags, options, etc) {
|
|
NEWSBLUR.assets.mark_story_as_starred(this.id);
|
|
},
|
|
|
|
existing_tags: function() {
|
|
var tags = this.get('user_tags');
|
|
|
|
if (!tags) {
|
|
tags = this.folder_tags();
|
|
}
|
|
|
|
return tags || [];
|
|
},
|
|
|
|
unused_story_tags: function() {
|
|
var tags = _.reduce(this.get('user_tags') || [], function(m, t) {
|
|
return _.without(m, t);
|
|
}, this.get('story_tags'));
|
|
return tags;
|
|
},
|
|
|
|
folder_tags: function() {
|
|
var folder_tags = [];
|
|
var feed_id = this.get('story_feed_id');
|
|
var feed = NEWSBLUR.assets.get_feed(feed_id);
|
|
if (feed) {
|
|
folder_tags = feed.parent_folder_names();
|
|
}
|
|
return folder_tags;
|
|
},
|
|
|
|
all_tags: function() {
|
|
var tags = [];
|
|
var story_tags = this.get('story_tags') || [];
|
|
var user_tags = this.get('user_tags') || [];
|
|
var folder_tags = this.folder_tags();
|
|
var existing_tags = NEWSBLUR.assets.starred_feeds.all_tags();
|
|
var all_tags = _.unique(_.compact(_.reduce([
|
|
story_tags, user_tags, folder_tags, existing_tags
|
|
], function(x, m) {
|
|
return m.concat(x);
|
|
}, [])));
|
|
|
|
return all_tags;
|
|
}
|
|
|
|
});
|
|
|
|
NEWSBLUR.Collections.Stories = Backbone.Collection.extend({
|
|
|
|
model: NEWSBLUR.Models.Story,
|
|
|
|
read_stories: [],
|
|
|
|
previous_stories_stack: [],
|
|
|
|
active_story: null,
|
|
|
|
initialize: function() {
|
|
// this.bind('change:selected', this.detect_selected_story, this);
|
|
this.bind('reset', this.clear_previous_stories_stack, this);
|
|
},
|
|
|
|
// ===========
|
|
// = Actions =
|
|
// ===========
|
|
|
|
deselect_other_stories: function(selected_story) {
|
|
this.any(function(story) {
|
|
if (story.get('selected') && story.id != selected_story.id) {
|
|
story.set('selected', false);
|
|
return true;
|
|
}
|
|
});
|
|
},
|
|
|
|
mark_read: function(story, options) {
|
|
options = options || {};
|
|
var delay = NEWSBLUR.assets.preference('read_story_delay');
|
|
|
|
if (options.skip_delay) {
|
|
delay = 0;
|
|
} else if (options.force) {
|
|
delay = 0;
|
|
} else if (delay == -1) {
|
|
return;
|
|
}
|
|
|
|
clearTimeout(this.read_story_delay);
|
|
|
|
this.read_story_delay = _.delay(_.bind(function() {
|
|
if (!delay || (delay && this.active_story.id == story.id)) {
|
|
var feed = NEWSBLUR.assets.get_feed(NEWSBLUR.reader.active_feed);
|
|
if (!feed) {
|
|
feed = NEWSBLUR.assets.get_feed(story.get('story_feed_id'));
|
|
}
|
|
NEWSBLUR.assets.mark_story_hash_as_read(story, _.bind(function(read) {
|
|
this.update_read_count(story, {previously_read: read});
|
|
}, this));
|
|
}
|
|
}, this), delay * 1000);
|
|
},
|
|
|
|
mark_unread: function(story, options) {
|
|
options = options || {};
|
|
NEWSBLUR.assets.mark_story_as_unread(story.id, story.get('story_feed_id'), _.bind(function(read) {
|
|
this.update_read_count(story, {unread: true});
|
|
}, this), _.bind(function(data) {
|
|
story.set('read_status', 1, {'error_marking_unread': true, 'message': data.message});
|
|
this.update_read_count(story, {unread: false});
|
|
}, this));
|
|
story.set('read_status', 0);
|
|
},
|
|
|
|
update_read_count: function(story, options) {
|
|
options = options || {};
|
|
|
|
if (options.previously_read) return;
|
|
|
|
var story_unread_counter = NEWSBLUR.app.story_unread_counter;
|
|
var unread_view = NEWSBLUR.reader.get_unread_view_name();
|
|
var active_feed = NEWSBLUR.assets.get_feed(NEWSBLUR.reader.active_feed);
|
|
var story_feed = NEWSBLUR.assets.get_feed(story.get('story_feed_id'));
|
|
var friend_feeds = NEWSBLUR.assets.get_friend_feeds(story);
|
|
|
|
if (!active_feed) {
|
|
// River of News does not have an active feed.
|
|
active_feed = story_feed;
|
|
} else if (active_feed && active_feed.is_social()) {
|
|
friend_feeds = _.without(friend_feeds, active_feed);
|
|
}
|
|
|
|
if (story.score() > 0) {
|
|
var active_count = active_feed && Math.max(active_feed.get('ps') + (options.unread?1:-1), 0);
|
|
var story_count = story_feed && Math.max(story_feed.get('ps') + (options.unread?1:-1), 0);
|
|
if (active_feed) active_feed.set('ps', active_count, {instant: true});
|
|
if (story_feed) story_feed.set('ps', story_count, {instant: true});
|
|
_.each(friend_feeds, function(socialsub) {
|
|
var socialsub_count = Math.max(socialsub.get('ps') + (options.unread?1:-1), 0);
|
|
socialsub.set('ps', socialsub_count, {instant: true});
|
|
});
|
|
} else if (story.score() == 0) {
|
|
var active_count = active_feed && Math.max(active_feed.get('nt') + (options.unread?1:-1), 0);
|
|
var story_count = story_feed && Math.max(story_feed.get('nt') + (options.unread?1:-1), 0);
|
|
if (active_feed) active_feed.set('nt', active_count, {instant: true});
|
|
if (story_feed) story_feed.set('nt', story_count, {instant: true});
|
|
_.each(friend_feeds, function(socialsub) {
|
|
var socialsub_count = Math.max(socialsub.get('nt') + (options.unread?1:-1), 0);
|
|
socialsub.set('nt', socialsub_count, {instant: true});
|
|
});
|
|
} else if (story.score() < 0) {
|
|
var active_count = active_feed && Math.max(active_feed.get('ng') + (options.unread?1:-1), 0);
|
|
var story_count = story_feed && Math.max(story_feed.get('ng') + (options.unread?1:-1), 0);
|
|
if (active_feed) active_feed.set('ng', active_count, {instant: true});
|
|
if (story_feed) story_feed.set('ng', story_count, {instant: true});
|
|
_.each(friend_feeds, function(socialsub) {
|
|
var socialsub_count = Math.max(socialsub.get('ng') + (options.unread?1:-1), 0);
|
|
socialsub.set('ng', socialsub_count, {instant: true});
|
|
});
|
|
}
|
|
|
|
if (story_unread_counter) {
|
|
story_unread_counter.flash();
|
|
}
|
|
|
|
// if ((unread_view == 'positive' && feed.get('ps') == 0) ||
|
|
// (unread_view == 'neutral' && feed.get('ps') == 0 && feed.get('nt') == 0) ||
|
|
// (unread_view == 'negative' && feed.get('ps') == 0 && feed.get('nt') == 0 && feed.get('ng') == 0)) {
|
|
// story_unread_counter.fall();
|
|
// }
|
|
},
|
|
|
|
clear_previous_stories_stack: function() {
|
|
this.previous_stories_stack = [];
|
|
},
|
|
|
|
select_previous_story: function() {
|
|
if (this.previous_stories_stack.length) {
|
|
var previous_story = this.previous_stories_stack.pop();
|
|
if (previous_story.get('selected') ||
|
|
previous_story.score() < NEWSBLUR.reader.get_unread_view_score()) {
|
|
this.select_previous_story();
|
|
return;
|
|
}
|
|
|
|
previous_story.set('selected', true);
|
|
}
|
|
},
|
|
|
|
// ==================
|
|
// = Model Managers =
|
|
// ==================
|
|
|
|
visible: function(score) {
|
|
score = _.isUndefined(score) ? NEWSBLUR.reader.get_unread_view_score() : score;
|
|
|
|
return this.select(function(story) {
|
|
return story.score() >= score || story.get('visible');
|
|
});
|
|
},
|
|
|
|
last_visible: function(score) {
|
|
score = _.isUndefined(score) ? NEWSBLUR.reader.get_unread_view_score() : score;
|
|
|
|
for (var i=this.size(); i >= 0; i--) {
|
|
var story = this.at(i);
|
|
if (story.score() >= score || story.get('visible')) {
|
|
return story;
|
|
}
|
|
}
|
|
},
|
|
|
|
visible_and_unread: function(score, include_active_story) {
|
|
var active_story_id = this.active_story && this.active_story.id;
|
|
score = _.isUndefined(score) ? NEWSBLUR.reader.get_unread_view_score() : score;
|
|
|
|
return this.select(function(story) {
|
|
var visible = story.score() >= score || story.get('visible');
|
|
var same_story = include_active_story && story.id == active_story_id;
|
|
var read = !!story.get('read_status');
|
|
|
|
return visible && (!read || same_story);
|
|
});
|
|
},
|
|
|
|
hidden: function(score) {
|
|
score = _.isUndefined(score) ? NEWSBLUR.reader.get_unread_view_score() : score;
|
|
|
|
return this.select(function(story) {
|
|
return story.score() < score && !story.get('visible');
|
|
});
|
|
},
|
|
|
|
// ===========
|
|
// = Getters =
|
|
// ===========
|
|
|
|
get_next_story: function(direction, options) {
|
|
options = options || {};
|
|
if (direction == -1) return this.get_previous_story(options);
|
|
|
|
var visible_stories = this.visible(options.score);
|
|
|
|
if (!this.active_story) {
|
|
return visible_stories[0];
|
|
}
|
|
|
|
var current_index = _.indexOf(visible_stories, this.active_story);
|
|
|
|
if (current_index+1 <= visible_stories.length) {
|
|
return visible_stories[current_index+1];
|
|
}
|
|
},
|
|
|
|
get_previous_story: function(options) {
|
|
options = options || {};
|
|
var visible_stories = this.visible(options.score);
|
|
|
|
if (!this.active_story) {
|
|
return visible_stories[0];
|
|
}
|
|
|
|
var current_index = _.indexOf(visible_stories, this.active_story);
|
|
|
|
if (current_index-1 >= 0) {
|
|
return visible_stories[current_index-1];
|
|
}
|
|
},
|
|
|
|
get_next_unread_story: function(options) {
|
|
options = options || {};
|
|
var visible_stories = this.visible_and_unread(options.score, true);
|
|
if (!visible_stories.length) return;
|
|
|
|
if (!this.active_story) {
|
|
return visible_stories[0];
|
|
}
|
|
|
|
var current_index = _.indexOf(visible_stories, this.active_story);
|
|
|
|
// The +1+1 is because the currently selected story is included, so it
|
|
// counts for more than what is available.
|
|
if (current_index+1+1 <= visible_stories.length) {
|
|
if (visible_stories[current_index+1])
|
|
return visible_stories[current_index+1];
|
|
} else if (current_index-1 >= 0) {
|
|
return visible_stories[current_index-1];
|
|
} else if (visible_stories.length == 1 && visible_stories[0] == this.active_story && !this.active_story.get('read_status')) {
|
|
// If the current story is unread yet selected, switch it back.
|
|
visible_stories[current_index].set('selected', false);
|
|
return visible_stories[current_index];
|
|
}
|
|
|
|
},
|
|
|
|
get_last_unread_story: function(unread_count, options) {
|
|
options = options || {};
|
|
var visible_stories = this.visible_and_unread(options.score);
|
|
if (!visible_stories.length || visible_stories.length < unread_count) return;
|
|
|
|
return _.last(visible_stories);
|
|
},
|
|
|
|
// ==========
|
|
// = Events =
|
|
// ==========
|
|
|
|
detect_selected_story: function(selected_story, selected) {
|
|
if (selected) {
|
|
this.deselect_other_stories(selected_story);
|
|
this.active_story = selected_story;
|
|
NEWSBLUR.reader.active_story = selected_story;
|
|
this.previous_stories_stack.push(selected_story);
|
|
if (!selected_story.get('read_status')) {
|
|
this.mark_read(selected_story);
|
|
}
|
|
}
|
|
}
|
|
|
|
}); |