PageRenderTime 96ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/media/js/newsblur/reader/reader.js

https://github.com/speedsticko/NewsBlur
JavaScript | 5494 lines | 4719 code | 588 blank | 187 comment | 1056 complexity | 532f19f2d3a17b9fd9db0a9280b807df MD5 | raw file
Possible License(s): MIT
  1. (function($) {
  2. NEWSBLUR.Reader = Backbone.Router.extend({
  3. init: function(options) {
  4. var defaults = {};
  5. // ===========
  6. // = Globals =
  7. // ===========
  8. NEWSBLUR.assets = new NEWSBLUR.AssetModel();
  9. this.model = NEWSBLUR.assets;
  10. this.story_view = 'page';
  11. this.options = _.extend({}, defaults, options);
  12. this.$s = {
  13. $body: $('body'),
  14. $layout: $('.NB-layout'),
  15. $sidebar: $('.NB-sidebar'),
  16. $feed_lists: $('.NB-feedlists'),
  17. $feed_list: $('#feed_list'),
  18. $social_feeds: $('.NB-socialfeeds-folder'),
  19. $story_titles: $('#story_titles'),
  20. $content_pane: $('.content-pane'),
  21. $story_taskbar: $('#story_taskbar'),
  22. $story_pane: $('#story_pane .NB-story-pane-container'),
  23. $feed_view: $('.NB-feed-story-view'),
  24. $feed_stories: $('.NB-feed-stories'),
  25. $feed_iframe: $('.NB-feed-iframe'),
  26. $story_iframe: $('.NB-story-iframe'),
  27. $intelligence_slider: $('.NB-intelligence-slider'),
  28. $mouse_indicator: $('#mouse-indicator'),
  29. $feed_link_loader: $('#NB-feeds-list-loader'),
  30. $feeds_progress: $('#NB-progress'),
  31. $dashboard: $('.NB-feeds-header-dashboard'),
  32. $river_sites_header: $('.NB-feeds-header-river-sites'),
  33. $river_blurblogs_header: $('.NB-feeds-header-river-blurblogs'),
  34. $river_global_header: $('.NB-feeds-header-river-global'),
  35. $starred_header: $('.NB-feeds-header-starred'),
  36. $tryfeed_header: $('.NB-feeds-header-tryfeed'),
  37. $taskbar: $('.taskbar_nav'),
  38. $feed_floater: $('.NB-feed-story-view-floater'),
  39. $feedbar: $('.NB-feedbar')
  40. };
  41. this.flags = {
  42. 'bouncing_callout': false,
  43. 'has_unfetched_feeds': false,
  44. 'count_unreads_after_import_working': false,
  45. 'import_from_google_reader_working': false,
  46. 'sidebar_closed': this.options.hide_sidebar
  47. };
  48. this.locks = {};
  49. this.counts = {
  50. 'page': 1,
  51. 'feature_page': 0,
  52. 'unfetched_feeds': 0,
  53. 'fetched_feeds': 0,
  54. 'page_fill_outs': 0,
  55. 'recommended_feed_page': 0,
  56. 'interactions_page': 1,
  57. 'activities_page': 1
  58. };
  59. this.cache = {
  60. 'iframe_story_positions': {},
  61. 'feed_view_story_positions': {},
  62. 'iframe_story_positions_keys': [],
  63. 'feed_view_story_positions_keys': [],
  64. 'river_feeds_with_unreads': [],
  65. '$feed_in_social_feed_list': {}
  66. };
  67. this.views = {};
  68. this.layout = {};
  69. this.constants = {
  70. FEED_REFRESH_INTERVAL: (1000 * 60) * 1, // 1 minute
  71. FILL_OUT_PAGES: 50,
  72. FIND_NEXT_UNREAD_STORY_TRIES: 12,
  73. RIVER_STORIES_FOR_STANDARD_ACCOUNT: 5,
  74. MIN_FEED_LIST_SIZE: 206
  75. };
  76. // ==================
  77. // = Event Handlers =
  78. // ==================
  79. $(window).bind('resize.reader', _.throttle($.rescope(this.resize_window, this), 1000));
  80. this.$s.$body.bind('click.reader', $.rescope(this.handle_clicks, this));
  81. this.$s.$body.bind('keyup.reader', $.rescope(this.handle_keyup, this));
  82. this.handle_keystrokes();
  83. // ============
  84. // = Bindings =
  85. // ============
  86. _.bindAll(this, 'show_stories_error');
  87. // ==================
  88. // = Initialization =
  89. // ==================
  90. var refresh_page = this.check_and_load_ssl();
  91. if (refresh_page) return;
  92. this.load_javascript_elements_on_page();
  93. this.apply_resizable_layout();
  94. this.add_body_classes();
  95. if (NEWSBLUR.Flags['start_import_from_google_reader']) {
  96. this.start_import_from_google_reader();
  97. }
  98. NEWSBLUR.app.sidebar_header = new NEWSBLUR.Views.SidebarHeader({collection: NEWSBLUR.assets.feeds});
  99. NEWSBLUR.app.sidebar = new NEWSBLUR.Views.Sidebar();
  100. NEWSBLUR.app.feed_list = new NEWSBLUR.Views.FeedList({el: this.$s.$feed_list[0]});
  101. NEWSBLUR.app.story_titles = new NEWSBLUR.Views.StoryTitlesView({collection: NEWSBLUR.assets.stories});
  102. NEWSBLUR.app.story_list = new NEWSBLUR.Views.StoryListView({collection: NEWSBLUR.assets.stories});
  103. NEWSBLUR.app.original_tab_view = new NEWSBLUR.Views.OriginalTabView({collection: NEWSBLUR.assets.stories});
  104. NEWSBLUR.app.story_tab_view = new NEWSBLUR.Views.StoryTabView({collection: NEWSBLUR.assets.stories});
  105. NEWSBLUR.app.feed_selector = new NEWSBLUR.Views.FeedSelector();
  106. NEWSBLUR.app.follow_requests_module = new NEWSBLUR.Views.FollowRequestsModule();
  107. this.load_intelligence_slider();
  108. this.handle_mouse_indicator_hover();
  109. this.position_mouse_indicator();
  110. this.handle_login_and_signup_forms();
  111. this.apply_story_styling();
  112. this.apply_tipsy_titles();
  113. this.load_recommended_feeds();
  114. this.setup_dashboard_graphs();
  115. this.setup_feedback_table();
  116. this.setup_howitworks_hovers();
  117. this.setup_interactions_module();
  118. this.setup_activities_module();
  119. this.setup_unfetched_feed_check();
  120. },
  121. // ========
  122. // = Page =
  123. // ========
  124. check_and_load_ssl: function() {
  125. if (window.location.protocol == 'http:' && this.model.preference('ssl')) {
  126. window.location.href = window.location.href.replace('http:', 'https:');
  127. return true;
  128. }
  129. },
  130. load_javascript_elements_on_page: function() {
  131. $('.NB-javascript').removeClass('NB-javascript');
  132. },
  133. resize_window: function() {
  134. var flag;
  135. var view = this.story_view;
  136. if (this.flags['page_view_showing_feed_view']) {
  137. view = 'feed';
  138. flag = 'page';
  139. } else if (this.flags['feed_view_showing_story_view']) {
  140. view = 'story';
  141. flag = 'story';
  142. }
  143. this.flags.scrolling_by_selecting_story_title = true;
  144. clearTimeout(this.locks.scrolling);
  145. this.locks.scrolling = _.delay(_.bind(function() {
  146. this.flags.scrolling_by_selecting_story_title = false;
  147. }, this), 1000);
  148. this.make_story_titles_pane_counter();
  149. this.position_mouse_indicator();
  150. this.switch_taskbar_view(view, {
  151. skip_save_type: flag,
  152. resize: true
  153. });
  154. NEWSBLUR.app.story_titles.fill_out();
  155. this.flags.fetch_story_locations_in_feed_view = this.flags.fetch_story_locations_in_feed_view ||
  156. _.throttle(function() {
  157. NEWSBLUR.app.story_list.reset_story_positions();
  158. }, 2000);
  159. this.flags.fetch_story_locations_in_feed_view();
  160. if ((NEWSBLUR.reader.layout.contentLayout.panes.north &&
  161. NEWSBLUR.reader.layout.contentLayout.panes.north.width() < 600) ||
  162. (NEWSBLUR.reader.layout.contentLayout.panes.center &&
  163. NEWSBLUR.reader.layout.contentLayout.panes.center.width() < 700)) {
  164. this.$s.$feed_view.addClass('NB-feed-story-view-narrow');
  165. } else {
  166. this.$s.$feed_view.removeClass('NB-feed-story-view-narrow');
  167. }
  168. },
  169. apply_resizable_layout: function(refresh) {
  170. var story_anchor = this.model.preference('story_pane_anchor');
  171. var right_pane_hidden = !$('.right-pane').is(':visible');
  172. if (refresh) {
  173. this.layout.contentLayout && this.layout.contentLayout.destroy();
  174. this.layout.rightLayout && this.layout.rightLayout.destroy();
  175. this.layout.leftCenterLayout && this.layout.leftCenterLayout.destroy();
  176. this.layout.leftLayout && this.layout.leftLayout.destroy();
  177. this.layout.outerLayout && this.layout.outerLayout.destroy();
  178. var feed_stories_bin = $.make('div').append(this.$s.$feed_stories.children());
  179. var story_titles_bin = $.make('div').append(this.$s.$story_titles.children());
  180. }
  181. $('.right-pane').removeClass('NB-story-pane-west')
  182. .removeClass('NB-story-pane-north')
  183. .removeClass('NB-story-pane-south')
  184. .addClass('NB-story-pane-'+story_anchor);
  185. this.layout.outerLayout = this.$s.$layout.layout({
  186. zIndex: 2,
  187. fxName: "slideOffscreen",
  188. fxSettings: { duration: 560, easing: "easeInOutQuint" },
  189. center__paneSelector: ".right-pane",
  190. west__paneSelector: ".left-pane",
  191. west__size: this.model.preference('feed_pane_size'),
  192. west__minSize: this.constants.MIN_FEED_LIST_SIZE,
  193. west__onresize_end: $.rescope(this.save_feed_pane_size, this),
  194. // west__initHidden: this.options.hide_sidebar,
  195. west__spacing_open: this.options.hide_sidebar ? 1 : 6,
  196. resizerDragOpacity: 0.6,
  197. resizeWhileDragging: true,
  198. enableCursorHotkey: false
  199. });
  200. if (this.model.preference('feed_pane_size') < 240) {
  201. this.layout.outerLayout.resizeAll();
  202. }
  203. this.layout.leftLayout = $('.left-pane').layout({
  204. closable: false,
  205. resizeWhileDragging: true,
  206. fxName: "slideOffscreen",
  207. fxSettings: { duration: 560, easing: "easeInOutQuint" },
  208. animatePaneSizing: true,
  209. north__paneSelector: ".left-north",
  210. north__size: 18,
  211. north__resizeable: false,
  212. north__spacing_open: 0,
  213. center__paneSelector: ".left-center",
  214. center__resizable: false,
  215. south__paneSelector: ".left-south",
  216. south__size: 31,
  217. south__resizable: false,
  218. south__spacing_open: 0,
  219. enableCursorHotkey: false
  220. });
  221. this.layout.leftCenterLayout = $('.left-center').layout({
  222. closable: false,
  223. slidable: false,
  224. resizeWhileDragging: true,
  225. center__paneSelector: ".left-center-content",
  226. center__resizable: false,
  227. south__paneSelector: ".left-center-footer",
  228. south__size: 'auto',
  229. south__resizable: false,
  230. south__slidable: true,
  231. south__spacing_open: 0,
  232. south__spacing_closed: 0,
  233. south__closable: true,
  234. south__initClosed: true,
  235. fxName: "slideOffscreen",
  236. fxSettings: { duration: 560, easing: "easeInOutQuint" },
  237. enableCursorHotkey: false
  238. });
  239. var rightLayoutOptions = {
  240. resizeWhileDragging: true,
  241. center__paneSelector: ".content-pane",
  242. spacing_open: story_anchor == 'west' ? 4 : 10,
  243. resizerDragOpacity: 0.6,
  244. enableCursorHotkey: false,
  245. fxName: "slideOffscreen",
  246. fxSettings: { duration: 560, easing: "easeInOutQuint" }
  247. };
  248. rightLayoutOptions[story_anchor+'__paneSelector'] = '.right-north';
  249. rightLayoutOptions[story_anchor+'__size'] = this.model.preference('story_titles_pane_size');
  250. rightLayoutOptions[story_anchor+'__onresize_end'] = $.rescope(this.save_story_titles_pane_size, this);
  251. rightLayoutOptions[story_anchor+'__onclose_start'] = $.rescope(this.toggle_story_titles_pane, this);
  252. rightLayoutOptions[story_anchor+'__onopen_start'] = $.rescope(this.toggle_story_titles_pane, this);
  253. this.layout.rightLayout = $('.right-pane').layout(rightLayoutOptions);
  254. var contentLayoutOptions = {
  255. resizeWhileDragging: true,
  256. center__paneSelector: ".content-center",
  257. spacing_open: 0,
  258. resizerDragOpacity: 0.6,
  259. enableCursorHotkey: false
  260. };
  261. if (story_anchor == 'west') {
  262. contentLayoutOptions['north__paneSelector'] = '.content-north';
  263. contentLayoutOptions['north__size'] = 30;
  264. } else {
  265. contentLayoutOptions[story_anchor+'__paneSelector'] = '.content-north';
  266. contentLayoutOptions[story_anchor+'__size'] = 30;
  267. }
  268. this.layout.contentLayout = this.$s.$content_pane.layout(contentLayoutOptions);
  269. if (!refresh) {
  270. $('.right-pane').hide();
  271. } else {
  272. this.$s.$feed_stories.append(feed_stories_bin.children());
  273. this.$s.$story_titles.append(story_titles_bin.children());
  274. this.resize_window();
  275. if (right_pane_hidden) {
  276. $('.right-pane').hide();
  277. }
  278. }
  279. },
  280. apply_tipsy_titles: function() {
  281. if (this.model.preference('show_tooltips')) {
  282. $('.NB-taskbar-sidebar-toggle-close').tipsy({
  283. gravity: 'se',
  284. delayIn: 375
  285. });
  286. $('.NB-taskbar-sidebar-toggle-open').tipsy({
  287. gravity: 'sw',
  288. delayIn: 375
  289. });
  290. $('.NB-task-add').tipsy({
  291. gravity: 'sw',
  292. delayIn: 375
  293. });
  294. $('.NB-task-manage').tipsy({
  295. gravity: 's',
  296. delayIn: 375
  297. });
  298. } else {
  299. $('.NB-taskbar-sidebar-toggle-close').tipsy('disable');
  300. $('.NB-taskbar-sidebar-toggle-open').tipsy('disable');
  301. $('.NB-task-add').tipsy('disable');
  302. $('.NB-task-manage').tipsy('disable');
  303. }
  304. $('.NB-module-content-account-realtime').tipsy({
  305. gravity: 'se',
  306. delayIn: 0
  307. });
  308. },
  309. save_feed_pane_size: function(w, pane, $pane, state, options, name) {
  310. var feed_pane_size = state.size;
  311. $('#NB-splash').css('left', feed_pane_size);
  312. $pane.toggleClass("NB-narrow", this.layout.outerLayout.state.west.size < 240);
  313. this.flags.set_feed_pane_size = this.flags.set_feed_pane_size || _.debounce( _.bind(function() {
  314. var feed_pane_size = this.layout.outerLayout.state.west.size;
  315. this.model.preference('feed_pane_size', feed_pane_size);
  316. this.flags.set_feed_pane_size = null;
  317. }, this), 1000);
  318. this.flags.set_feed_pane_size();
  319. },
  320. save_story_titles_pane_size: function(w, pane, $pane, state, options, name) {
  321. this.flags.scrolling_by_selecting_story_title = true;
  322. clearTimeout(this.locks.scrolling);
  323. var offset = 0;
  324. if (this.story_view == 'feed') {
  325. offset = this.$s.$feed_iframe.width();
  326. } else if (this.story_view == 'story') {
  327. offset = 2 * this.$s.$feed_iframe.width();
  328. }
  329. this.$s.$story_pane.css('left', -1 * offset);
  330. this.flags.set_story_titles_size = this.flags.set_story_titles_size || _.debounce( _.bind(function() {
  331. var story_titles_size = this.layout.rightLayout.state[this.model.preference('story_pane_anchor')].size;
  332. this.model.preference('story_titles_pane_size', story_titles_size);
  333. this.flags.set_story_titles_size = null;
  334. this.locks.scrolling = _.delay(_.bind(function() {
  335. this.flags.scrolling_by_selecting_story_title = false;
  336. }, this), 100);
  337. }, this), 1000);
  338. this.flags.set_story_titles_size();
  339. this.flags.resize_window = this.flags.resize_window || _.debounce( _.bind(function() {
  340. this.resize_window();
  341. this.flags.resize_window = null;
  342. }, this), 10);
  343. this.flags.resize_window();
  344. },
  345. add_body_classes: function() {
  346. this.$s.$body.toggleClass('NB-is-premium', NEWSBLUR.Globals.is_premium);
  347. this.$s.$body.toggleClass('NB-is-anonymous', NEWSBLUR.Globals.is_anonymous);
  348. this.$s.$body.toggleClass('NB-is-authenticated', NEWSBLUR.Globals.is_authenticated);
  349. this.$s.$body.toggleClass('NB-pref-hide-changes', !!this.model.preference('hide_story_changes'));
  350. },
  351. hide_splash_page: function() {
  352. var self = this;
  353. var resize = false;
  354. if (!$('.right-pane').is(':visible')) {
  355. resize = true;
  356. }
  357. $('.right-pane').show();
  358. $('#NB-splash,.NB-splash').hide();
  359. $('.NB-splash-info').hide();
  360. $('#NB-splash-overlay').hide();
  361. this.$s.$dashboard.addClass('NB-active');
  362. if (resize) {
  363. this.$s.$layout.layout().resizeAll();
  364. }
  365. if (NEWSBLUR.Globals.is_anonymous) {
  366. this.setup_ftux_signup_callout();
  367. }
  368. },
  369. show_splash_page: function(skip_router) {
  370. this.reset_feed();
  371. $('.right-pane').hide();
  372. $('.NB-splash-info').show();
  373. $('#NB-splash,.NB-splash').show();
  374. $('#NB-splash-overlay').show();
  375. this.$s.$dashboard.removeClass('NB-active');
  376. if (!skip_router) {
  377. NEWSBLUR.router.navigate('');
  378. }
  379. this.model.preference('dashboard_date', new Date);
  380. },
  381. add_url_from_querystring: function() {
  382. if (this.flags['added_url_from_querystring']) return;
  383. var url = $.getQueryString('url');
  384. this.flags['added_url_from_querystring'] = true;
  385. if (url) {
  386. this.open_add_feed_modal({url: url});
  387. }
  388. },
  389. animate_progress_bar: function($bar, seconds, percentage) {
  390. var self = this;
  391. percentage = percentage || 0;
  392. seconds = parseFloat(Math.max(1, parseInt(seconds, 10)), 10);
  393. if (percentage > 90) {
  394. time = seconds;
  395. } else if (percentage > 80) {
  396. time = seconds / 8;
  397. } else if (percentage > 70) {
  398. time = seconds / 16;
  399. } else if (percentage > 60) {
  400. time = seconds / 40;
  401. } else if (percentage > 50) {
  402. time = seconds / 80;
  403. } else if (percentage > 40) {
  404. time = seconds / 160;
  405. } else if (percentage > 30) {
  406. time = seconds / 200;
  407. } else if (percentage > 20) {
  408. time = seconds / 300;
  409. } else if (percentage > 10) {
  410. time = seconds / 400;
  411. } else {
  412. time = seconds / 500;
  413. }
  414. if (percentage <= 100) {
  415. this.locks['animate_progress_bar'] = setTimeout(function() {
  416. percentage += 1;
  417. $bar.progressbar({value: percentage});
  418. self.animate_progress_bar($bar, seconds, percentage);
  419. }, time * 1000);
  420. }
  421. },
  422. blur_to_page: function(options) {
  423. options = options || {};
  424. if (options.manage_menu) {
  425. $('.NB-menu-manage :focus').blur();
  426. } else {
  427. $(':focus').blur();
  428. }
  429. },
  430. // ==============
  431. // = Navigation =
  432. // ==============
  433. show_next_story: function(direction) {
  434. var story = NEWSBLUR.assets.stories.get_next_story(direction, {
  435. score: this.get_unread_view_score()
  436. });
  437. if (story) {
  438. story.set('selected', true);
  439. }
  440. },
  441. show_next_unread_story: function() {
  442. var unread_count = this.get_unread_count(true);
  443. if (unread_count) {
  444. var next_story = NEWSBLUR.assets.stories.get_next_unread_story();
  445. if (next_story) {
  446. this.counts['find_next_unread_on_page_of_feed_stories_load'] = 0;
  447. next_story.set('selected', true);
  448. } else if (this.counts['find_next_unread_on_page_of_feed_stories_load'] <
  449. this.constants.FIND_NEXT_UNREAD_STORY_TRIES &&
  450. !this.model.flags['no_more_stories']) {
  451. // Nothing up, nothing down, but still unread. Load 1 page then find it.
  452. this.counts['find_next_unread_on_page_of_feed_stories_load'] += 1;
  453. this.load_page_of_feed_stories();
  454. } else if (this.counts['find_next_unread_on_page_of_feed_stories_load'] >=
  455. this.constants.FIND_NEXT_UNREAD_STORY_TRIES) {
  456. this.open_next_unread_story_across_feeds(true);
  457. }
  458. }
  459. },
  460. open_next_unread_story_across_feeds: function(force_next_feed) {
  461. var unread_count = !force_next_feed && this.active_feed && this.get_unread_count(true);
  462. if (!unread_count) {
  463. if (this.flags.river_view && !this.flags.social_view) {
  464. var $next_folder = this.get_next_unread_folder(1);
  465. var folder = NEWSBLUR.assets.folders.get_view($next_folder);
  466. if (folder != this.active_folder) {
  467. this.open_river_stories($next_folder, folder && folder.model);
  468. }
  469. } else {
  470. // Find next feed with unreads
  471. var $next_feed = this.get_next_unread_feed(1);
  472. if (!$next_feed || !$next_feed.length) return;
  473. var next_feed_id = $next_feed.data('id');
  474. if (next_feed_id == this.active_feed) return;
  475. if (NEWSBLUR.utils.is_feed_social(next_feed_id)) {
  476. this.open_social_stories(next_feed_id, {force: true, $feed_link: $next_feed});
  477. } else {
  478. next_feed_id = parseInt(next_feed_id, 10);
  479. this.open_feed(next_feed_id, {force: true, $feed_link: $next_feed});
  480. }
  481. }
  482. }
  483. this.show_next_unread_story();
  484. },
  485. show_last_unread_story: function() {
  486. var unread_count = this.get_unread_count(true);
  487. if (unread_count) {
  488. var last_story = NEWSBLUR.assets.stories.get_last_unread_story(unread_count);
  489. if (last_story) {
  490. this.counts['find_last_unread_on_page_of_feed_stories_load'] = 0;
  491. last_story.set('selected', true);
  492. } else if (this.counts['find_last_unread_on_page_of_feed_stories_load'] < this.constants.FILL_OUT_PAGES &&
  493. !this.model.flags['no_more_stories']) {
  494. // Nothing up, nothing down, but still unread. Load 1 page then find it.
  495. this.counts['find_last_unread_on_page_of_feed_stories_load'] += 1;
  496. this.load_page_of_feed_stories();
  497. }
  498. }
  499. },
  500. select_story_in_feed: function() {
  501. var story_id = this.flags['select_story_in_feed'];
  502. var story = NEWSBLUR.assets.stories.get(story_id);
  503. // NEWSBLUR.log(['select_story_in_feed', story_id, story, this.story_view, this.counts['select_story_in_feed'], this.flags['no_more_stories']]);
  504. if (story) {
  505. this.counts['select_story_in_feed'] = 0;
  506. this.flags['select_story_in_feed'] = null;
  507. _.delay(_.bind(function() {
  508. // Even though a story_id is specified, this just means go to the comments.
  509. // Refactor when stories can be scrolled to separately from comments.
  510. story.set('selected', true, {scroll_to_comments: true});
  511. }, this), 100);
  512. } else if (this.counts['select_story_in_feed'] < this.constants.FILL_OUT_PAGES &&
  513. !this.model.flags['no_more_stories']) {
  514. // Nothing up, nothing down, but still not found. Load 1 page then find it.
  515. this.counts['select_story_in_feed'] += 1;
  516. this.load_page_of_feed_stories();
  517. } else {
  518. this.counts['select_story_in_feed'] = 0;
  519. this.flags['select_story_in_feed'] = null;
  520. }
  521. },
  522. show_previous_story: function() {
  523. NEWSBLUR.assets.stories.select_previous_story();
  524. },
  525. show_next_feed: function(direction, $current_feed) {
  526. var $feed_list = this.$s.$feed_list.add(this.$s.$social_feeds);
  527. if (this.flags.river_view && !this.flags.social_view) {
  528. return this.show_next_folder(direction, $current_feed);
  529. }
  530. var $next_feed = this.get_next_feed(direction, $current_feed, {include_selected: true});
  531. var next_feed_id = $next_feed.data('id');
  532. if (next_feed_id && next_feed_id == this.active_feed) {
  533. this.show_next_feed(direction, $next_feed);
  534. } else if (NEWSBLUR.utils.is_feed_social(next_feed_id)) {
  535. this.open_social_stories(next_feed_id, {force: true, $feed_link: $next_feed});
  536. } else {
  537. next_feed_id = parseInt(next_feed_id, 10);
  538. this.open_feed(next_feed_id, {force: true, $feed_link: $next_feed});
  539. }
  540. },
  541. show_next_folder: function(direction, $current_folder) {
  542. var $next_folder = this.get_next_folder(direction, $current_folder);
  543. var folder = NEWSBLUR.assets.folders.get_view($next_folder);
  544. this.open_river_stories($next_folder, folder && folder.model);
  545. },
  546. get_next_feed: function(direction, $current_feed, options) {
  547. options = options || {};
  548. var self = this;
  549. var $feed_list = this.$s.$feed_list.add(this.$s.$social_feeds);
  550. var $current_feed = $current_feed || $('.selected', $feed_list);
  551. var $next_feed,
  552. scroll;
  553. var $feeds = $('.feed:visible:not(.NB-empty)', $feed_list);
  554. if (!$current_feed.length) {
  555. if (options.include_selected) {
  556. $feeds = $feeds.add('.NB-feedlists .feed.NB-selected');
  557. }
  558. $current_feed = $('.feed:visible:not(.NB-empty)', $feed_list)[direction==-1?'last':'first']();
  559. $next_feed = $current_feed;
  560. } else {
  561. var current_feed = 0;
  562. $feeds.each(function(i) {
  563. if (this == $current_feed[0]) {
  564. current_feed = i;
  565. return false;
  566. }
  567. });
  568. $next_feed = $feeds.eq((current_feed+direction) % ($feeds.length));
  569. }
  570. return $next_feed;
  571. },
  572. get_next_folder: function(direction, $current_folder) {
  573. var self = this;
  574. var $feed_list = this.$s.$feed_list.add(this.$s.$social_feeds);
  575. var $current_folder = $('.folder.NB-selected', $feed_list);
  576. var $folders = $('li.folder:visible:not(.NB-empty)', $feed_list);
  577. var current_folder = 0;
  578. $folders.each(function(i) {
  579. if (this == $current_folder[0]) {
  580. current_folder = i;
  581. return false;
  582. }
  583. });
  584. var next_folder_index = (current_folder+direction) % ($folders.length);
  585. var $next_folder = $folders.eq(next_folder_index);
  586. return $next_folder;
  587. },
  588. get_next_unread_feed: function(direction, $current_feed) {
  589. var self = this;
  590. var $feed_list = this.$s.$feed_list.add(this.$s.$social_feeds);
  591. $current_feed = $current_feed || $('.selected', $feed_list);
  592. var unread_view = this.get_unread_view_name();
  593. var $next_feed;
  594. var current_feed;
  595. var $feeds = $('.feed:visible:not(.NB-empty)', $feed_list).filter(function() {
  596. var $this = $(this);
  597. if (unread_view == 'positive') {
  598. return $this.is('.unread_positive');
  599. } else if (unread_view == 'neutral') {
  600. return $this.is('.unread_positive,.unread_neutral');
  601. } else if (unread_view == 'negative') {
  602. return $this.is('.unread_positive,.unread_neutral,.unread_negative');
  603. }
  604. }).add('.NB-feedlists .feed.NB-selected');
  605. if (!$current_feed.length) {
  606. $next_feed = $feeds.first();
  607. } else {
  608. $feeds.each(function(i) {
  609. if (this == $current_feed[0]) {
  610. current_feed = i;
  611. return false;
  612. }
  613. });
  614. $next_feed = $feeds.eq((current_feed+direction) % ($feeds.length));
  615. }
  616. return $next_feed;
  617. },
  618. get_next_unread_folder: function(direction) {
  619. var self = this;
  620. var $feed_list = this.$s.$feed_list.add(this.$s.$social_feeds);
  621. var $current_folder = $('.folder.NB-selected', $feed_list);
  622. var unread_view = this.get_unread_view_name();
  623. var $next_folder;
  624. var current_folder = 0;
  625. var $folders = $('li.folder:visible:not(.NB-empty)', $feed_list);
  626. $folders = $folders.filter(function() {
  627. var $this = $(this);
  628. var folder_view = NEWSBLUR.assets.folders.get_view($current_folder);
  629. var folder_model = folder_view && folder_view.model;
  630. if (!folder_model) return false;
  631. var counts = folder_model.collection.unread_counts();
  632. if (this == $current_folder[0]) return true;
  633. if (unread_view == 'positive') {
  634. return counts.ps;
  635. } else if (unread_view == 'neutral') {
  636. return counts.ps + counts.nt;
  637. } else if (unread_view == 'negative') {
  638. return counts.ps + counts.nt + counts.ng;
  639. }
  640. });
  641. $folders.each(function(i) {
  642. if (this == $current_folder[0]) {
  643. current_folder = i;
  644. return false;
  645. }
  646. });
  647. $next_folder = $folders.eq((current_folder+direction) % ($folders.length));
  648. return $next_folder;
  649. },
  650. page_in_story: function(amount, direction) {
  651. var page_height = this.$s.$story_pane.height();
  652. var scroll_height = parseInt(page_height * amount, 10);
  653. var dir = '+';
  654. if (direction == -1) {
  655. dir = '-';
  656. }
  657. // NEWSBLUR.log(['page_in_story', this.$s.$story_pane, direction, page_height, scroll_height]);
  658. if (this.story_view == 'page' && !this.flags['page_view_showing_feed_view']) {
  659. this.$s.$feed_iframe.scrollTo({
  660. top: dir+'='+scroll_height,
  661. left:'+=0'
  662. }, 230, {queue: false});
  663. } else if (this.story_view == 'feed' || this.flags['page_view_showing_feed_view']) {
  664. this.$s.$feed_stories.scrollTo({
  665. top: dir+'='+scroll_height,
  666. left:'+=0'
  667. }, 230, {queue: false});
  668. }
  669. this.show_mouse_indicator();
  670. // _.delay(_.bind(this.hide_mouse_indicator, this), 350);
  671. },
  672. find_story_with_action_preference_on_open_feed: function() {
  673. var open_feed_action = this.model.preference('open_feed_action');
  674. if (!this.active_story && open_feed_action == 'newest') {
  675. this.show_next_unread_story();
  676. }
  677. },
  678. // =============
  679. // = Feed Pane =
  680. // =============
  681. sort_feeds: function($feeds) {
  682. $('.feed', $feeds).tsort('', {sortFunction: NEWSBLUR.Collections.Folders.comparator});
  683. $('.folder', $feeds).tsort('.folder_title_text');
  684. },
  685. load_sortable_feeds: function() {
  686. var self = this;
  687. this.$s.$feed_list.sortable({
  688. items: '.feed,li.folder',
  689. connectWith: 'ul.folder,.feed.NB-empty',
  690. placeholder: 'NB-feeds-list-highlight',
  691. axis: 'y',
  692. distance: 4,
  693. cursor: 'move',
  694. containment: '#feed_list',
  695. tolerance: 'pointer',
  696. scrollSensitivity: 35,
  697. start: function(e, ui) {
  698. self.flags['sorting_feed'] = true;
  699. ui.placeholder.attr('class', ui.item.attr('class') + ' NB-feeds-list-highlight');
  700. NEWSBLUR.app.feed_list.start_sorting();
  701. ui.item.addClass('NB-feed-sorting');
  702. ui.placeholder.data('id', ui.item.data('id'));
  703. if (ui.item.is('.folder')) {
  704. ui.placeholder.html(ui.item.children().clone());
  705. ui.item.data('previously_collapsed', ui.item.data('collapsed'));
  706. self.collapse_folder(ui.item.children('.folder_title'), true);
  707. self.collapse_folder(ui.placeholder.children('.folder_title'), true);
  708. ui.item.css('height', ui.item.children('.folder_title').outerHeight(true) + 'px');
  709. ui.helper.css('height', ui.helper.children('.folder_title').outerHeight(true) + 'px');
  710. } else {
  711. ui.placeholder.html(ui.item.children().clone());
  712. }
  713. },
  714. change: function(e, ui) {
  715. var $feeds = ui.placeholder.closest('ul.folder');
  716. self.sort_feeds($feeds);
  717. },
  718. stop: function(e, ui) {
  719. setTimeout(function() {
  720. self.flags['sorting_feed'] = false;
  721. }, 100);
  722. ui.item.removeClass('NB-feed-sorting');
  723. NEWSBLUR.app.feed_list.end_sorting();
  724. self.sort_feeds(e.target);
  725. self.save_feed_order();
  726. ui.item.css({'backgroundColor': '#D7DDE6'})
  727. .animate({'backgroundColor': '#F0F076'}, {'duration': 800})
  728. .animate({'backgroundColor': '#D7DDE6'}, {'duration': 1000});
  729. if (ui.item.is('.folder') && !ui.item.data('previously_collapsed')) {
  730. self.collapse_folder(ui.item.children('.folder_title'));
  731. self.collapse_folder(ui.placeholder.children('.folder_title'));
  732. }
  733. }
  734. });
  735. },
  736. save_feed_order: function() {
  737. var combine_folders = function($folder) {
  738. var folders = [];
  739. var $items = $folder.children('li.folder, .feed');
  740. for (var i=0, i_count=$items.length; i < i_count; i++) {
  741. var $item = $items.eq(i);
  742. if ($item.hasClass('feed')) {
  743. var feed_id = parseInt($item.data('id'), 10);
  744. if (feed_id) {
  745. folders.push(feed_id);
  746. }
  747. } else if ($item.hasClass('folder')) {
  748. var folder_title = $item.find('.folder_title_text').eq(0).text();
  749. var child_folders = {};
  750. child_folders[folder_title] = combine_folders($item.children('ul.folder').eq(0));
  751. folders.push(child_folders);
  752. }
  753. }
  754. return folders;
  755. };
  756. var combined_folders = combine_folders(this.$s.$feed_list);
  757. // NEWSBLUR.log(['Save new folder/feed order', {'combined': combined_folders}]);
  758. this.model.save_feed_order(combined_folders);
  759. },
  760. show_feed_chooser_button: function() {
  761. var self = this;
  762. var $progress = this.$s.$feeds_progress;
  763. var $bar = $('.NB-progress-bar', $progress);
  764. var percentage = 0;
  765. $('.NB-progress-title', $progress).text('Get Started');
  766. $('.NB-progress-counts', $progress).hide();
  767. $('.NB-progress-percentage', $progress).hide();
  768. $progress.addClass('NB-progress-error').addClass('NB-progress-big');
  769. $('.NB-progress-link', $progress).html($.make('div', {
  770. className: 'NB-modal-submit-button NB-modal-submit-green NB-menu-manage-feedchooser'
  771. }, ['Choose your 64 sites']));
  772. this.show_progress_bar();
  773. },
  774. hide_feed_chooser_button: function() {
  775. var $progress = this.$s.$feeds_progress;
  776. var $bar = $('.NB-progress-bar', $progress);
  777. $progress.removeClass('NB-progress-error').removeClass('NB-progress-big');
  778. this.hide_progress_bar();
  779. },
  780. open_dialog_after_feeds_loaded: function(options) {
  781. options = options || {};
  782. if (!NEWSBLUR.Globals.is_authenticated) return;
  783. if (!NEWSBLUR.assets.folders.length ||
  784. !NEWSBLUR.assets.preference('has_setup_feeds')) {
  785. if (options.delayed_import || this.flags.delayed_import) {
  786. this.setup_ftux_add_feed_callout("Check your email...");
  787. } else if (NEWSBLUR.assets.preference('has_setup_feeds')) {
  788. this.setup_ftux_add_feed_callout();
  789. } else if (!NEWSBLUR.intro || !NEWSBLUR.intro.flags.open) {
  790. _.defer(_.bind(this.open_intro_modal, this), 100);
  791. }
  792. } else if (!NEWSBLUR.assets.flags['has_chosen_feeds'] &&
  793. NEWSBLUR.assets.folders.length) {
  794. _.defer(_.bind(this.open_feedchooser_modal, this), 100);
  795. } else if (!NEWSBLUR.Globals.is_premium &&
  796. NEWSBLUR.assets.feeds.active().length > 64) {
  797. _.defer(_.bind(this.open_feedchooser_modal, this), 100);
  798. }
  799. },
  800. // ================
  801. // = Progress Bar =
  802. // ================
  803. check_feed_fetch_progress: function() {
  804. $.extend(this.counts, {
  805. 'unfetched_feeds': 0,
  806. 'fetched_feeds': 0
  807. });
  808. var counts = this.model.count_unfetched_feeds();
  809. this.counts['unfetched_feeds'] = counts['unfetched_feeds'];
  810. this.counts['fetched_feeds'] = counts['fetched_feeds'];
  811. if (this.counts['unfetched_feeds'] == 0) {
  812. this.flags['has_unfetched_feeds'] = false;
  813. this.hide_unfetched_feed_progress();
  814. } else {
  815. this.flags['has_unfetched_feeds'] = true;
  816. this.show_unfetched_feed_progress();
  817. }
  818. },
  819. show_progress_bar: function() {
  820. var $layout = this.$s.$feeds_progress.parents('.left-center').layout();
  821. if (!this.flags['showing_progress_bar']) {
  822. this.flags['showing_progress_bar'] = true;
  823. $layout.open('south');
  824. }
  825. $layout.sizePane('south');
  826. },
  827. hide_progress_bar: function(permanent) {
  828. var self = this;
  829. if (permanent) {
  830. this.model.preference('hide_fetch_progress', true);
  831. }
  832. this.flags['showing_progress_bar'] = false;
  833. this.$s.$feeds_progress.parents('.left-center').layout().close('south');
  834. },
  835. show_unfetched_feed_progress: function() {
  836. var self = this;
  837. var $progress = this.$s.$feeds_progress;
  838. var percentage = parseInt(this.counts['fetched_feeds'] / (this.counts['unfetched_feeds'] + this.counts['fetched_feeds']) * 100, 10);
  839. $('.NB-progress-title', $progress).text('Fetching your feeds');
  840. $('.NB-progress-counts', $progress).show();
  841. $('.NB-progress-counts-fetched', $progress).text(this.counts['fetched_feeds']);
  842. $('.NB-progress-counts-total', $progress).text(this.counts['unfetched_feeds'] + this.counts['fetched_feeds']);
  843. $('.NB-progress-percentage', $progress).show().text(percentage + '%');
  844. $('.NB-progress-bar', $progress).progressbar({
  845. value: percentage
  846. });
  847. if (!$progress.is(':visible') && !this.model.preference('hide_fetch_progress')) {
  848. setTimeout(function() {
  849. self.show_progress_bar();
  850. }, 1000);
  851. }
  852. this.setup_feed_refresh(true);
  853. },
  854. hide_unfetched_feed_progress: function(permanent) {
  855. if (permanent) {
  856. this.model.preference('hide_fetch_progress', true);
  857. }
  858. this.setup_feed_refresh();
  859. this.hide_progress_bar();
  860. },
  861. // ===============================
  862. // = Feed bar - Individual Feeds =
  863. // ===============================
  864. reset_feed: function(options) {
  865. options = options || {};
  866. $.extend(this.flags, {
  867. 'scrolling_by_selecting_story_title': false,
  868. 'page_view_showing_feed_view': false,
  869. 'feed_view_showing_story_view': false,
  870. 'story_titles_loaded': false,
  871. 'iframe_prevented_from_loading': false,
  872. 'pause_feed_refreshing': false,
  873. 'feed_list_showing_manage_menu': false,
  874. 'unread_threshold_temporarily': null,
  875. 'river_view': false,
  876. 'social_view': false,
  877. 'non_premium_river_view': false,
  878. 'select_story_in_feed': null,
  879. 'global_blurblogs': false
  880. });
  881. $.extend(this.cache, {
  882. 'iframe': {},
  883. 'iframe_stories': {},
  884. 'iframe_story_positions': {},
  885. 'feed_view_story_positions': {},
  886. 'iframe_story_positions_keys': [],
  887. 'feed_view_story_positions_keys': [],
  888. 'river_feeds_with_unreads': [],
  889. 'prefetch_last_story': 0,
  890. 'prefetch_iteration': 0,
  891. 'feed_title_floater_story_id': null,
  892. '$feed_in_social_feed_list': {}
  893. });
  894. $.extend(this.counts, {
  895. 'page': 1,
  896. 'page_fill_outs': 0,
  897. 'find_next_unread_on_page_of_feed_stories_load': 0,
  898. 'find_last_unread_on_page_of_feed_stories_load': 0,
  899. 'select_story_in_feed': 0
  900. });
  901. if (_.isUndefined(options.search)) {
  902. delete this.flags.search;
  903. }
  904. this.model.flags['no_more_stories'] = false;
  905. this.$s.$feed_stories.scrollTop(0);
  906. this.$s.$starred_header.removeClass('NB-selected');
  907. this.$s.$river_sites_header.removeClass('NB-selected');
  908. this.$s.$river_blurblogs_header.removeClass('NB-selected');
  909. this.$s.$river_global_header.removeClass('NB-selected');
  910. this.$s.$tryfeed_header.removeClass('NB-selected');
  911. this.model.feeds.deselect();
  912. if (_.string.contains(this.active_feed, 'social:')) {
  913. this.model.social_feeds.deselect();
  914. }
  915. if (_.string.contains(this.active_feed, 'river:')) {
  916. this.model.folders.deselect();
  917. }
  918. this.$s.$body.removeClass('NB-view-river');
  919. $('.task_view_page', this.$s.$taskbar).removeClass('NB-disabled');
  920. $('.task_view_story', this.$s.$taskbar).removeClass('NB-disabled');
  921. $('.task_view_page', this.$s.$taskbar).removeClass('NB-task-return');
  922. clearTimeout(this.flags['next_fetch']);
  923. if (this.flags['showing_feed_in_tryfeed_view'] || this.flags['showing_social_feed_in_tryfeed_view']) {
  924. this.hide_tryfeed_view();
  925. }
  926. if (NEWSBLUR.Globals.is_anonymous) {
  927. if (options.router) {
  928. this.$s.$layout.layout().show('west', true);
  929. this.$s.$layout.show();
  930. }
  931. this.hide_tryout_signup_button();
  932. }
  933. this.active_folder = null;
  934. this.active_feed = null;
  935. this.active_story = null;
  936. NEWSBLUR.assets.stories.reset();
  937. NEWSBLUR.app.feed_selector.hide_feed_selector();
  938. NEWSBLUR.app.original_tab_view.unload_feed_iframe();
  939. NEWSBLUR.app.story_tab_view.unload_story_iframe();
  940. },
  941. reload_feed: function(options) {
  942. options = options || {};
  943. if (this.active_feed == 'starred') {
  944. this.open_starred_stories(options);
  945. } else if (this.flags['social_view'] &&
  946. this.active_feed == 'river:blurblogs') {
  947. this.open_river_blurblogs_stories();
  948. } else if (this.flags['social_view'] &&
  949. this.active_feed == 'river:global') {
  950. this.open_river_blurblogs_stories({'global': true});
  951. } else if (this.flags['social_view']) {
  952. this.open_social_stories(this.active_feed);
  953. } else if (this.flags['river_view']) {
  954. this.open_river_stories(this.active_folder &&
  955. this.active_folder.folder_view &&
  956. this.active_folder.folder_view.$el,
  957. this.active_folder);
  958. } else {
  959. this.open_feed(this.active_feed, options);
  960. }
  961. },
  962. open_feed: function(feed_id, options) {
  963. options = options || {};
  964. var self = this;
  965. var $story_titles = this.$s.$story_titles;
  966. var feed = this.model.get_feed(feed_id) || options.feed;
  967. var temp = feed && (feed.get('temp') || !feed.get('subscribed'));
  968. if (!feed || (temp && !options.try_feed)) {
  969. // Setup tryfeed views first, then come back here.
  970. options.feed = options.feed && options.feed.attributes;
  971. return this.load_feed_in_tryfeed_view(feed_id, options);
  972. }
  973. this.flags['opening_feed'] = true;
  974. if (options.try_feed || feed) {
  975. this.reset_feed(options);
  976. this.hide_splash_page();
  977. if (options.story_id) {
  978. this.flags['select_story_in_feed'] = options.story_id;
  979. }
  980. this.active_feed = feed.id;
  981. this.next_feed = feed.id;
  982. feed.set('selected', true, options);
  983. if (NEWSBLUR.app.story_unread_counter) {
  984. NEWSBLUR.app.story_unread_counter.remove();
  985. }
  986. NEWSBLUR.app.story_titles.show_loading(options);
  987. this.hide_stories_error();
  988. // this.show_stories_progress_bar();
  989. this.iframe_scroll = null;
  990. this.set_correct_story_view_for_feed(feed.id);
  991. this.make_feed_title_in_stories();
  992. this.switch_taskbar_view(this.story_view);
  993. _.delay(_.bind(function() {
  994. if (!options.delay || feed.id == self.next_feed) {
  995. this.model.load_feed(feed.id, 1, true, $.rescope(this.post_open_feed, this),
  996. this.show_stories_error);
  997. }
  998. }, this), options.delay || 0);
  999. if (!this.story_view || this.story_view == 'page') {
  1000. _.delay(_.bind(function() {
  1001. if (!options.delay || feed.id == this.next_feed) {
  1002. NEWSBLUR.app.original_tab_view.load_feed_iframe(feed.id);
  1003. }
  1004. }, this), options.delay || 0);
  1005. } else {
  1006. NEWSBLUR.app.original_tab_view.unload_feed_iframe();
  1007. NEWSBLUR.app.story_tab_view.unload_story_iframe();
  1008. this.flags['iframe_prevented_from_loading'] = true;
  1009. }
  1010. this.setup_mousemove_on_views();
  1011. if (!options.silent) {
  1012. var feed_title = feed.get('feed_title') || '';
  1013. var slug = _.string.words(_.string.clean(feed_title.replace(/[^a-z0-9\. ]/ig, ''))).join('-').toLowerCase();
  1014. var url = "site/" + feed.id + "/" + slug;
  1015. if (!_.string.include(window.location.pathname, url)) {
  1016. NEWSBLUR.log(["Navigating to url", url]);
  1017. NEWSBLUR.router.navigate(url);
  1018. }
  1019. }
  1020. }
  1021. },
  1022. post_open_feed: function(e, data, first_load) {
  1023. if (!data) {
  1024. NEWSBLUR.log(["No data from feed, trying again..."]);
  1025. return this.open_feed(this.active_feed, {force: true});
  1026. }
  1027. var stories = data.stories;
  1028. var tags = data.tags;
  1029. var feed_id = data.feed_id;
  1030. if (data.dupe_feed_id && this.active_feed == data.dupe_feed_id) {
  1031. this.active_feed = data.feed_id;
  1032. }
  1033. this.flags['opening_feed'] = false;
  1034. NEWSBLUR.app.story_titles_header.show_feed_hidden_story_title_indicator(true);
  1035. this.show_story_titles_above_intelligence_level({'animate': false});
  1036. if (this.counts['find_next_unread_on_page_of_feed_stories_load']) {
  1037. this.show_next_unread_story(true);
  1038. } else if (this.counts['find_last_unread_on_page_of_feed_stories_load']) {
  1039. this.show_last_unread_story(true);
  1040. } else if (this.counts['select_story_in_feed'] || this.flags['select_story_in_feed']) {
  1041. this.select_story_in_feed();
  1042. }
  1043. this.flags['story_titles_loaded'] = true;
  1044. if (first_load) {
  1045. this.make_story_titles_pane_counter();
  1046. this.find_story_with_action_preference_on_open_feed();
  1047. if (this.story_view == 'story' &&
  1048. !this.active_story &&
  1049. !this.counts['find_next_unread_on_page_of_feed_stories_load']) {
  1050. this.show_next_story(1);
  1051. }
  1052. }
  1053. this.hide_stories_progress_bar();
  1054. if (NEWSBLUR.Globals.is_anonymous) {
  1055. this.show_tryout_signup_button();
  1056. } else if (this.flags['showing_feed_in_tryfeed_view']) {
  1057. this.show_tryfeed_add_button();
  1058. this.correct_tryfeed_title();
  1059. }
  1060. },
  1061. set_correct_story_view_for_feed: function(feed_id, view) {
  1062. var feed = NEWSBLUR.assets.get_feed(feed_id || this.active_feed);
  1063. var $original_tabs = $('.task_view_page, .task_view_story');
  1064. var $page_tab = $('.task_view_page');
  1065. view = view || NEWSBLUR.assets.view_setting(feed_id);
  1066. if (feed && feed.get('disabled_page')) {
  1067. view = 'feed';
  1068. $original_tabs.addClass('NB-disabled-page')
  1069. .addClass('NB-disabled')
  1070. .attr('title', 'The original page has been disabled by the publisher.')
  1071. .tipsy({
  1072. gravity: 's',
  1073. fade: true,
  1074. delayIn: 200
  1075. });
  1076. $original_tabs.each(function() {
  1077. $(this).tipsy('enable');
  1078. });
  1079. } else if (feed && feed.get('has_exception') && feed.get('exception_type') == 'page') {
  1080. if (view == 'page') {
  1081. view = 'feed';
  1082. }
  1083. $('.task_view_page').addClass('NB-exception-page');
  1084. } else {
  1085. $original_tabs.removeClass('NB-disabled-page')
  1086. .removeClass('NB-disabled')
  1087. .removeClass('NB-exception-page');
  1088. $original_tabs.each(function() {
  1089. $(this).tipsy('disable');
  1090. });
  1091. }
  1092. if (feed_id == 'starred') {
  1093. $page_tab.addClass('NB-disabled-page').addClass('NB-disabled');
  1094. }
  1095. this.story_view = view;
  1096. },
  1097. change_view_setting: function(feed_id, setting, $feed) {
  1098. var changed = NEWSBLUR.assets.view_setting(feed_id, setting);
  1099. if (!changed) return;
  1100. if (feed_id == this.active_feed && this.flags.social_view) {
  1101. this.open_social_stories(feed_id, {$feed: $feed});
  1102. } else if (feed_id == this.active_feed && this.flags.river_view) {
  1103. var folder_view = NEWSBLUR.assets.folders.get_view($feed);
  1104. if (folder_view) {
  1105. var folder = folder_view.model;
  1106. } else {
  1107. var folder = this.active_folder;
  1108. $feed = folder.folder_view.$el;
  1109. }
  1110. this.open_river_stories($feed, folder);
  1111. } else if (feed_id == this.active_feed) {
  1112. this.open_feed(feed_id, {$feed: $feed});
  1113. }
  1114. this.show_correct_feed_view_options_in_menu();
  1115. },
  1116. // ===============
  1117. // = Feed Header =
  1118. // ===============
  1119. update_starred_count: function() {
  1120. var starred_count = this.model.starred_count;
  1121. var $starred_count = $('.NB-feeds-header-count', this.$s.$starred_header);
  1122. var $starred_container = this.$s.$starred_header.closest('.NB-feeds-header-container');
  1123. if (starred_count <= 0) {
  1124. this.$s.$starred_header.addClass('NB-empty');
  1125. $starred_count.text('');
  1126. $starred_container.slideUp(350);
  1127. } else if (starred_count > 0) {
  1128. $starred_count.text(starred_count);
  1129. this.$s.$starred_header.removeClass('NB-empty');
  1130. $starred_container.slideDown(350);
  1131. }
  1132. },
  1133. open_starred_stories: function(options) {
  1134. options = options || {};
  1135. var $story_titles = this.$s.$story_titles;
  1136. this.reset_feed(options);
  1137. this.hide_splash_page();
  1138. this.active_feed = 'starred';
  1139. if (options.story_id) {
  1140. this.flags['select_story_in_feed'] = options.story_id;
  1141. }
  1142. this.iframe_scroll = null;
  1143. this.$s.$starred_header.addClass('NB-selected');
  1144. this.$s.$body.addClass('NB-view-river');
  1145. this.flags.river_view = true;
  1146. $('.task_view_page', this.$s.$taskbar).addClass('NB-disabled');
  1147. var explicit_view_setting = this.model.view_setting(this.active_feed, 'view');
  1148. if (!explicit_view_setting || explicit_view_setting == 'page') {
  1149. explicit_view_setting = 'feed';
  1150. }
  1151. this.set_correct_story_view_for_feed(this.active_feed, explicit_view_setting);
  1152. this.switch_taskbar_view(this.story_view);
  1153. this.setup_mousemove_on_views();
  1154. this.make_feed_title_in_stories();
  1155. this.hide_stories_error();
  1156. this.model.fetch_starred_stories(1, _.bind(this.post_open_starred_stories, this),
  1157. this.show_stories_error, true);
  1158. },
  1159. post_open_starred_stories: function(data, first_load) {
  1160. if (this.active_feed == 'starred') {
  1161. // NEWSBLUR.log(['post_open_starred_stories', data.stories.length, first_load]);
  1162. this.flags['opening_feed'] = false;
  1163. if (this.counts['select_story_in_feed'] || this.flags['select_story_in_feed']) {
  1164. this.select_story_in_feed();
  1165. }
  1166. if (first_load) {
  1167. this.find_story_with_action_preference_on_open_feed();
  1168. }
  1169. this.show_story_titles_above_intelligence_level({'animate': false});
  1170. this.flags['story_titles_loaded'] = true;
  1171. }
  1172. },
  1173. // =================
  1174. // = River of News =
  1175. // =================
  1176. open_river_stories: function($folder, folder, options) {
  1177. options = options || {};
  1178. var $story_titles = this.$s.$story_titles;
  1179. $folder = $folder || this.$s.$feed_list;
  1180. var folder_view = NEWSBLUR.assets.folders.get_view($folder) ||
  1181. this.active_folder && this.active_folder.folder_view;
  1182. var folder_title = folder && folder.get('folder_title') || "Everything";
  1183. this.reset_feed(options);
  1184. this.hide_splash_page();
  1185. this.active_folder = folder || new Backbone.Model({
  1186. folder_title: folder_title,
  1187. fake: true
  1188. });
  1189. if (!folder || folder.get('fake')) {
  1190. this.active_feed = 'river:';
  1191. this.$s.$river_sites_header.addClass('NB-selected');
  1192. } else {
  1193. this.active_feed = 'river:' + folder_title;
  1194. folder_view.model.set('selected', true);
  1195. }
  1196. this.iframe_scroll = null;
  1197. this.flags['opening_feed'] = true;
  1198. this.$s.$body.addClass('NB-view-river');
  1199. this.flags.river_view = true;
  1200. $('.task_view_page', this.$s.$taskbar).addClass('NB-disabled');
  1201. var explicit_view_setting = this.model.view_setting(this.active_feed, 'view');
  1202. if (!explicit_view_setting || explicit_view_setting == 'page') {
  1203. explicit_view_setting = 'feed';
  1204. }
  1205. this.set_correct_story_view_for_feed(this.active_feed, explicit_view_setting);
  1206. this.switch_taskbar_view(this.story_view);
  1207. this.setup_mousemove_on_views();
  1208. this.make_feed_title_in_stories();
  1209. NEWSBLUR.app.feed_list.scroll_to_show_selected_folder();
  1210. if (!options.silent) {
  1211. var slug = folder_title.replace(/ /g, '-').toLowerCase();
  1212. var url = "folder/" + slug;
  1213. if (!_.string.include(window.location.pathname, url)) {
  1214. NEWSBLUR.log(["Navigating to url", url]);
  1215. NEWSBLUR.router.navigate(url);
  1216. }
  1217. }
  1218. var feeds = this.list_feeds_with_unreads_in_folder($folder, false, true);
  1219. this.cache['river_feeds_with_unreads'] = feeds;
  1220. this.hide_stories_error();
  1221. this.show_stories_progress_bar(feeds.length);
  1222. this.model.fetch_river_stories(this.active_feed, feeds, 1,
  1223. _.bind(this.post_open_river_stories, this), this.show_stories_error, true);
  1224. },
  1225. post_open_river_stories: function(data, first_load) {
  1226. // NEWSBLUR.log(['post_open_river_stories', data, this.active_feed]);
  1227. if (!data) {
  1228. return this.show_stories_error(data);
  1229. }
  1230. if (this.active_feed && this.active_feed.indexOf('river:') != -1) {
  1231. if (!NEWSBLUR.Globals.is_premium &&
  1232. NEWSBLUR.Globals.is_authenticated &&
  1233. this.flags['river_view'] &&
  1234. this.active_feed.indexOf('river:') != -1) {
  1235. this.flags['non_premium_river_view'] = true;
  1236. }
  1237. this.flags['opening_feed'] = false;
  1238. NEWSBLUR.app.story_titles_header.show_feed_hidden_story_title_indicator(true);
  1239. this.show_story_titles_above_intelligence_level({'animate': false});
  1240. this.flags['story_titles_loaded'] = true;
  1241. if (this.counts['find_next_unread_on_page_of_feed_stories_load']) {
  1242. this.show_next_unread_story(true);
  1243. } else if (this.counts['find_last_unread_on_page_of_feed_stories_load']) {
  1244. this.show_last_unread_story(true);
  1245. } else if (this.counts['select_story_in_feed'] || this.flags['select_story_in_feed']) {
  1246. this.select_story_in_feed();
  1247. }
  1248. if (first_load) {
  1249. this.find_story_with_action_preference_on_open_feed();
  1250. }
  1251. this.hide_stories_progress_bar();
  1252. if (NEWSBLUR.Globals.is_anonymous) {
  1253. this.show_tryout_signup_button();
  1254. } else if (first_load) {
  1255. this.make_story_titles_pane_counter();
  1256. }
  1257. }
  1258. },
  1259. list_feeds_with_unreads_in_folder: function($folder, counts_only, visible_only) {
  1260. var model = this.model;
  1261. var unread_view = this.get_unread_view_name();
  1262. $folder = $folder || this.$s.$feed_list;
  1263. var $feeds = $('.feed:not(.NB-empty)', $folder);
  1264. var feeds = _.compact(_.map($('.feed:not(.NB-empty)', $folder), function(o) {
  1265. var feed_id = parseInt($(o).data('id'), 10);
  1266. var feed = model.get_feed(feed_id);
  1267. if (!feed) {
  1268. return;
  1269. } else if (counts_only && !visible_only) {
  1270. return feed.get('ps') + feed.get('nt') + feed.get('ng');
  1271. } else if (counts_only && visible_only) {
  1272. if (unread_view == 'positive') return feed.get('ps');
  1273. if (unread_view == 'neutral') return feed.get('ps') + feed.get('nt');
  1274. if (unread_view == 'negative') return feed.get('ps') + feed.get('nt') + feed.get('ng');
  1275. } else if (!counts_only && visible_only) {
  1276. if (unread_view == 'positive') return feed.get('ps') && feed_id;
  1277. if (unread_view == 'neutral') return (feed.get('ps') || feed.get('nt')) && feed_id;
  1278. if (unread_view == 'negative') return (feed.get('ps') || feed.get('nt') || feed.get('ng')) && feed_id;
  1279. } else {
  1280. return (feed.get('ps') || feed.get('nt') || feed.get('ng')) && feed_id;
  1281. }
  1282. }));
  1283. return feeds;
  1284. },
  1285. // ===================
  1286. // = River Blurblogs =
  1287. // ===================
  1288. open_river_blurblogs_stories: function(options) {
  1289. options = options || {};
  1290. var $story_titles = this.$s.$story_titles;
  1291. var folder_title = options.global ? "Global Blurblogs" : "Blurblogs";
  1292. this.reset_feed(options);
  1293. this.hide_splash_page();
  1294. this.active_folder = new Backbone.Model({
  1295. folder_title: options.global ? "Global Shared Stories" : "All Shared Stories",
  1296. fake: true
  1297. });
  1298. this.active_feed = options.global ? 'river:global' : 'river:blurblogs';
  1299. if (options.global) {
  1300. this.$s.$river_global_header.addClass('NB-selected');
  1301. } else {
  1302. this.$s.$river_blurblogs_header.addClass('NB-selected');
  1303. }
  1304. this.iframe_scroll = null;
  1305. this.flags['opening_feed'] = true;
  1306. this.$s.$body.addClass('NB-view-river');
  1307. this.flags.river_view = true;
  1308. this.flags.social_view = true;
  1309. this.flags.global_blurblogs = options.global;
  1310. $('.task_view_page', this.$s.$taskbar).addClass('NB-disabled');
  1311. var explicit_view_setting = this.model.view_setting(this.active_feed, 'view');
  1312. if (!explicit_view_setting || explicit_view_setting == 'page') {
  1313. explicit_view_setting = 'feed';
  1314. }
  1315. this.set_correct_story_view_for_feed(this.active_feed, explicit_view_setting);
  1316. this.switch_taskbar_view(this.story_view);
  1317. this.setup_mousemove_on_views();
  1318. this.make_feed_title_in_stories();
  1319. NEWSBLUR.app.feed_list.scroll_to_show_selected_folder();
  1320. if (!options.silent) {
  1321. var slug = folder_title.replace(/ /g, '-').toLowerCase();
  1322. var url = "folder/" + slug;
  1323. if (!_.string.include(window.location.pathname, url)) {
  1324. NEWSBLUR.log(["Navigating to url", url]);
  1325. NEWSBLUR.router.navigate(url);
  1326. }
  1327. }
  1328. this.hide_stories_error();
  1329. this.show_stories_progress_bar(100); // Assume 100 followees for popular
  1330. this.model.fetch_river_blurblogs_stories(this.active_feed, 1,
  1331. {'global': this.flags.global_blurblogs},
  1332. _.bind(this.post_open_river_blurblogs_stories, this),
  1333. this.show_stories_error, true);
  1334. },
  1335. post_open_river_blurblogs_stories: function(data, first_load) {
  1336. // NEWSBLUR.log(['post_open_river_stories', data, this.active_feed]);
  1337. if (!data) {
  1338. return this.show_stories_error(data);
  1339. }
  1340. if (this.active_feed && this.active_feed.indexOf('river:') != -1) {
  1341. if (!NEWSBLUR.Globals.is_premium &&
  1342. NEWSBLUR.Globals.is_authenticated &&
  1343. this.flags['river_view'] &&
  1344. this.active_feed.indexOf('river:') != -1) {
  1345. this.flags['non_premium_river_view'] = true;
  1346. }
  1347. this.flags['opening_feed'] = false;
  1348. NEWSBLUR.app.story_titles_header.show_feed_hidden_story_title_indicator(true);
  1349. this.show_story_titles_above_intelligence_level({'animate': false});
  1350. this.flags['story_titles_loaded'] = true;
  1351. if (this.counts['find_next_unread_on_page_of_feed_stories_load']) {
  1352. this.show_next_unread_story(true);
  1353. } else if (this.counts['find_last_unread_on_page_of_feed_stories_load']) {
  1354. this.show_last_unread_story(true);
  1355. } else if (this.counts['select_story_in_feed'] ||
  1356. this.flags['select_story_in_feed']) {
  1357. this.select_story_in_feed();
  1358. }
  1359. if (first_load) {
  1360. this.find_story_with_action_preference_on_open_feed();
  1361. }
  1362. this.hide_stories_progress_bar();
  1363. if (NEWSBLUR.Globals.is_anonymous) {
  1364. this.show_tryout_signup_button();
  1365. }
  1366. }
  1367. },
  1368. // ==================
  1369. // = Social Stories =
  1370. // ==================
  1371. open_social_stories: function(feed_id, options) {
  1372. // NEWSBLUR.log(["open_social_stories", feed_id, options]);
  1373. options = options || {};
  1374. if (_.isNumber(feed_id)) feed_id = "social:" + feed_id;
  1375. var feed = this.model.get_feed(feed_id);
  1376. var $story_titles = this.$s.$story_titles;
  1377. var $social_feed = this.find_social_feed_with_feed_id(feed_id);
  1378. if (!feed && !options.try_feed) {
  1379. // Setup tryfeed views first, then come back here.
  1380. var socialsub = this.model.add_social_feed({
  1381. id: feed_id,
  1382. user_id: parseInt(feed_id.replace('social:', ''), 10)
  1383. });
  1384. return this.load_social_feed_in_tryfeed_view(socialsub, options);
  1385. }
  1386. this.reset_feed(options);
  1387. this.hide_splash_page();
  1388. this.active_feed = feed.id;
  1389. this.next_feed = feed.id;
  1390. this.flags.river_view = true;
  1391. if (options.story_id) {
  1392. this.flags['select_story_in_feed'] = options.story_id;
  1393. }
  1394. this.iframe_scroll = null;
  1395. this.flags['opening_feed'] = true;
  1396. feed.set('selected', true, options);
  1397. this.make_feed_title_in_stories();
  1398. this.$s.$body.addClass('NB-view-river');
  1399. this.flags.social_view = true;
  1400. this.set_correct_story_view_for_feed(this.active_feed);
  1401. // TODO: Only make feed the default for blurblogs, not overriding an explicit pref.
  1402. this.switch_taskbar_view('feed');
  1403. this.setup_mousemove_on_views();
  1404. this.hide_stories_error();
  1405. this.show_stories_progress_bar();
  1406. this.model.fetch_social_stories(this.active_feed, 1,
  1407. _.bind(this.post_open_social_stories, this), this.show_stories_error, true);
  1408. if (this.story_view == 'page') {
  1409. _.delay(_.bind(function() {
  1410. if (!options.delay || feed.id == this.next_feed) {
  1411. NEWSBLUR.app.original_tab_view.load_feed_iframe();
  1412. }
  1413. }, this), options.delay || 0);
  1414. } else {
  1415. this.flags['iframe_prevented_from_loading'] = true;
  1416. }
  1417. if (!options.silent && feed.get('feed_title')) {
  1418. var slug = _.string.words(_.string.clean(feed.get('feed_title').replace(/[^a-z0-9\. ]/ig, ''))).join('-').toLowerCase();
  1419. var url = "social/" + feed.get('user_id') + "/" + slug;
  1420. if (!_.string.include(window.location.pathname, url)) {
  1421. var params = {};
  1422. if (_.string.include(window.location.pathname, "social/" + feed.get('user_id'))) {
  1423. params['replace'] = true;
  1424. }
  1425. NEWSBLUR.log(["Navigating to social", url, window.location.pathname]);
  1426. NEWSBLUR.router.navigate(url, params);
  1427. }
  1428. } else if (!feed.get('feed_title')) {
  1429. NEWSBLUR.log(["No feed title on social", feed]);
  1430. NEWSBLUR.router.navigate('');
  1431. }
  1432. },
  1433. post_open_social_stories: function(data, first_load) {
  1434. // NEWSBLUR.log(['post_open_river_stories', data, this.active_feed, this.flags['select_story_in_feed']]);
  1435. if (!data) {
  1436. return this.show_stories_error(data);
  1437. }
  1438. if (this.active_feed && NEWSBLUR.utils.is_feed_social(this.active_feed)) {
  1439. this.flags['opening_feed'] = false;
  1440. this.show_story_titles_above_intelligence_level({'animate': false});
  1441. NEWSBLUR.app.story_titles_header.show_feed_hidden_story_title_indicator(true);
  1442. this.flags['story_titles_loaded'] = true;
  1443. if (this.counts['select_story_in_feed'] || this.flags['select_story_in_feed']) {
  1444. this.select_story_in_feed();
  1445. } else if (this.counts['find_next_unread_on_page_of_feed_stories_load']) {
  1446. this.show_next_unread_story(true);
  1447. } else if (this.counts['find_last_unread_on_page_of_feed_stories_load']) {
  1448. this.show_last_unread_story(true);
  1449. }
  1450. if (first_load) {
  1451. this.find_story_with_action_preference_on_open_feed();
  1452. }
  1453. this.hide_stories_progress_bar();
  1454. if (NEWSBLUR.Globals.is_anonymous) {
  1455. this.show_tryout_signup_button();
  1456. } else if (this.flags['showing_social_feed_in_tryfeed_view']) {
  1457. this.show_tryfeed_follow_button();
  1458. this.correct_tryfeed_title();
  1459. }
  1460. }
  1461. },
  1462. find_social_feed_with_feed_id: function(feed_id) {
  1463. if (_.contains(this.cache.$feed_in_social_feed_list, feed_id)) {
  1464. return this.cache.$feed_in_social_feed_list[feed_id];
  1465. }
  1466. var $social_feeds = this.$s.$social_feeds;
  1467. var $feeds = $([]);
  1468. $('.feed', $social_feeds).each(function() {
  1469. if ($(this).data('id') == feed_id) {
  1470. $feeds.push($(this).get(0));
  1471. }
  1472. });
  1473. this.cache.$feed_in_social_feed_list[feed_id] = $feeds;
  1474. return $feeds;
  1475. },
  1476. // =================
  1477. // = Story loading =
  1478. // =================
  1479. show_stories_progress_bar: function(feeds_loading) {
  1480. if (NEWSBLUR.app.story_unread_counter) {
  1481. NEWSBLUR.app.story_unread_counter.remove();
  1482. }
  1483. var $progress = $.make('div', { className: 'NB-river-progress' }, [
  1484. $.make('div', { className: 'NB-river-progress-text' }),
  1485. $.make('div', { className: 'NB-river-progress-bar' })
  1486. ]).css({'opacity': 0});
  1487. this.$s.$story_taskbar.append($progress);
  1488. $progress.animate({'opacity': 1}, {'duration': 500, 'queue': false});
  1489. var $bar = $('.NB-river-progress-bar', $progress);
  1490. var unreads;
  1491. if (feeds_loading) unreads = feeds_loading;
  1492. else unreads = this.get_unread_count(false) / 10;
  1493. this.animate_progress_bar($bar, unreads / 10);
  1494. $('.NB-river-progress-text', $progress).text('Fetching stories');
  1495. // Center the progress bar
  1496. var i_width = $progress.width();
  1497. var o_width = this.$s.$story_taskbar.width();
  1498. var left = (o_width / 2.0) - (i_width / 2.0);
  1499. $progress.css({'left': left});
  1500. },
  1501. hide_stories_progress_bar: function() {
  1502. var $progress = $('.NB-river-progress', this.$s.$story_taskbar);
  1503. $progress.stop().animate({'opacity': 0}, {
  1504. 'duration': 250,
  1505. 'queue': false,
  1506. 'complete': function() {
  1507. $progress.remove();
  1508. }
  1509. });
  1510. },
  1511. show_stories_error: function(data) {
  1512. NEWSBLUR.log(["show_stories_error", data]);
  1513. this.hide_stories_progress_bar();
  1514. NEWSBLUR.app.original_tab_view.iframe_not_busting();
  1515. this.model.flags['no_more_stories'] = true;
  1516. var message = "Oh no! <br> There was an error!";
  1517. if (data && data.status) {
  1518. if (data.status == 502) {
  1519. message = "NewsBlur is down right now. <br> Try again soon.";
  1520. } else if (data.status == 503) {
  1521. message = "NewsBlur is in maintenace mode. <br> Try again soon.";
  1522. this.show_maintenance_page();
  1523. }
  1524. }
  1525. var $error = $.make('div', { className: 'NB-feed-error' }, [
  1526. $.make('div', { className: 'NB-feed-error-icon' }),
  1527. $.make('div', { className: 'NB-feed-error-text' }, message)
  1528. ]).css({'opacity': 0});
  1529. this.$s.$story_taskbar.append($error);
  1530. if (NEWSBLUR.app.story_unread_counter) {
  1531. NEWSBLUR.app.story_unread_counter.remove();
  1532. }
  1533. $error.animate({'opacity': 1}, {'duration': 500, 'queue': false});
  1534. // Center the progress bar
  1535. var i_width = $error.width();
  1536. var o_width = this.$s.$story_taskbar.width();
  1537. var left = (o_width / 2.0) - (i_width / 2.0);
  1538. $error.css({'left': left});
  1539. NEWSBLUR.app.story_titles.end_loading();
  1540. },
  1541. hide_stories_error: function() {
  1542. var $error = $('.NB-feed-error', this.$s.$story_taskbar);
  1543. $error.animate({'opacity': 0}, {
  1544. 'duration': 250,
  1545. 'queue': false,
  1546. 'complete': function() {
  1547. $error.remove();
  1548. }
  1549. });
  1550. },
  1551. show_maintenance_page: function() {
  1552. this.switch_taskbar_view('page', {skip_save_type: 'maintenance'});
  1553. },
  1554. // ==========================
  1555. // = Story Pane - All Views =
  1556. // ==========================
  1557. switch_to_correct_view: function(found_story_in_page) {
  1558. // NEWSBLUR.log(['Found story', this.story_view, found_story_in_page, this.flags['page_view_showing_feed_view'], this.flags['feed_view_showing_story_view']]);
  1559. if (found_story_in_page === false) {
  1560. // Story not found, show in feed view with link to page view
  1561. if (this.story_view == 'page' && !this.flags['page_view_showing_feed_view']) {
  1562. // NEWSBLUR.log(['turn on feed view', this.flags['page_view_showing_feed_view'], this.flags['feed_view_showing_story_view']]);
  1563. this.flags['page_view_showing_feed_view'] = true;
  1564. this.flags['feed_view_showing_story_view'] = false;
  1565. this.switch_taskbar_view('feed', {skip_save_type: 'page'});
  1566. NEWSBLUR.app.story_list.show_stories_preference_in_feed_view();
  1567. }
  1568. } else {
  1569. if (this.story_view == 'page' && this.flags['page_view_showing_feed_view']) {
  1570. // NEWSBLUR.log(['turn off feed view', this.flags['page_view_showing_feed_view'], this.flags['feed_view_showing_story_view']]);
  1571. this.flags['page_view_showing_feed_view'] = false;
  1572. this.flags['feed_view_showing_story_view'] = false;
  1573. this.switch_taskbar_view('page');
  1574. } else if (this.flags['feed_view_showing_story_view']) {
  1575. // NEWSBLUR.log(['turn off story view', this.flags['page_view_showing_feed_view'], this.flags['feed_view_showing_story_view']]);
  1576. this.flags['page_view_showing_feed_view'] = false;
  1577. this.flags['feed_view_showing_story_view'] = false;
  1578. this.switch_taskbar_view(this.story_view, {skip_save_type: true});
  1579. }
  1580. }
  1581. },
  1582. mark_active_story_read: function() {
  1583. if (!this.active_story) return;
  1584. var story_id = this.active_story.id;
  1585. var story = this.model.get_story(story_id);
  1586. if (this.active_story && !this.active_story.get('read_status')) {
  1587. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1588. } else if (this.active_story && this.active_story.get('read_status')) {
  1589. NEWSBLUR.assets.stories.mark_unread(story);
  1590. }
  1591. },
  1592. mark_feed_as_read: function(feed_id) {
  1593. feed_id = feed_id || this.active_feed;
  1594. this.mark_feed_as_read_update_counts(feed_id);
  1595. this.model.mark_feed_as_read([feed_id]);
  1596. if (feed_id == this.active_feed) {
  1597. this.model.stories.each(function(story) {
  1598. story.set('read_status', true);
  1599. });
  1600. }
  1601. },
  1602. mark_folder_as_read: function(folder) {
  1603. var folder = folder || this.active_folder;
  1604. var feeds = folder.feed_ids_in_folder();
  1605. _.each(feeds, _.bind(function(feed_id) {
  1606. this.mark_feed_as_read_update_counts(feed_id);
  1607. }, this));
  1608. this.model.mark_feed_as_read(feeds);
  1609. if (folder == this.active_folder) {
  1610. this.model.stories.each(function(story) {
  1611. story.set('read_status', true);
  1612. });
  1613. }
  1614. },
  1615. mark_feed_as_read_update_counts: function(feed_id) {
  1616. if (feed_id) {
  1617. var feed = this.model.get_feed(feed_id);
  1618. if (!feed) return;
  1619. feed.set('ps', 0);
  1620. feed.set('nt', 0);
  1621. feed.set('ng', 0);
  1622. }
  1623. },
  1624. open_story_trainer: function(story_id, feed_id, options) {
  1625. options = options || {};
  1626. story_id = story_id || this.active_story && this.active_story.id;
  1627. feed_id = feed_id || (story_id && this.model.get_story(story_id).get('story_feed_id'));
  1628. var story = this.model.get_story(story_id);
  1629. // console.log(["open_story_trainer", story_id, feed_id, options]);
  1630. if (story_id && feed_id) {
  1631. options['feed_loaded'] = !this.flags['river_view'];
  1632. if (this.flags['social_view']) {
  1633. options['feed_loaded'] = true;
  1634. }
  1635. if (this.flags['social_view'] && !_.string.contains(this.active_feed, 'river:')) {
  1636. options['social_feed_id'] = this.active_feed;
  1637. } else if (this.flags['social_view'] && story.get('friend_user_ids')) {
  1638. options['social_feed_id'] = 'social:' + story.get('friend_user_ids')[0];
  1639. }
  1640. NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierStory(story_id, feed_id, options);
  1641. }
  1642. },
  1643. // ===========
  1644. // = Send To =
  1645. // ===========
  1646. send_story_to_instapaper: function(story_id) {
  1647. var story = this.model.get_story(story_id);
  1648. var url = 'http://www.instapaper.com/edit';
  1649. var instapaper_url = [
  1650. url,
  1651. '?url=',
  1652. encodeURIComponent(story.get('story_permalink')),
  1653. '&title=',
  1654. encodeURIComponent(story.get('story_title'))
  1655. ].join('');
  1656. window.open(instapaper_url, '_blank');
  1657. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1658. },
  1659. send_story_to_readitlater: function(story_id) {
  1660. var story = this.model.get_story(story_id);
  1661. var url = 'https://getpocket.com/save';
  1662. var readitlater_url = [
  1663. url,
  1664. '?url=',
  1665. encodeURIComponent(story.get('story_permalink')),
  1666. '&title=',
  1667. encodeURIComponent(story.get('story_title'))
  1668. ].join('');
  1669. window.open(readitlater_url, '_blank');
  1670. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1671. },
  1672. send_story_to_tumblr: function(story_id) {
  1673. var story = this.model.get_story(story_id);
  1674. var url = 'http://www.tumblr.com/share';
  1675. var tumblr_url = [
  1676. url,
  1677. '?v=3&u=',
  1678. encodeURIComponent(story.get('story_permalink')),
  1679. '&t=',
  1680. encodeURIComponent(story.get('story_title'))
  1681. ].join('');
  1682. window.open(tumblr_url, '_blank');
  1683. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1684. },
  1685. send_story_to_delicious: function(story_id) {
  1686. var story = this.model.get_story(story_id);
  1687. var url = 'http://www.delicious.com/save';
  1688. var delicious_url = [
  1689. url,
  1690. '?v=6&url=',
  1691. encodeURIComponent(story.get('story_permalink')),
  1692. '&title=',
  1693. encodeURIComponent(story.get('story_title'))
  1694. ].join('');
  1695. window.open(delicious_url, '_blank');
  1696. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1697. },
  1698. send_story_to_readability: function(story_id) {
  1699. var story = this.model.get_story(story_id);
  1700. var url = 'http://www.readability.com/save';
  1701. var readability_url = [
  1702. url,
  1703. '?url=',
  1704. encodeURIComponent(story.get('story_permalink')),
  1705. '&title=',
  1706. encodeURIComponent(story.get('story_title'))
  1707. ].join('');
  1708. window.open(readability_url, '_blank');
  1709. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1710. },
  1711. send_story_to_twitter: function(story_id) {
  1712. var story = this.model.get_story(story_id);
  1713. var url = 'http://twitter.com/';
  1714. var twitter_url = [
  1715. url,
  1716. '?status=',
  1717. encodeURIComponent(story.get('story_title')),
  1718. ': ',
  1719. encodeURIComponent(story.get('story_permalink'))
  1720. ].join('');
  1721. window.open(twitter_url, '_blank');
  1722. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1723. },
  1724. send_story_to_facebook: function(story_id) {
  1725. var story = this.model.get_story(story_id);
  1726. var url = 'http://www.facebook.com/sharer.php?src=newsblur&v=3.14159265&i=1.61803399';
  1727. var facebook_url = [
  1728. url,
  1729. '&u=',
  1730. encodeURIComponent(story.get('story_permalink')),
  1731. '&t=',
  1732. encodeURIComponent(story.get('story_title'))
  1733. ].join('');
  1734. window.open(facebook_url, '_blank');
  1735. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1736. },
  1737. send_story_to_pinboard: function(story_id) {
  1738. var story = this.model.get_story(story_id);
  1739. var url = 'http://pinboard.in/add/?';
  1740. var pinboard_url = [
  1741. url,
  1742. 'url=',
  1743. encodeURIComponent(story.get('story_permalink')),
  1744. '&title=',
  1745. encodeURIComponent(story.get('story_title')),
  1746. '&tags=',
  1747. encodeURIComponent(story.get('story_tags').join(', '))
  1748. ].join('');
  1749. window.open(pinboard_url, '_blank');
  1750. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1751. },
  1752. send_story_to_diigo: function(story_id) {
  1753. var story = this.model.get_story(story_id);
  1754. var url = 'http://www.diigo.com/post?';
  1755. var url = [
  1756. url,
  1757. 'url=',
  1758. encodeURIComponent(story.get('story_permalink')),
  1759. '&title=',
  1760. encodeURIComponent(story.get('story_title')),
  1761. '&tags=',
  1762. encodeURIComponent(story.get('story_tags').join(', '))
  1763. ].join('');
  1764. window.open(url, '_blank');
  1765. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1766. },
  1767. send_story_to_kippt: function(story_id) {
  1768. var story = this.model.get_story(story_id);
  1769. var url = 'https://kippt.com/extensions/new/?';
  1770. var url = [
  1771. url,
  1772. 'url=',
  1773. encodeURIComponent(story.get('story_permalink')),
  1774. '&title=',
  1775. encodeURIComponent(story.get('story_title')),
  1776. '&tags=',
  1777. encodeURIComponent(story.get('story_tags').join(', '))
  1778. ].join('');
  1779. window.open(url, '_blank');
  1780. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1781. },
  1782. send_story_to_evernote: function(story_id) {
  1783. var story = this.model.get_story(story_id);
  1784. var url = 'https://www.evernote.com/clip.action?';
  1785. var url = [
  1786. url,
  1787. 'url=',
  1788. encodeURIComponent(story.get('story_permalink')),
  1789. '&title=',
  1790. encodeURIComponent(story.get('story_title')),
  1791. '&tags=',
  1792. encodeURIComponent(story.get('story_tags').join(', '))
  1793. ].join('');
  1794. window.open(url, '_blank');
  1795. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1796. },
  1797. send_story_to_googleplus: function(story_id) {
  1798. var story = this.model.get_story(story_id);
  1799. var url = 'https://plusone.google.com/_/+1/confirm'; //?hl=en&url=${url}
  1800. var googleplus_url = [
  1801. url,
  1802. '?hl=en&url=',
  1803. encodeURIComponent(story.get('story_permalink')),
  1804. '&title=',
  1805. encodeURIComponent(story.get('story_title')),
  1806. '&tags=',
  1807. encodeURIComponent(story.get('story_tags').join(', '))
  1808. ].join('');
  1809. window.open(googleplus_url, '_blank');
  1810. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1811. },
  1812. send_story_to_email: function(story) {
  1813. NEWSBLUR.reader_send_email = new NEWSBLUR.ReaderSendEmail(story);
  1814. NEWSBLUR.assets.stories.mark_read(story, {skip_delay: true});
  1815. },
  1816. // =====================
  1817. // = Story Titles Pane =
  1818. // =====================
  1819. make_story_titles_pane_counter: function() {
  1820. var $content_pane = this.$s.$content_pane;
  1821. feed_id = this.active_feed;
  1822. if (!feed_id) return;
  1823. if (this.flags['river_view']) {
  1824. var folder = this.active_folder;
  1825. } else {
  1826. var feed = this.model.get_feed(feed_id);
  1827. }
  1828. if (!feed && !folder) return;
  1829. if (this.active_feed == 'river:global') return;
  1830. if (NEWSBLUR.app.story_unread_counter) {
  1831. NEWSBLUR.app.story_unread_counter.remove();
  1832. }
  1833. if (feed) {
  1834. NEWSBLUR.app.story_unread_counter = new NEWSBLUR.Views.FeedCount({
  1835. model: feed
  1836. }).render();
  1837. } else if (folder) {
  1838. var collection;
  1839. if (!folder.folder_view) {
  1840. // River blurblog gets a special collection
  1841. collection = NEWSBLUR.assets.folders;
  1842. } else {
  1843. collection = folder.folder_view.collection;
  1844. }
  1845. NEWSBLUR.app.story_unread_counter = new NEWSBLUR.Views.FolderCount({
  1846. collection: collection
  1847. }).render();
  1848. }
  1849. NEWSBLUR.app.story_unread_counter.$el.css({'opacity': 0});
  1850. this.$s.$story_taskbar.append(NEWSBLUR.app.story_unread_counter.$el);
  1851. _.delay(function() {
  1852. NEWSBLUR.app.story_unread_counter.center();
  1853. NEWSBLUR.app.story_unread_counter.$el.animate({'opacity': .2}, {'duration': 1000, 'queue': false});
  1854. }, 500);
  1855. },
  1856. // ===========
  1857. // = Stories =
  1858. // ===========
  1859. load_page_of_feed_stories: function(options) {
  1860. options = _.extend({}, {'show_loading': true}, options);
  1861. var $story_titles = this.$s.$story_titles;
  1862. var feed_id = this.active_feed;
  1863. var feed = this.model.get_feed(feed_id);
  1864. if (!this.flags['opening_feed']) {
  1865. this.flags['opening_feed'] = true;
  1866. this.counts['page'] += 1;
  1867. NEWSBLUR.app.story_titles.show_loading(options);
  1868. if (this.active_feed == 'starred') {
  1869. this.model.fetch_starred_stories(this.counts['page'], _.bind(this.post_open_starred_stories, this),
  1870. this.show_stories_error, false);
  1871. } else if (this.flags['social_view'] && _.contains(['river:blurblogs', 'river:global'], this.active_feed)) {
  1872. this.model.fetch_river_blurblogs_stories(this.active_feed,
  1873. this.counts['page'],
  1874. {'global': this.flags.global_blurblogs},
  1875. _.bind(this.post_open_river_blurblogs_stories, this),
  1876. this.show_stories_error, false);
  1877. } else if (this.flags['social_view']) {
  1878. this.model.fetch_social_stories(this.active_feed,
  1879. this.counts['page'], _.bind(this.post_open_social_stories, this),
  1880. this.show_stories_error, false);
  1881. } else if (this.flags['river_view']) {
  1882. this.model.fetch_river_stories(this.active_feed, this.cache['river_feeds_with_unreads'],
  1883. this.counts['page'], _.bind(this.post_open_river_stories, this),
  1884. this.show_stories_error, false);
  1885. } else {
  1886. this.model.load_feed(feed_id, this.counts['page'], false,
  1887. $.rescope(this.post_open_feed, this), this.show_stories_error);
  1888. }
  1889. }
  1890. },
  1891. make_feed_title_in_stories: function(options) {
  1892. if (!_.isUndefined(this.flags.search) && NEWSBLUR.app.story_titles_header) {
  1893. console.log(["make_feed_title_in_stories not destroying", this.flags.search]);
  1894. return;
  1895. }
  1896. if (NEWSBLUR.app.story_titles_header) {
  1897. if (NEWSBLUR.app.story_titles_header.destroy) {
  1898. NEWSBLUR.app.story_titles_header.destroy();
  1899. } else {
  1900. NEWSBLUR.app.story_titles_header.remove();
  1901. }
  1902. }
  1903. NEWSBLUR.app.story_titles_header = new NEWSBLUR.Views.StoryTitlesHeader({
  1904. feed_id: this.active_feed
  1905. }).render();
  1906. },
  1907. open_feed_intelligence_modal: function(score, feed_id, feed_loaded) {
  1908. feed_id = feed_id || this.active_feed;
  1909. if (feed_id) {
  1910. NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierFeed(feed_id, {
  1911. 'score': score,
  1912. 'feed_loaded': feed_loaded
  1913. });
  1914. }
  1915. },
  1916. open_trainer_modal: function(score) {
  1917. var feed_id = this.active_feed;
  1918. // NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierFeed(feed_id, {'score': score});
  1919. NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierTrainer({'score': score});
  1920. },
  1921. open_friends_modal: function() {
  1922. NEWSBLUR.assets.preference('has_found_friends', true);
  1923. NEWSBLUR.reader.check_hide_getting_started();
  1924. NEWSBLUR.reader_friends = new NEWSBLUR.ReaderFriends();
  1925. },
  1926. open_profile_editor_modal: function() {
  1927. NEWSBLUR.reader_profile_editor = new NEWSBLUR.ReaderProfileEditor();
  1928. },
  1929. open_recommend_modal: function(feed_id) {
  1930. NEWSBLUR.recommend_feed = new NEWSBLUR.ReaderRecommendFeed(feed_id);
  1931. },
  1932. open_tutorial_modal: function() {
  1933. NEWSBLUR.tutorial = new NEWSBLUR.ReaderTutorial();
  1934. },
  1935. open_intro_modal: function(options) {
  1936. NEWSBLUR.intro = new NEWSBLUR.ReaderIntro(options);
  1937. },
  1938. hide_intelligence_trainer: function() {
  1939. var $trainer = $('.NB-module-account-trainer');
  1940. $trainer.addClass('NB-done');
  1941. },
  1942. hide_find_friends: function() {
  1943. var $findfriends = $('.NB-module-find-friends');
  1944. $findfriends.addClass('NB-done');
  1945. },
  1946. check_hide_getting_started: function(force) {
  1947. var friends = this.model.preference('has_found_friends');
  1948. var trained = this.model.preference('has_trained_intelligence');
  1949. var feeds = this.model.preference('has_setup_feeds');
  1950. if (force ||
  1951. friends && trained && feeds) {
  1952. var $gettingstarted = $('.NB-module-gettingstarted');
  1953. $gettingstarted.animate({
  1954. 'opacity': 0
  1955. }, {
  1956. 'duration': 500,
  1957. 'complete': function() {
  1958. $gettingstarted.slideUp(350);
  1959. }
  1960. });
  1961. this.model.preference('hide_getting_started', true);
  1962. } else {
  1963. var $intro = $('.NB-module-item-intro');
  1964. var $findfriends = $('.NB-module-find-friends');
  1965. var $trainer = $('.NB-module-account-trainer');
  1966. $intro.toggleClass('NB-done', feeds);
  1967. $findfriends.toggleClass('NB-done', friends);
  1968. $findfriends.toggleClass('NB-hidden', !feeds);
  1969. $trainer.toggleClass('NB-done', trained);
  1970. $trainer.toggleClass('NB-hidden', !feeds);
  1971. }
  1972. },
  1973. // ==========================
  1974. // = Story Pane - Feed View =
  1975. // ==========================
  1976. apply_story_styling: function(reset_stories) {
  1977. var $body = this.$s.$body;
  1978. $body.removeClass('NB-theme-sans-serif');
  1979. $body.removeClass('NB-theme-serif');
  1980. if (NEWSBLUR.Preferences['story_styling'] == 'sans-serif') {
  1981. $body.addClass('NB-theme-sans-serif');
  1982. } else if (NEWSBLUR.Preferences['story_styling'] == 'serif') {
  1983. $body.addClass('NB-theme-serif');
  1984. }
  1985. if (reset_stories) {
  1986. this.show_story_titles_above_intelligence_level({'animate': true, 'follow': true});
  1987. }
  1988. },
  1989. // ===================
  1990. // = Taskbar - Story =
  1991. // ===================
  1992. switch_taskbar_view: function(view, options) {
  1993. options = options || {};
  1994. // NEWSBLUR.log(['switch_taskbar_view', view, options.skip_save_type]);
  1995. var self = this;
  1996. var $story_pane = this.$s.$story_pane;
  1997. var feed = this.model.get_feed(this.active_feed);
  1998. if (view == 'page' && feed && feed.get('has_exception') && feed.get('exception_type') == 'page') {
  1999. this.open_feed_exception_modal();
  2000. return;
  2001. } else if (_.contains(['page', 'story'], view) && feed && feed.get('disabled_page')) {
  2002. view = 'feed';
  2003. } else if ($('.task_button_view.task_view_'+view).hasClass('NB-disabled')) {
  2004. return;
  2005. }
  2006. var $taskbar_buttons = $('.NB-taskbar .task_button_view');
  2007. var $feed_view = this.$s.$feed_view;
  2008. var $feed_iframe = this.$s.$feed_iframe;
  2009. var $page_to_feed_arrow = $('.NB-taskbar .NB-task-view-page-to-feed-arrow');
  2010. var $feed_to_story_arrow = $('.NB-taskbar .NB-task-view-feed-to-story-arrow');
  2011. if (!options.skip_save_type && this.story_view != view) {
  2012. this.model.view_setting(this.active_feed, {'view': view});
  2013. }
  2014. $page_to_feed_arrow.hide();
  2015. $feed_to_story_arrow.hide();
  2016. this.flags['page_view_showing_feed_view'] = false;
  2017. if (options.skip_save_type == 'page') {
  2018. $page_to_feed_arrow.show();
  2019. this.flags['page_view_showing_feed_view'] = true;
  2020. } else if (options.skip_save_type == 'story') {
  2021. $feed_to_story_arrow.show();
  2022. this.flags['feed_view_showing_story_view'] = true;
  2023. } else {
  2024. $taskbar_buttons.removeClass('NB-active');
  2025. $('.task_button_view.task_view_'+view).addClass('NB-active');
  2026. this.story_view = view;
  2027. }
  2028. this.flags.scrolling_by_selecting_story_title = true;
  2029. clearInterval(this.locks.scrolling);
  2030. this.locks.scrolling = setTimeout(function() {
  2031. self.flags.scrolling_by_selecting_story_title = false;
  2032. }, 550);
  2033. if (view == 'page') {
  2034. // NEWSBLUR.log(["iframe_prevented_from_loading", this.flags['iframe_prevented_from_loading']]);
  2035. if (this.flags['iframe_prevented_from_loading']) {
  2036. NEWSBLUR.app.original_tab_view.load_feed_iframe();
  2037. }
  2038. NEWSBLUR.app.original_tab_view.scroll_to_selected_story(this.active_story, {
  2039. immediate: true,
  2040. only_if_hidden: options.resize
  2041. });
  2042. $story_pane.animate({
  2043. 'left': 0
  2044. }, {
  2045. 'easing': 'easeInOutQuint',
  2046. 'duration': this.model.preference('animations') ? 550 : 0,
  2047. 'queue': false
  2048. });
  2049. } else if (view == 'feed') {
  2050. NEWSBLUR.app.story_list.scroll_to_selected_story(this.active_story, {
  2051. immediate: true,
  2052. only_if_hidden: options.resize
  2053. });
  2054. NEWSBLUR.app.story_list.show_stories_preference_in_feed_view();
  2055. $story_pane.animate({
  2056. 'left': -1 * $feed_iframe.width()
  2057. }, {
  2058. 'easing': 'easeInOutQuint',
  2059. 'duration': this.model.preference('animations') ? 550 : 0,
  2060. 'queue': false
  2061. });
  2062. NEWSBLUR.app.story_list.reset_story_positions();
  2063. } else if (view == 'story') {
  2064. $story_pane.animate({
  2065. 'left': -2 * $feed_iframe.width()
  2066. }, {
  2067. 'easing': 'easeInOutQuint',
  2068. 'duration': this.model.preference('animations') ? 550 : 0,
  2069. 'queue': false
  2070. });
  2071. NEWSBLUR.app.story_tab_view.load_story_iframe();
  2072. if (!this.active_story) {
  2073. this.show_next_story(1);
  2074. }
  2075. }
  2076. this.setup_mousemove_on_views();
  2077. },
  2078. switch_taskbar_view_direction: function(direction) {
  2079. var $active = $('.taskbar_nav_view .NB-active');
  2080. var view;
  2081. if (direction == -1) {
  2082. if ($active.hasClass('task_view_page')) {
  2083. // view = 'page';
  2084. } else if ($active.hasClass('task_view_feed')) {
  2085. view = 'page';
  2086. } else if ($active.hasClass('task_view_story')) {
  2087. view = 'feed';
  2088. }
  2089. } else if (direction == 1) {
  2090. if ($active.hasClass('task_view_page')) {
  2091. view = 'feed';
  2092. } else if ($active.hasClass('task_view_feed')) {
  2093. view = 'story';
  2094. } else if ($active.hasClass('task_view_story')) {
  2095. // view = 'story';
  2096. }
  2097. }
  2098. if (view) {
  2099. this.switch_taskbar_view(view);
  2100. }
  2101. },
  2102. // ===================
  2103. // = Taskbar - Feeds =
  2104. // ===================
  2105. open_add_feed_modal: function(options) {
  2106. clearInterval(this.flags['bouncing_callout']);
  2107. $.modal.close();
  2108. NEWSBLUR.add_feed = new NEWSBLUR.ReaderAddFeed(options);
  2109. },
  2110. open_manage_feed_modal: function(feed_id) {
  2111. feed_id = feed_id || this.active_feed;
  2112. NEWSBLUR.manage_feed = new NEWSBLUR.ReaderManageFeed(feed_id);
  2113. },
  2114. open_mark_read_modal: function(options) {
  2115. NEWSBLUR.mark_read = new NEWSBLUR.ReaderMarkRead(options);
  2116. },
  2117. open_keyboard_shortcuts_modal: function() {
  2118. NEWSBLUR.keyboard = new NEWSBLUR.ReaderKeyboard();
  2119. },
  2120. open_goodies_modal: function() {
  2121. NEWSBLUR.goodies = new NEWSBLUR.ReaderGoodies();
  2122. },
  2123. open_preferences_modal: function() {
  2124. NEWSBLUR.preferences = new NEWSBLUR.ReaderPreferences();
  2125. },
  2126. open_account_modal: function(options) {
  2127. NEWSBLUR.account = new NEWSBLUR.ReaderAccount(options);
  2128. },
  2129. open_feedchooser_modal: function() {
  2130. NEWSBLUR.feedchooser = new NEWSBLUR.ReaderFeedchooser();
  2131. },
  2132. open_feed_exception_modal: function(feed_id) {
  2133. feed_id = feed_id || this.active_feed;
  2134. NEWSBLUR.feed_exception = new NEWSBLUR.ReaderFeedException(feed_id);
  2135. },
  2136. open_feed_statistics_modal: function(feed_id) {
  2137. feed_id = feed_id || this.active_feed;
  2138. NEWSBLUR.statistics = new NEWSBLUR.ReaderStatistics(feed_id);
  2139. },
  2140. open_social_profile_modal: function(user_id) {
  2141. if (!user_id) user_id = NEWSBLUR.Globals.user_id;
  2142. if (_.string.contains(user_id, 'social:')) {
  2143. user_id = parseInt(user_id.replace('social:', ''), 10);
  2144. }
  2145. NEWSBLUR.social_profile = new NEWSBLUR.ReaderSocialProfile(user_id);
  2146. },
  2147. close_social_profile: function() {
  2148. if (NEWSBLUR.social_profile) {
  2149. NEWSBLUR.social_profile.close();
  2150. }
  2151. },
  2152. toggle_sidebar: function() {
  2153. if (this.flags['sidebar_closed']) {
  2154. this.open_sidebar();
  2155. return true;
  2156. } else {
  2157. this.close_sidebar();
  2158. return false;
  2159. }
  2160. },
  2161. close_sidebar: function() {
  2162. this.$s.$layout.layout().hide('west');
  2163. this.resize_window();
  2164. this.flags['sidebar_closed'] = true;
  2165. $('.NB-taskbar-sidebar-toggle-open').stop().animate({
  2166. 'left': -1
  2167. }, {
  2168. 'duration': 1000,
  2169. 'easing': 'easeOutQuint',
  2170. 'queue': false
  2171. });
  2172. },
  2173. open_sidebar: function() {
  2174. this.$s.$layout.layout().open('west');
  2175. this.resize_window();
  2176. this.flags['sidebar_closed'] = false;
  2177. $('.NB-taskbar-sidebar-toggle-open').stop().css({
  2178. 'left': -24
  2179. });
  2180. },
  2181. toggle_story_titles_pane: function(update_layout) {
  2182. if (this.flags['story_titles_closed']) {
  2183. this.open_story_titles_pane(update_layout === true);
  2184. } else {
  2185. this.close_story_titles_pane(update_layout === true);
  2186. }
  2187. },
  2188. close_story_titles_pane: function(update_layout) {
  2189. var story_anchor = this.model.preference('story_pane_anchor');
  2190. if (update_layout) {
  2191. NEWSBLUR.reader.layout.rightLayout.close(story_anchor);
  2192. }
  2193. this.resize_window();
  2194. this.flags['story_titles_closed'] = true;
  2195. },
  2196. open_story_titles_pane: function(update_layout) {
  2197. var story_anchor = this.model.preference('story_pane_anchor');
  2198. if (update_layout) {
  2199. NEWSBLUR.reader.layout.rightLayout.open(story_anchor);
  2200. }
  2201. this.resize_window();
  2202. this.flags['story_titles_closed'] = false;
  2203. _.defer(function() {
  2204. NEWSBLUR.app.story_titles.scroll_to_selected_story();
  2205. });
  2206. },
  2207. // =======================
  2208. // = Sidebar Manage Menu =
  2209. // =======================
  2210. make_manage_menu: function(type, feed_id, story_id, inverse, $item) {
  2211. var $manage_menu;
  2212. // NEWSBLUR.log(["make_manage_menu", type, feed_id, story_id, inverse, $item]);
  2213. if (type == 'site') {
  2214. var show_chooser = !NEWSBLUR.Globals.is_premium && NEWSBLUR.Globals.is_authenticated;
  2215. $manage_menu = $.make('ul', { className: 'NB-menu-manage' }, [
  2216. $.make('li', { className: 'NB-menu-manage-site-info' }, [
  2217. $.make('div', { className: 'NB-menu-manage-image' }),
  2218. $.make('span', { className: 'NB-menu-manage-title' }, "Manage NewsBlur")
  2219. ]).corner('tl tr 8px'),
  2220. $.make('li', { className: 'NB-menu-separator' }),
  2221. $.make('li', { className: 'NB-menu-item NB-menu-manage-mark-read NB-menu-manage-site-mark-read' }, [
  2222. $.make('div', { className: 'NB-menu-manage-image' }),
  2223. $.make('div', { className: 'NB-menu-manage-title' }, 'Mark everything as read'),
  2224. $.make('div', { className: 'NB-menu-manage-subtitle' }, 'Choose how many days back.')
  2225. ]),
  2226. $.make('li', { className: 'NB-menu-item NB-menu-manage-trainer' }, [
  2227. $.make('div', { className: 'NB-menu-manage-image' }),
  2228. $.make('div', { className: 'NB-menu-manage-title' }, 'Intelligence Trainer'),
  2229. $.make('div', { className: 'NB-menu-manage-subtitle' }, 'Accurate filters are happy filters.')
  2230. ]),
  2231. (show_chooser && $.make('li', { className: 'NB-menu-item NB-menu-manage-feedchooser' }, [
  2232. $.make('div', { className: 'NB-menu-manage-image' }),
  2233. $.make('div', { className: 'NB-menu-manage-title' }, 'Choose Your 64 sites'),
  2234. $.make('div', { className: 'NB-menu-manage-subtitle' }, 'Enable the sites you want.')
  2235. ])),
  2236. $.make('li', { className: 'NB-menu-separator' }),
  2237. $.make('li', { className: 'NB-menu-item NB-menu-manage-keyboard' }, [
  2238. $.make('div', { className: 'NB-menu-manage-image' }),
  2239. $.make('div', { className: 'NB-menu-manage-title' }, 'Keyboard shortcuts')
  2240. ]),
  2241. $.make('li', { className: 'NB-menu-item NB-menu-manage-tutorial' }, [
  2242. $.make('div', { className: 'NB-menu-manage-image' }),
  2243. $.make('div', { className: 'NB-menu-manage-title' }, 'Tips &amp; Tricks')
  2244. ]),
  2245. $.make('li', { className: 'NB-menu-item NB-menu-manage-goodies' }, [
  2246. $.make('div', { className: 'NB-menu-manage-image' }),
  2247. $.make('div', { className: 'NB-menu-manage-title' }, 'Goodies &amp; Mobile Apps')
  2248. ]),
  2249. $.make('li', { className: 'NB-menu-separator' }),
  2250. $.make('li', { className: 'NB-menu-item NB-menu-manage-account' }, [
  2251. $.make('div', { className: 'NB-menu-manage-image' }),
  2252. $.make('div', { className: 'NB-menu-manage-title' }, 'Account')
  2253. ]),
  2254. $.make('li', { className: 'NB-menu-item NB-menu-manage-profile-editor' }, [
  2255. $.make('div', { className: 'NB-menu-manage-image' }),
  2256. $.make('div', { className: 'NB-menu-manage-title' }, 'Profile &amp; Blurblog')
  2257. ]),
  2258. $.make('li', { className: 'NB-menu-item NB-menu-manage-friends' }, [
  2259. $.make('div', { className: 'NB-menu-manage-image' }),
  2260. $.make('div', { className: 'NB-menu-manage-title' }, 'Friends &amp; Followers')
  2261. ]),
  2262. $.make('li', { className: 'NB-menu-item NB-menu-manage-preferences' }, [
  2263. $.make('div', { className: 'NB-menu-manage-image' }),
  2264. $.make('div', { className: 'NB-menu-manage-title' }, 'Preferences')
  2265. ])
  2266. ]);
  2267. $manage_menu.addClass('NB-menu-manage-notop');
  2268. } else if (type == 'feed') {
  2269. var feed = this.model.get_feed(feed_id);
  2270. if (!feed) return;
  2271. var unread_count = this.get_unread_count(true, feed_id);
  2272. var tab_unread_count = Math.min(25, unread_count);
  2273. $manage_menu = $.make('ul', { className: 'NB-menu-manage NB-menu-manage-feed' }, [
  2274. $.make('li', { className: 'NB-menu-separator-inverse' }),
  2275. (feed.get('has_exception') && $.make('li', { className: 'NB-menu-item NB-menu-manage-feed-exception' }, [
  2276. $.make('div', { className: 'NB-menu-manage-image' }),
  2277. $.make('div', { className: 'NB-menu-manage-title' }, 'Fix this misbehaving site')
  2278. ])),
  2279. (feed.get('has_exception') && $.make('li', { className: 'NB-menu-separator-inverse' })),
  2280. (feed.get('exception_type') != 'feed' && $.make('li', { className: 'NB-menu-item NB-menu-manage-mark-read NB-menu-manage-feed-mark-read' }, [
  2281. $.make('div', { className: 'NB-menu-manage-image' }),
  2282. $.make('div', { className: 'NB-menu-manage-title' }, 'Mark as read')
  2283. ])),
  2284. $.make('li', { className: 'NB-menu-item NB-menu-manage-feed-reload' }, [
  2285. $.make('div', { className: 'NB-menu-manage-image' }),
  2286. $.make('div', { className: 'NB-menu-manage-title' }, 'Insta-fetch stories')
  2287. ]),
  2288. $.make('li', { className: 'NB-menu-separator' }),
  2289. $.make('li', { className: 'NB-menu-subitem NB-menu-manage-controls NB-menu-manage-controls-feed' }, [
  2290. $.make('ul', { className: 'segmented-control NB-menu-manage-view-setting-order' }, [
  2291. $.make('li', { className: 'NB-view-setting-order-newest NB-active' }, 'Newest first'),
  2292. $.make('li', { className: 'NB-view-setting-order-oldest' }, 'Oldest')
  2293. ]),
  2294. $.make('ul', { className: 'segmented-control NB-menu-manage-view-setting-readfilter' }, [
  2295. $.make('li', { className: 'NB-view-setting-readfilter-all NB-active' }, 'All stories'),
  2296. $.make('li', { className: 'NB-view-setting-readfilter-unread' }, 'Unread only')
  2297. ])
  2298. ]),
  2299. $.make('li', { className: 'NB-menu-separator' }),
  2300. $.make('li', { className: 'NB-menu-item NB-menu-manage-feed-stats' }, [
  2301. $.make('div', { className: 'NB-menu-manage-image' }),
  2302. $.make('div', { className: 'NB-menu-manage-title' }, 'Statistics')
  2303. ]),
  2304. $.make('li', { className: 'NB-menu-item NB-menu-manage-feed-train' }, [
  2305. $.make('div', { className: 'NB-menu-manage-image' }),
  2306. $.make('div', { className: 'NB-menu-manage-title' }, 'Intelligence trainer'),
  2307. $.make('div', { className: 'NB-menu-manage-subtitle' }, 'What you like and dislike.')
  2308. ]),
  2309. $.make('li', { className: 'NB-menu-separator' }),
  2310. (NEWSBLUR.Globals.is_admin && $.make('li', { className: 'NB-menu-item NB-menu-manage-feed-recommend' }, [
  2311. $.make('div', { className: 'NB-menu-manage-image' }),
  2312. $.make('div', { className: 'NB-menu-manage-title' }, 'Recommend this site')
  2313. ])),
  2314. (NEWSBLUR.Globals.is_admin && $.make('li', { className: 'NB-menu-separator' })),
  2315. $.make('li', { className: 'NB-menu-item NB-menu-manage-feed-settings' }, [
  2316. $.make('div', { className: 'NB-menu-manage-image' }),
  2317. $.make('div', { className: 'NB-menu-manage-title' }, 'Site settings')
  2318. ]),
  2319. $.make('li', { className: 'NB-menu-item NB-menu-manage-move NB-menu-manage-feed-move' }, [
  2320. $.make('div', { className: 'NB-menu-manage-image' }),
  2321. $.make('div', { className: 'NB-menu-manage-title' }, 'Move to folder')
  2322. ]),
  2323. $.make('li', { className: 'NB-menu-subitem NB-menu-manage-confirm NB-menu-manage-feed-move-confirm NB-modal-submit' }, [
  2324. $.make('div', { className: 'NB-menu-manage-confirm-position'}, [
  2325. $.make('div', { className: 'NB-menu-manage-move-save NB-menu-manage-feed-move-save NB-modal-submit-green NB-modal-submit-button' }, 'Save'),
  2326. $.make('div', { className: 'NB-menu-manage-image' }),
  2327. $.make('div', { className: 'NB-add-folders' }, NEWSBLUR.utils.make_folders(this.model))
  2328. ])
  2329. ]),
  2330. $.make('li', { className: 'NB-menu-item NB-menu-manage-rename NB-menu-manage-feed-rename' }, [
  2331. $.make('div', { className: 'NB-menu-manage-image' }),
  2332. $.make('div', { className: 'NB-menu-manage-title' }, 'Rename this site')
  2333. ]),
  2334. $.make('li', { className: 'NB-menu-subitem NB-menu-manage-confirm NB-menu-manage-feed-rename-confirm NB-modal-submit' }, [
  2335. $.make('div', { className: 'NB-menu-manage-confirm-position'}, [
  2336. $.make('div', { className: 'NB-menu-manage-rename-save NB-menu-manage-feed-rename-save NB-modal-submit-green NB-modal-submit-button' }, 'Save'),
  2337. $.make('div', { className: 'NB-menu-manage-image' }),
  2338. $.make('input', { name: 'new_title', className: 'NB-menu-manage-title', value: feed.get('feed_title') })
  2339. ])
  2340. ]),
  2341. $.make('li', { className: 'NB-menu-item NB-menu-manage-delete NB-menu-manage-feed-delete' }, [
  2342. $.make('div', { className: 'NB-menu-manage-image' }),
  2343. $.make('div', { className: 'NB-menu-manage-title' }, 'Delete this site')
  2344. ]),
  2345. $.make('li', { className: 'NB-menu-item NB-menu-manage-delete-confirm NB-menu-manage-feed-delete-confirm' }, [
  2346. $.make('div', { className: 'NB-menu-manage-image' }),
  2347. $.make('div', { className: 'NB-menu-manage-title' }, 'Really delete?')
  2348. ])
  2349. ]);
  2350. $manage_menu.data('feed_id', feed_id);
  2351. $manage_menu.data('$feed', $item);
  2352. if (feed_id && unread_count == 0) {
  2353. $('.NB-menu-manage-feed-mark-read', $manage_menu).addClass('NB-disabled');
  2354. $('.NB-menu-manage-feed-unreadtabs', $manage_menu).addClass('NB-disabled');
  2355. }
  2356. } else if (type == 'socialfeed') {
  2357. var feed = this.model.get_feed(feed_id);
  2358. if (!feed) return;
  2359. var unread_count = this.get_unread_count(true, feed_id);
  2360. var tab_unread_count = Math.min(25, unread_count);
  2361. $manage_menu = $.make('ul', { className: 'NB-menu-manage NB-menu-manage-feed' }, [
  2362. $.make('li', { className: 'NB-menu-separator-inverse' }),
  2363. (feed.get('has_exception') && $.make('li', { className: 'NB-menu-item NB-menu-manage-feed-exception' }, [
  2364. $.make('div', { className: 'NB-menu-manage-image' }),
  2365. $.make('div', { className: 'NB-menu-manage-title' }, 'Fix this misbehaving site')
  2366. ])),
  2367. (feed.get('has_exception') && $.make('li', { className: 'NB-menu-separator-inverse' })),
  2368. $.make('li', { className: 'NB-menu-item NB-menu-manage-social-profile' }, [
  2369. $.make('div', { className: 'NB-menu-manage-image' }),
  2370. $.make('div', { className: 'NB-menu-manage-title' }, 'View profile')
  2371. ]),
  2372. (feed.get('exception_type') != 'feed' && $.make('li', { className: 'NB-menu-separator' })),
  2373. (feed.get('exception_type') != 'feed' && $.make('li', { className: 'NB-menu-item NB-menu-manage-mark-read NB-menu-manage-feed-mark-read' }, [
  2374. $.make('div', { className: 'NB-menu-manage-image' }),
  2375. $.make('div', { className: 'NB-menu-manage-title' }, 'Mark as read')
  2376. ])),
  2377. $.make('li', { className: 'NB-menu-separator' }),
  2378. $.make('li', { className: 'NB-menu-subitem NB-menu-manage-controls NB-menu-manage-controls-feed' }, [
  2379. (NEWSBLUR.Globals.is_admin && $.make('ul', { className: 'segmented-control NB-menu-manage-view-setting-order' }, [
  2380. $.make('li', { className: 'NB-view-setting-order-newest NB-active' }, 'Newest first'),
  2381. $.make('li', { className: 'NB-view-setting-order-oldest' }, 'Oldest')
  2382. ])),
  2383. $.make('ul', { className: 'segmented-control NB-menu-manage-view-setting-readfilter' }, [
  2384. $.make('li', { className: 'NB-view-setting-readfilter-all NB-active' }, 'All stories'),
  2385. $.make('li', { className: 'NB-view-setting-readfilter-unread' }, 'Unread only')
  2386. ])
  2387. ]),
  2388. $.make('li', { className: 'NB-menu-separator' }),
  2389. $.make('li', { className: 'NB-menu-item NB-menu-manage-feed-stats' }, [
  2390. $.make('div', { className: 'NB-menu-manage-image' }),
  2391. $.make('div', { className: 'NB-menu-manage-title' }, 'Statistics')
  2392. ]),
  2393. $.make('li', { className: 'NB-menu-item NB-menu-manage-feed-train' }, [
  2394. $.make('div', { className: 'NB-menu-manage-image' }),
  2395. $.make('div', { className: 'NB-menu-manage-title' }, 'Intelligence trainer'),
  2396. $.make('div', { className: 'NB-menu-manage-subtitle' }, 'What you like and dislike.')
  2397. ]),
  2398. $.make('li', { className: 'NB-menu-separator' }),
  2399. $.make('li', { className: 'NB-menu-item NB-menu-manage-feed-settings' }, [
  2400. $.make('div', { className: 'NB-menu-manage-image' }),
  2401. $.make('div', { className: 'NB-menu-manage-title' }, 'Site settings')
  2402. ]),
  2403. (feed.get('user_id') != NEWSBLUR.Globals.user_id && $.make('li', { className: 'NB-menu-item NB-menu-manage-delete NB-menu-manage-socialfeed-delete' }, [
  2404. $.make('div', { className: 'NB-menu-manage-image' }),
  2405. $.make('div', { className: 'NB-menu-manage-title' }, 'Unfollow')
  2406. ])),
  2407. $.make('li', { className: 'NB-menu-item NB-menu-manage-delete-confirm NB-menu-manage-socialfeed-delete-confirm' }, [
  2408. $.make('div', { className: 'NB-menu-manage-image' }),
  2409. $.make('div', { className: 'NB-menu-manage-title' }, 'Really unfollow?')
  2410. ])
  2411. ]);
  2412. $manage_menu.data('feed_id', feed_id);
  2413. $manage_menu.data('$feed', $item);
  2414. if (feed_id && unread_count == 0) {
  2415. $('.NB-menu-manage-feed-mark-read', $manage_menu).addClass('NB-disabled');
  2416. $('.NB-menu-manage-feed-unreadtabs', $manage_menu).addClass('NB-disabled');
  2417. }
  2418. } else if (type == 'folder') {
  2419. $manage_menu = $.make('ul', { className: 'NB-menu-manage NB-menu-manage-folder' }, [
  2420. $.make('li', { className: 'NB-menu-separator-inverse' }),
  2421. $.make('li', { className: 'NB-menu-item NB-menu-manage-mark-read NB-menu-manage-folder-mark-read' }, [
  2422. $.make('div', { className: 'NB-menu-manage-image' }),
  2423. $.make('div', { className: 'NB-menu-manage-title' }, 'Mark folder as read')
  2424. ]),
  2425. $.make('li', { className: 'NB-menu-item NB-menu-manage-folder-subscribe' }, [
  2426. $.make('div', { className: 'NB-menu-manage-image' }),
  2427. $.make('div', { className: 'NB-menu-manage-title' }, 'Add a site to this folder')
  2428. ]),
  2429. $.make('li', { className: 'NB-menu-item NB-menu-manage-folder-subfolder' }, [
  2430. $.make('div', { className: 'NB-menu-manage-image' }),
  2431. $.make('div', { className: 'NB-menu-manage-title' }, 'Create a new subfolder')
  2432. ]),
  2433. $.make('li', { className: 'NB-menu-separator' }),
  2434. $.make('li', { className: 'NB-menu-subitem NB-menu-manage-controls NB-menu-manage-controls-folder' }, [
  2435. $.make('ul', { className: 'segmented-control NB-menu-manage-view-setting-order' }, [
  2436. $.make('li', { className: 'NB-view-setting-order-newest NB-active' }, 'Newest first'),
  2437. $.make('li', { className: 'NB-view-setting-order-oldest' }, 'Oldest')
  2438. ])
  2439. ]),
  2440. $.make('li', { className: 'NB-menu-separator' }),
  2441. $.make('li', { className: 'NB-menu-item NB-menu-manage-move NB-menu-manage-folder-move' }, [
  2442. $.make('div', { className: 'NB-menu-manage-image' }),
  2443. $.make('div', { className: 'NB-menu-manage-title' }, 'Move to folder')
  2444. ]),
  2445. $.make('li', { className: 'NB-menu-subitem NB-menu-manage-confirm NB-menu-manage-folder-move-confirm NB-modal-submit' }, [
  2446. $.make('div', { className: 'NB-menu-manage-confirm-position'}, [
  2447. $.make('div', { className: 'NB-menu-manage-move-save NB-menu-manage-folder-move-save NB-modal-submit-green NB-modal-submit-button' }, 'Save'),
  2448. $.make('div', { className: 'NB-menu-manage-image' }),
  2449. $.make('div', { className: 'NB-add-folders' }, NEWSBLUR.utils.make_folders(this.model))
  2450. ])
  2451. ]),
  2452. $.make('li', { className: 'NB-menu-item NB-menu-manage-rename NB-menu-manage-folder-rename' }, [
  2453. $.make('div', { className: 'NB-menu-manage-image' }),
  2454. $.make('div', { className: 'NB-menu-manage-title' }, 'Rename this folder')
  2455. ]),
  2456. $.make('li', { className: 'NB-menu-subitem NB-menu-manage-confirm NB-menu-manage-folder-rename-confirm NB-modal-submit' }, [
  2457. $.make('div', { className: 'NB-menu-manage-confirm-position'}, [
  2458. $.make('div', { className: 'NB-menu-manage-rename-save NB-menu-manage-folder-rename-save NB-modal-submit-green NB-modal-submit-button' }, 'Save'),
  2459. $.make('div', { className: 'NB-menu-manage-image' }),
  2460. $.make('input', { name: 'new_title', className: 'NB-menu-manage-title', value: feed_id })
  2461. ])
  2462. ]),
  2463. $.make('li', { className: 'NB-menu-item NB-menu-manage-delete NB-menu-manage-folder-delete' }, [
  2464. $.make('div', { className: 'NB-menu-manage-image' }),
  2465. $.make('div', { className: 'NB-menu-manage-title' }, 'Delete this folder')
  2466. ]),
  2467. $.make('li', { className: 'NB-menu-item NB-menu-manage-delete-confirm NB-menu-manage-folder-delete-confirm' }, [
  2468. $.make('div', { className: 'NB-menu-manage-image' }),
  2469. $.make('div', { className: 'NB-menu-manage-title' }, 'Really delete?')
  2470. ])
  2471. ]);
  2472. $manage_menu.data('folder_name', feed_id);
  2473. $manage_menu.data('$folder', $item);
  2474. } else if (type == 'story') {
  2475. var feed = this.model.get_feed(feed_id);
  2476. var story = this.model.get_story(story_id);
  2477. var starred_class = story.get('starred') ? ' NB-story-starred ' : '';
  2478. var starred_title = story.get('starred') ? 'Unsave this story' : 'Save this story';
  2479. var shared_class = story.get('shared') ? ' NB-story-shared ' : '';
  2480. var shared_title = story.get('shared') ? 'Shared' : 'Share to your Blurblog';
  2481. story.story_share_menu_view = new NEWSBLUR.Views.StoryShareView({
  2482. model: story
  2483. });
  2484. $manage_menu = $.make('ul', { className: 'NB-menu-manage NB-menu-manage-story ' + starred_class + shared_class }, [
  2485. $.make('li', { className: 'NB-menu-separator' }),
  2486. $.make('li', { className: 'NB-menu-item NB-menu-manage-story-open' }, [
  2487. $.make('div', { className: 'NB-menu-manage-image' }),
  2488. $.make('input', { name: 'story_permalink', className: 'NB-menu-manage-open-input', value: story.get('story_permalink') }),
  2489. $.make('div', { className: 'NB-menu-manage-title' }, 'Open')
  2490. ]),
  2491. $.make('li', { className: 'NB-menu-separator' }),
  2492. $.make('li', { className: 'NB-menu-item NB-menu-manage-story-star' }, [
  2493. $.make('div', { className: 'NB-menu-manage-image' }),
  2494. $.make('div', { className: 'NB-menu-manage-title' }, starred_title)
  2495. ]),
  2496. (story.get('read_status') && $.make('li', { className: 'NB-menu-item NB-menu-manage-story-unread' }, [
  2497. $.make('div', { className: 'NB-menu-manage-image' }),
  2498. $.make('div', { className: 'NB-menu-manage-title' }, 'Mark as unread')
  2499. ])),
  2500. $.make('li', { className: 'NB-menu-item NB-menu-manage-story-thirdparty' }, [
  2501. (NEWSBLUR.Preferences['story_share_facebook'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-facebook'}).bind('mouseenter', _.bind(function(e) {
  2502. $(e.target).siblings('.NB-menu-manage-title').text('Facebook').parent().addClass('NB-menu-manage-highlight-facebook');
  2503. }, this)).bind('mouseleave', _.bind(function(e) {
  2504. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-facebook');
  2505. }, this))),
  2506. (NEWSBLUR.Preferences['story_share_twitter'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-twitter'}).bind('mouseenter', _.bind(function(e) {
  2507. $(e.target).siblings('.NB-menu-manage-title').text('Twitter').parent().addClass('NB-menu-manage-highlight-twitter');
  2508. }, this)).bind('mouseleave', _.bind(function(e) {
  2509. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-twitter');
  2510. }, this))),
  2511. (NEWSBLUR.Preferences['story_share_readitlater'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-readitlater'}).bind('mouseenter', _.bind(function(e) {
  2512. $(e.target).siblings('.NB-menu-manage-title').text('Pocket (RIL)').parent().addClass('NB-menu-manage-highlight-readitlater');
  2513. }, this)).bind('mouseleave', _.bind(function(e) {
  2514. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-readitlater');
  2515. }, this))),
  2516. (NEWSBLUR.Preferences['story_share_tumblr'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-tumblr'}).bind('mouseenter', _.bind(function(e) {
  2517. $(e.target).siblings('.NB-menu-manage-title').text('Tumblr').parent().addClass('NB-menu-manage-highlight-tumblr');
  2518. }, this)).bind('mouseleave', _.bind(function(e) {
  2519. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-tumblr');
  2520. }, this))),
  2521. (NEWSBLUR.Preferences['story_share_delicious'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-delicious'}).bind('mouseenter', _.bind(function(e) {
  2522. $(e.target).siblings('.NB-menu-manage-title').text('Delicious').parent().addClass('NB-menu-manage-highlight-delicious');
  2523. }, this)).bind('mouseleave', _.bind(function(e) {
  2524. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-delicious');
  2525. }, this))),
  2526. (NEWSBLUR.Preferences['story_share_pinboard'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-pinboard'}).bind('mouseenter', _.bind(function(e) {
  2527. $(e.target).siblings('.NB-menu-manage-title').text('Pinboard').parent().addClass('NB-menu-manage-highlight-pinboard');
  2528. }, this)).bind('mouseleave', _.bind(function(e) {
  2529. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-pinboard');
  2530. }, this))),
  2531. (NEWSBLUR.Preferences['story_share_diigo'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-diigo'}).bind('mouseenter', _.bind(function(e) {
  2532. $(e.target).siblings('.NB-menu-manage-title').text('Diigo').parent().addClass('NB-menu-manage-highlight-diigo');
  2533. }, this)).bind('mouseleave', _.bind(function(e) {
  2534. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-diigo');
  2535. }, this))),
  2536. (NEWSBLUR.Preferences['story_share_kippt'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-kippt'}).bind('mouseenter', _.bind(function(e) {
  2537. $(e.target).siblings('.NB-menu-manage-title').text('Kippt').parent().addClass('NB-menu-manage-highlight-kippt');
  2538. }, this)).bind('mouseleave', _.bind(function(e) {
  2539. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-kippt');
  2540. }, this))),
  2541. (NEWSBLUR.Preferences['story_share_evernote'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-evernote'}).bind('mouseenter', _.bind(function(e) {
  2542. $(e.target).siblings('.NB-menu-manage-title').text('Evernote').parent().addClass('NB-menu-manage-highlight-evernote');
  2543. }, this)).bind('mouseleave', _.bind(function(e) {
  2544. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-evernote');
  2545. }, this))),
  2546. (NEWSBLUR.Preferences['story_share_googleplus'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-googleplus'}).bind('mouseenter', _.bind(function(e) {
  2547. $(e.target).siblings('.NB-menu-manage-title').text('Google+').parent().addClass('NB-menu-manage-highlight-googleplus');
  2548. }, this)).bind('mouseleave', _.bind(function(e) {
  2549. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-googleplus');
  2550. }, this))),
  2551. (NEWSBLUR.Preferences['story_share_instapaper'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-instapaper'}).bind('mouseenter', _.bind(function(e) {
  2552. $(e.target).siblings('.NB-menu-manage-title').text('Instapaper').parent().addClass('NB-menu-manage-highlight-instapaper');
  2553. }, this)).bind('mouseleave', _.bind(function(e) {
  2554. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-instapaper');
  2555. }, this))),
  2556. (NEWSBLUR.Preferences['story_share_readability'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-readability'}).bind('mouseenter', _.bind(function(e) {
  2557. $(e.target).siblings('.NB-menu-manage-title').text('Readability').parent().addClass('NB-menu-manage-highlight-readability');
  2558. }, this)).bind('mouseleave', _.bind(function(e) {
  2559. $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-readability');
  2560. }, this))),
  2561. $.make('div', { className: 'NB-menu-manage-image' }),
  2562. $.make('div', { className: 'NB-menu-manage-title' }, 'Email story')
  2563. ]).bind('click', _.bind(function(e) {
  2564. e.preventDefault();
  2565. e.stopPropagation();
  2566. var $target = $(e.target);
  2567. if ($target.hasClass('NB-menu-manage-thirdparty-facebook')) {
  2568. this.send_story_to_facebook(story.id);
  2569. } else if ($target.hasClass('NB-menu-manage-thirdparty-twitter')) {
  2570. this.send_story_to_twitter(story.id);
  2571. } else if ($target.hasClass('NB-menu-manage-thirdparty-readitlater')) {
  2572. this.send_story_to_readitlater(story.id);
  2573. } else if ($target.hasClass('NB-menu-manage-thirdparty-tumblr')) {
  2574. this.send_story_to_tumblr(story.id);
  2575. } else if ($target.hasClass('NB-menu-manage-thirdparty-delicious')) {
  2576. this.send_story_to_delicious(story.id);
  2577. } else if ($target.hasClass('NB-menu-manage-thirdparty-readability')) {
  2578. this.send_story_to_readability(story.id);
  2579. } else if ($target.hasClass('NB-menu-manage-thirdparty-pinboard')) {
  2580. this.send_story_to_pinboard(story.id);
  2581. } else if ($target.hasClass('NB-menu-manage-thirdparty-diigo')) {
  2582. this.send_story_to_diigo(story.id);
  2583. } else if ($target.hasClass('NB-menu-manage-thirdparty-kippt')) {
  2584. this.send_story_to_kippt(story.id);
  2585. } else if ($target.hasClass('NB-menu-manage-thirdparty-evernote')) {
  2586. this.send_story_to_evernote(story.id);
  2587. } else if ($target.hasClass('NB-menu-manage-thirdparty-googleplus')) {
  2588. this.send_story_to_googleplus(story.id);
  2589. } else if ($target.hasClass('NB-menu-manage-thirdparty-instapaper')) {
  2590. this.send_story_to_instapaper(story.id);
  2591. } else {
  2592. this.send_story_to_email(story);
  2593. }
  2594. }, this)),
  2595. $.make('li', { className: 'NB-menu-item NB-menu-manage-story NB-menu-manage-story-share' }, [
  2596. $.make('div', { className: 'NB-menu-manage-image' }),
  2597. $.make('div', { className: 'NB-menu-manage-title' }, shared_title)
  2598. ]),
  2599. $.make('li', { className: 'NB-menu-subitem NB-menu-manage-story NB-menu-manage-confirm NB-menu-manage-story-share-confirm NB-modal-submit' }, [
  2600. $.make('div', { className: 'NB-menu-manage-confirm-position' }, [
  2601. story.story_share_menu_view.render().el
  2602. ])
  2603. ]),
  2604. $.make('li', { className: 'NB-menu-separator' }),
  2605. $.make('li', { className: 'NB-menu-item NB-menu-manage-story-train' }, [
  2606. $.make('div', { className: 'NB-menu-manage-image' }),
  2607. $.make('div', { className: 'NB-menu-manage-title' }, 'Intelligence trainer'),
  2608. $.make('div', { className: 'NB-menu-manage-subtitle' }, 'What you like and dislike.')
  2609. ])
  2610. ]);
  2611. $manage_menu.data('feed_id', feed_id);
  2612. $manage_menu.data('story_id', story_id);
  2613. $manage_menu.data('$story', $item);
  2614. // this.update_share_button_label($('.NB-sideoption-share-comments', $manage_menu));
  2615. }
  2616. if (inverse) $manage_menu.addClass('NB-inverse');
  2617. return $manage_menu;
  2618. },
  2619. show_manage_menu: function(type, $item, options) {
  2620. var self = this;
  2621. var options = _.extend({
  2622. 'toplevel': false,
  2623. 'inverse': false
  2624. }, options);
  2625. var $manage_menu_container = $('.NB-menu-manage-container');
  2626. clearTimeout(this.flags.closed_manage_menu);
  2627. this.flags['showing_confirm_input_on_manage_menu'] = false;
  2628. // If another menu is open, hide it first.
  2629. // If this menu is already open, then hide it instead.
  2630. if (($item && $item[0] == $manage_menu_container.data('item')) &&
  2631. parseInt($manage_menu_container.css('opacity'), 10) == 1) {
  2632. this.hide_manage_menu(type, $item);
  2633. return;
  2634. } else {
  2635. this.hide_manage_menu(type, $item);
  2636. }
  2637. if ($item.hasClass('NB-empty')) return;
  2638. $item.addClass('NB-showing-menu');
  2639. // Create menu, size and position it, then attach to the right place.
  2640. var feed_id, inverse, story_id;
  2641. if (type == 'folder') {
  2642. feed_id = options.folder_title;
  2643. inverse = options.inverse || $item.hasClass("NB-hover-inverse");
  2644. } else if (type == 'feed') {
  2645. feed_id = options.feed_id;
  2646. inverse = options.inverse || $item.hasClass("NB-hover-inverse");
  2647. } else if (type == 'socialfeed') {
  2648. feed_id = options.feed_id;
  2649. inverse = options.inverse || $item.hasClass("NB-hover-inverse");
  2650. } else if (type == 'story') {
  2651. story_id = options.story_id;
  2652. if ($item.hasClass('NB-hover-inverse')) inverse = true;
  2653. } else if (type == 'site') {
  2654. $('.NB-task-manage').tipsy('hide');
  2655. $('.NB-task-manage').tipsy('disable');
  2656. }
  2657. var toplevel = options.toplevel || $item.hasClass("NB-toplevel") ||
  2658. $item.children('.folder_title').hasClass("NB-toplevel");
  2659. var $manage_menu = this.make_manage_menu(type, feed_id, story_id, inverse, $item);
  2660. this.show_correct_feed_view_options_in_menu($manage_menu);
  2661. $manage_menu_container.empty().append($manage_menu);
  2662. $manage_menu_container.data('item', $item && $item[0]);
  2663. $('.NB-task-manage').parents('.NB-taskbar').css('z-index', 2);
  2664. if (type == 'site') {
  2665. $manage_menu_container.align($('.NB-task-manage'), '-bottom -left', {
  2666. 'top': -32,
  2667. 'left': -2
  2668. });
  2669. $('.NB-task-manage').addClass('NB-hover');
  2670. $manage_menu_container.corner('tl tr 8px');
  2671. } else if (type == 'feed' || type == 'folder' || type == 'story' || type == 'socialfeed') {
  2672. var left, top;
  2673. // NEWSBLUR.log(['menu open', $item, inverse, toplevel, type]);
  2674. if (inverse) {
  2675. var $align = $item;
  2676. if (type == 'feed') {
  2677. left = toplevel ? 2 : -20;
  2678. top = toplevel ? 21 : 21;
  2679. } else if (type == 'socialfeed') {
  2680. left = toplevel ? 2 : -20;
  2681. top = toplevel ? 21 : 21;
  2682. } else if (type == 'folder') {
  2683. left = toplevel ? 0 : -20;
  2684. top = toplevel ? 23 : 24;
  2685. $align = $('.folder_title', $item);
  2686. } else if (type == 'story') {
  2687. left = 4;
  2688. top = 24 ;
  2689. $align = $('.NB-story-manage-icon,.NB-feed-story-manage-icon', $item);
  2690. if (!$align.is(':visible')) {
  2691. $align = $('.NB-storytitles-sentiment', $item);
  2692. }
  2693. }
  2694. $manage_menu_container.align($align, '-bottom -left', {
  2695. 'top': -1 * top,
  2696. 'left': left
  2697. });
  2698. $manage_menu_container.corner('br 8px');
  2699. $manage_menu_container.find('.NB-menu-manage > li.NB-menu-separator-inverse').each(function() {
  2700. $(this).appendTo($(this).parent());
  2701. });
  2702. } else {
  2703. var $align = $item;
  2704. if (type == 'feed') {
  2705. left = toplevel ? 2 : 0;
  2706. top = toplevel ? 21 : 21;
  2707. $align = $('.NB-feedlist-manage-icon', $item);
  2708. } else if (type == 'socialfeed') {
  2709. left = toplevel ? 2 : -18;
  2710. top = toplevel ? 21 : 21;
  2711. $align = $('.NB-feedlist-manage-icon', $item);
  2712. } else if (type == 'folder') {
  2713. left = toplevel ? 2 : -20;
  2714. top = toplevel ? 22 : 22;
  2715. } else if (type == 'story') {
  2716. left = 4;
  2717. top = 18;
  2718. $align = $('.NB-story-manage-icon,.NB-feed-story-manage-icon', $item);
  2719. if (!$align.is(':visible')) {
  2720. $align = $('.NB-storytitles-sentiment', $item);
  2721. }
  2722. }
  2723. $manage_menu_container.align($align, '-top -left', {
  2724. 'top': top,
  2725. 'left': left
  2726. });
  2727. $manage_menu_container.corner('tr 8px');
  2728. }
  2729. }
  2730. $manage_menu_container.stop().css({'display': 'block', 'opacity': 1});
  2731. // Create and position the arrow tab
  2732. if (type == 'feed' || type == 'folder' || type == 'story' || type == 'socialfeed') {
  2733. var $arrow = $.make('div', { className: 'NB-menu-manage-arrow' });
  2734. if (inverse) {
  2735. $arrow.corner('bl br 5px');
  2736. $manage_menu_container.append($arrow);
  2737. $arrow.addClass('NB-inverse');
  2738. } else {
  2739. $arrow.corner('tl tr 5px');
  2740. $manage_menu_container.prepend($arrow);
  2741. }
  2742. }
  2743. // Hide menu on click outside menu.
  2744. _.defer(function() {
  2745. var close_menu_handler = function(e) {
  2746. _.defer(function() {
  2747. $(document).bind('click.menu', function(e) {
  2748. self.hide_manage_menu(type, $item, false);
  2749. });
  2750. });
  2751. };
  2752. if (options.rightclick) {
  2753. $(document).one('mouseup.menu', close_menu_handler);
  2754. } else {
  2755. close_menu_handler();
  2756. }
  2757. });
  2758. // Hide menu on mouseout (on a delay).
  2759. $manage_menu_container.hover(function() {
  2760. clearTimeout(self.flags.closed_manage_menu);
  2761. }, function() {
  2762. clearTimeout(self.flags.closed_manage_menu);
  2763. self.flags.closed_manage_menu = setTimeout(function() {
  2764. if (self.flags.closed_manage_menu) {
  2765. self.hide_manage_menu(type, $item, true);
  2766. }
  2767. }, 1000);
  2768. });
  2769. // Hide menu on esc.
  2770. $('input,textarea', $manage_menu_container).bind('keydown.manage_menu', 'esc', function(e) {
  2771. e.preventDefault();
  2772. self.flags['showing_confirm_input_on_manage_menu'] = false;
  2773. self.hide_manage_menu(type, $item, true);
  2774. });
  2775. if (type == 'story') {
  2776. var share = _.bind(function(e) {
  2777. e.preventDefault();
  2778. var story = NEWSBLUR.assets.get_story(story_id);
  2779. story.story_share_menu_view.mark_story_as_shared({'source': 'menu'});
  2780. }, this);
  2781. $('.NB-sideoption-share-comments', $manage_menu_container).bind('keydown', 'ctrl+return', share);
  2782. $('.NB-sideoption-share-comments', $manage_menu_container).bind('keydown', 'meta+return', share);
  2783. }
  2784. // Hide menu on scroll.
  2785. var $scroll;
  2786. this.flags['feed_list_showing_manage_menu'] = true;
  2787. if (type == 'feed' || type == 'socialfeed') {
  2788. $scroll = this.$s.$feed_list.parent();
  2789. } else if (type == 'story') {
  2790. $scroll = this.$s.$story_titles.add(this.$s.$feed_stories);
  2791. }
  2792. $scroll && $scroll.unbind('scroll.manage_menu').bind('scroll.manage_menu', function(e) {
  2793. if (self.flags['feed_list_showing_manage_menu']) {
  2794. self.hide_manage_menu(type, $item, true);
  2795. } else {
  2796. $scroll.unbind('scroll.manage_menu');
  2797. }
  2798. });
  2799. },
  2800. hide_manage_menu: function(type, $item, animate) {
  2801. var $manage_menu_container = $('.NB-menu-manage-container');
  2802. var height = $manage_menu_container.outerHeight();
  2803. if (this.flags['showing_confirm_input_on_manage_menu'] && animate) return;
  2804. // NEWSBLUR.log(['hide_manage_menu', type, $item, animate, $manage_menu_container.css('opacity')]);
  2805. clearTimeout(this.flags.closed_manage_menu);
  2806. this.flags['feed_list_showing_manage_menu'] = false;
  2807. $(document).unbind('click.menu');
  2808. $(document).unbind('mouseup.menu');
  2809. if (this.model.preference('show_tooltips')) {
  2810. $('.NB-task-manage').tipsy('enable');
  2811. }
  2812. if ($item) $item.removeClass('NB-showing-menu');
  2813. if (animate) {
  2814. $manage_menu_container.stop().animate({
  2815. 'opacity': 0
  2816. }, {
  2817. 'duration': 250,
  2818. 'queue': false,
  2819. 'complete': function() {
  2820. $manage_menu_container.css({'display': 'none', 'opacity': 0});
  2821. }
  2822. });
  2823. } else {
  2824. $manage_menu_container.css({'display': 'none', 'opacity': 0});
  2825. }
  2826. $('.NB-task-manage').removeClass('NB-hover');
  2827. this.blur_to_page({manage_menu: true});
  2828. },
  2829. show_correct_feed_view_options_in_menu: function($manage_menu) {
  2830. $manage_menu = $manage_menu || $('.NB-menu-manage');
  2831. if ($manage_menu.hasClass("NB-menu-manage-feed")) {
  2832. var feed_id = $manage_menu.data('feed_id');
  2833. } else {
  2834. var feed_id = 'river:' + $manage_menu.data('folder_name');
  2835. }
  2836. var order = NEWSBLUR.assets.view_setting(feed_id, 'order');
  2837. var read_filter = NEWSBLUR.assets.view_setting(feed_id, 'read_filter');
  2838. var $oldest = $('.NB-view-setting-order-oldest', $manage_menu);
  2839. var $newest = $('.NB-view-setting-order-newest', $manage_menu);
  2840. var $unread = $('.NB-view-setting-readfilter-unread', $manage_menu);
  2841. var $all = $('.NB-view-setting-readfilter-all', $manage_menu);
  2842. $oldest.toggleClass('NB-active', order == 'oldest');
  2843. $newest.toggleClass('NB-active', order != 'oldest');
  2844. $oldest.text('Oldest' + (order == 'oldest' ? ' first' : ''));
  2845. $newest.text('Newest' + (order != 'oldest' ? ' first' : ''));
  2846. $unread.toggleClass('NB-active', read_filter == 'unread');
  2847. $all.toggleClass('NB-active', read_filter != 'unread');
  2848. },
  2849. // ========================
  2850. // = Manage menu - Delete =
  2851. // ========================
  2852. show_confirm_delete_menu_item: function() {
  2853. var $delete = $('.NB-menu-manage-feed-delete,.NB-menu-manage-folder-delete');
  2854. var $confirm = $('.NB-menu-manage-feed-delete-confirm,.NB-menu-manage-folder-delete-confirm');
  2855. $delete.addClass('NB-menu-manage-feed-delete-cancel');
  2856. $('.NB-menu-manage-title', $delete).text('Cancel delete');
  2857. $confirm.slideDown(500);
  2858. },
  2859. hide_confirm_delete_menu_item: function() {
  2860. var $delete = $('.NB-menu-manage-feed-delete,.NB-menu-manage-folder-delete');
  2861. var $confirm = $('.NB-menu-manage-feed-delete-confirm,.NB-menu-manage-folder-delete-confirm');
  2862. $delete.removeClass('NB-menu-manage-feed-delete-cancel');
  2863. var text = $delete.hasClass('NB-menu-manage-folder-delete') ?
  2864. 'Delete this folder' :
  2865. 'Delete this site';
  2866. $('.NB-menu-manage-title', $delete).text(text);
  2867. $confirm.slideUp(500);
  2868. },
  2869. manage_menu_delete_feed: function(feed_id, $feed) {
  2870. var self = this;
  2871. feed_id = feed_id || this.active_feed;
  2872. var feed = this.model.get_feed(feed_id);
  2873. var feed_view = feed.get_view($feed);
  2874. feed.delete_feed({view: feed_view});
  2875. },
  2876. show_confirm_unfollow_menu_item: function() {
  2877. var $unfollow = $('.NB-menu-manage-socialfeed-delete');
  2878. var $confirm = $('.NB-menu-manage-socialfeed-delete-confirm');
  2879. $unfollow.addClass('NB-menu-manage-socialfeed-delete-cancel');
  2880. $('.NB-menu-manage-title', $unfollow).text('Cancel unfollow');
  2881. $confirm.slideDown(500);
  2882. },
  2883. hide_confirm_unfollow_menu_item: function() {
  2884. var $unfollow = $('.NB-menu-manage-socialfeed-delete,.NB-menu-manage-folder-delete');
  2885. var $confirm = $('.NB-menu-manage-socialfeed-delete-confirm,.NB-menu-manage-folder-delete-confirm');
  2886. $unfollow.removeClass('NB-menu-manage-socialfeed-delete-cancel');
  2887. $('.NB-menu-manage-title', $unfollow).text('Unfollow');
  2888. $confirm.slideUp(500);
  2889. },
  2890. manage_menu_unfollow_feed: function(feed, $feed) {
  2891. var self = this;
  2892. var feed_id = feed || this.active_feed;
  2893. this.model.unfollow_user(feed_id, function() {
  2894. NEWSBLUR.app.feed_list.make_social_feeds();
  2895. });
  2896. },
  2897. manage_menu_delete_folder: function(folder_title, $folder) {
  2898. var self = this;
  2899. var folder_view = NEWSBLUR.assets.folders.get_view($folder) ||
  2900. this.active_folder.folder_view;
  2901. folder_view.model.delete_folder();
  2902. },
  2903. // ========================
  2904. // = Manage menu - Move =
  2905. // ========================
  2906. show_confirm_move_menu_item: function(feed_id, $feed) {
  2907. var self = this;
  2908. var $move = $('.NB-menu-manage-feed-move,.NB-menu-manage-folder-move');
  2909. var $confirm = $('.NB-menu-manage-feed-move-confirm,.NB-menu-manage-folder-move-confirm');
  2910. var $position = $('.NB-menu-manage-confirm-position', $confirm);
  2911. var $select = $('select', $confirm);
  2912. if (_.isNumber(feed_id)) {
  2913. var feed = this.model.get_feed(feed_id);
  2914. var feed_view = feed.get_view($feed, true);
  2915. var in_folder = feed_view.options.folder_title;
  2916. } else {
  2917. folder_view = NEWSBLUR.assets.folders.get_view($feed) ||
  2918. this.active_folder.folder_view;
  2919. var in_folder = folder_view.collection.options.title;
  2920. }
  2921. $move.addClass('NB-menu-manage-feed-move-cancel');
  2922. $('.NB-menu-manage-title', $move).text('Cancel move');
  2923. $position.css('position', 'relative');
  2924. var height = $confirm.height();
  2925. $position.css('position', 'absolute');
  2926. $confirm.css({'height': 0, 'display': 'block'}).animate({'height': height}, {
  2927. 'duration': 500,
  2928. 'easing': 'easeOutQuart'
  2929. });
  2930. $('select', $confirm).focus().select();
  2931. this.flags['showing_confirm_input_on_manage_menu'] = true;
  2932. $('option', $select).each(function() {
  2933. if ($(this).attr('value') == in_folder) {
  2934. $(this).attr('selected', 'selected');
  2935. return false;
  2936. }
  2937. });
  2938. },
  2939. hide_confirm_move_menu_item: function(moved) {
  2940. var $move = $('.NB-menu-manage-feed-move,.NB-menu-manage-folder-move');
  2941. var $confirm = $('.NB-menu-manage-feed-move-confirm,.NB-menu-manage-folder-move-confirm');
  2942. $move.removeClass('NB-menu-manage-feed-move-cancel');
  2943. var text = 'Move to folder';
  2944. if (moved) {
  2945. text = 'Moved';
  2946. $move.addClass('NB-active');
  2947. } else {
  2948. $move.removeClass('NB-active');
  2949. }
  2950. $('.NB-menu-manage-title', $move).text(text);
  2951. $confirm.slideUp(500);
  2952. this.flags['showing_confirm_input_on_manage_menu'] = false;
  2953. },
  2954. manage_menu_move_feed: function(feed_id, $feed) {
  2955. var self = this;
  2956. var feed_id = feed_id || this.active_feed;
  2957. var to_folder = $('.NB-menu-manage-feed-move-confirm select').val();
  2958. var feed = this.model.get_feed(feed_id);
  2959. var feed_view = feed.get_view($feed);
  2960. var moved = feed.move_to_folder(to_folder, {view: feed_view});
  2961. this.hide_confirm_move_menu_item(moved);
  2962. if (moved) {
  2963. _.delay(_.bind(function() {
  2964. this.hide_manage_menu('feed', $feed, true);
  2965. }, this), 500);
  2966. }
  2967. },
  2968. manage_menu_move_folder: function(folder, $folder) {
  2969. var self = this;
  2970. var to_folder = $('.NB-menu-manage-folder-move-confirm select').val();
  2971. var folder_view = NEWSBLUR.assets.folders.get_view($folder) ||
  2972. this.active_folder.folder_view;
  2973. var in_folder = folder_view.collection.options.title;
  2974. var folder_name = folder_view.options.folder_title;
  2975. var child_folders = folder_view.collection.child_folder_names();
  2976. if (to_folder == in_folder ||
  2977. to_folder == folder_name ||
  2978. _.contains(child_folders, to_folder)) {
  2979. return this.hide_confirm_move_menu_item();
  2980. }
  2981. var moved = folder_view.model.move_to_folder(to_folder, {view: folder_view});
  2982. this.hide_confirm_move_menu_item(moved);
  2983. if (moved) {
  2984. _.delay(_.bind(function() {
  2985. this.hide_manage_menu('folder', $folder, true);
  2986. }, this), 500);
  2987. }
  2988. },
  2989. // ========================
  2990. // = Manage menu - Rename =
  2991. // ========================
  2992. show_confirm_rename_menu_item: function() {
  2993. var self = this;
  2994. var $rename = $('.NB-menu-manage-feed-rename,.NB-menu-manage-folder-rename');
  2995. var $confirm = $('.NB-menu-manage-feed-rename-confirm,.NB-menu-manage-folder-rename-confirm');
  2996. var $position = $('.NB-menu-manage-confirm-position', $confirm);
  2997. $rename.addClass('NB-menu-manage-feed-rename-cancel');
  2998. $('.NB-menu-manage-title', $rename).text('Cancel rename');
  2999. $position.css('position', 'relative');
  3000. var height = $confirm.height();
  3001. $position.css('position', 'absolute');
  3002. $confirm.css({'height': 0, 'display': 'block'}).animate({'height': height}, {
  3003. 'duration': 500,
  3004. 'easing': 'easeOutQuart'
  3005. });
  3006. $('input', $confirm).focus().select();
  3007. this.flags['showing_confirm_input_on_manage_menu'] = true;
  3008. $('.NB-menu-manage-feed-rename-confirm input.NB-menu-manage-title').bind('keyup', 'return', function(e) {
  3009. var $t = $(e.target);
  3010. var feed_id = $t.closest('.NB-menu-manage').data('feed_id');
  3011. var $feed = $t.closest('.NB-menu-manage').data('$feed');
  3012. self.manage_menu_rename_feed(feed_id, $feed);
  3013. });
  3014. $('.NB-menu-manage-folder-rename-confirm input.NB-menu-manage-title').bind('keyup', 'return', function(e) {
  3015. var $t = $(e.target);
  3016. var folder_name = $t.parents('.NB-menu-manage').data('folder_name');
  3017. var $folder = $t.parents('.NB-menu-manage').data('$folder');
  3018. self.manage_menu_rename_folder(folder_name, $folder);
  3019. });
  3020. },
  3021. hide_confirm_rename_menu_item: function(renamed) {
  3022. var $rename = $('.NB-menu-manage-feed-rename,.NB-menu-manage-folder-rename');
  3023. var $confirm = $('.NB-menu-manage-feed-rename-confirm,.NB-menu-manage-folder-rename-confirm');
  3024. $rename.removeClass('NB-menu-manage-feed-rename-cancel');
  3025. var text = $rename.hasClass('NB-menu-manage-folder-rename') ?
  3026. 'Rename this folder' :
  3027. 'Rename this site';
  3028. if (renamed) {
  3029. text = 'Renamed';
  3030. $rename.addClass('NB-active');
  3031. } else {
  3032. $rename.removeClass('NB-active');
  3033. }
  3034. $('.NB-menu-manage-title', $rename).text(text);
  3035. $confirm.slideUp(500);
  3036. this.flags['showing_confirm_input_on_manage_menu'] = false;
  3037. },
  3038. manage_menu_rename_feed: function(feed_id) {
  3039. var feed_id = feed_id || this.active_feed;
  3040. var feed = this.model.get_feed(feed_id);
  3041. var new_title = $('.NB-menu-manage-feed-rename-confirm .NB-menu-manage-title').val();
  3042. if (new_title.length > 0) feed.rename(new_title);
  3043. this.hide_confirm_rename_menu_item(true);
  3044. },
  3045. manage_menu_rename_folder: function(folder, $folder) {
  3046. var self = this;
  3047. var new_folder_name = $('.NB-menu-manage-folder-rename-confirm .NB-menu-manage-title').val();
  3048. var folder_view = NEWSBLUR.assets.folders.get_view($folder) ||
  3049. this.active_folder.folder_view;
  3050. if (new_folder_name.length > 0) folder_view.model.rename(new_folder_name);
  3051. this.hide_confirm_rename_menu_item(true);
  3052. },
  3053. // =============================
  3054. // = Manage Menu - Share Story =
  3055. // =============================
  3056. show_confirm_story_share_menu_item: function(story_id) {
  3057. var self = this;
  3058. if (!story_id) story_id = $('.NB-menu-manage').data('story_id');
  3059. var story = NEWSBLUR.assets.get_story(story_id);
  3060. var $share = $('.NB-menu-manage-story-share');
  3061. var $confirm = $('.NB-menu-manage-story-share-confirm');
  3062. var $story_share = story.story_share_menu_view.$el;
  3063. var $position = $('.NB-menu-manage-confirm-position', $confirm);
  3064. $share.addClass('NB-menu-manage-story-share-cancel');
  3065. $('.NB-menu-manage-title', $share).text('Cancel share');
  3066. $confirm.css({'height': 0, 'display': 'block'});
  3067. story.story_share_menu_view.toggle_feed_story_share_dialog({immediate: true});
  3068. $position.css('position', 'relative');
  3069. var height = $story_share.height();
  3070. $position.css('position', 'absolute');
  3071. $confirm.css({'height': 0, 'display': 'block'}).animate({'height': height}, {
  3072. 'duration': 500,
  3073. 'easing': 'easeOutQuart'
  3074. });
  3075. $('textarea', $confirm).focus().select();
  3076. this.flags['showing_confirm_input_on_manage_menu'] = true;
  3077. },
  3078. hide_confirm_story_share_menu_item: function(shared) {
  3079. var story_id = $('.NB-menu-manage').data('story_id');
  3080. var story = NEWSBLUR.assets.get_story(story_id);
  3081. var $share = $('.NB-menu-manage-story-share');
  3082. var $confirm = $('.NB-menu-manage-story-share-confirm');
  3083. $share.removeClass('NB-menu-manage-story-share-cancel');
  3084. var text = 'Share to your Blurblog';
  3085. if (shared) {
  3086. text = 'Shared';
  3087. $share.addClass('NB-active');
  3088. } else {
  3089. $share.removeClass('NB-active');
  3090. }
  3091. $('.NB-menu-manage-title', $share).text(text);
  3092. $confirm.slideUp(500, _.bind(function() {
  3093. if (shared) {
  3094. this.hide_manage_menu('story', story.story_title_view.$el, true);
  3095. }
  3096. }, this));
  3097. this.flags['showing_confirm_input_on_manage_menu'] = false;
  3098. },
  3099. // ==========================
  3100. // = Taskbar - Intelligence =
  3101. // ==========================
  3102. load_intelligence_slider: function() {
  3103. var self = this;
  3104. var $slider = this.$s.$intelligence_slider;
  3105. var unread_view = this.get_unread_view_score();
  3106. if (unread_view == 0 && !NEWSBLUR.assets.preference('hide_read_feeds')) {
  3107. unread_view = -1;
  3108. }
  3109. this.slide_intelligence_slider(unread_view, true);
  3110. },
  3111. toggle_focus_in_slider: function() {
  3112. var $slider = this.$s.$intelligence_slider;
  3113. var $focus = $(".NB-intelligence-slider-green", $slider);
  3114. var show_focus = NEWSBLUR.assets.feeds.any(function(feed) {
  3115. return feed.get('ps');
  3116. });
  3117. $focus.css('display', show_focus ? 'block' : 'none');
  3118. if (!show_focus) {
  3119. if (NEWSBLUR.assets.preference('unread_view') > 0) {
  3120. this.slide_intelligence_slider(0);
  3121. }
  3122. }
  3123. },
  3124. slide_intelligence_slider: function(value, initial_load) {
  3125. var $slider = this.$s.$intelligence_slider;
  3126. var real_value = value;
  3127. if (value < 0) {
  3128. value = 0;
  3129. if (!initial_load) {
  3130. NEWSBLUR.assets.preference('hide_read_feeds', 0);
  3131. }
  3132. NEWSBLUR.assets.preference('unread_view', 0);
  3133. } else if (value == 0) {
  3134. if (!initial_load) {
  3135. NEWSBLUR.assets.preference('hide_read_feeds', 1);
  3136. }
  3137. NEWSBLUR.assets.preference('unread_view', 0);
  3138. } else if (value > 0) {
  3139. if (!initial_load) {
  3140. NEWSBLUR.assets.preference('hide_read_feeds', 1);
  3141. }
  3142. NEWSBLUR.assets.preference('unread_view', 1);
  3143. }
  3144. this.flags['unread_threshold_temporarily'] = null;
  3145. this.switch_feed_view_unread_view(value);
  3146. if (NEWSBLUR.app.story_titles_header) {
  3147. NEWSBLUR.app.story_titles_header.show_feed_hidden_story_title_indicator(true);
  3148. }
  3149. this.show_story_titles_above_intelligence_level({'animate': true, 'follow': true});
  3150. NEWSBLUR.app.sidebar_header.toggle_hide_read_preference();
  3151. NEWSBLUR.app.feed_list.scroll_to_show_selected_feed();
  3152. NEWSBLUR.app.feed_list.scroll_to_show_selected_folder();
  3153. $('.NB-active', $slider).removeClass('NB-active');
  3154. if (real_value < 0) {
  3155. $('.NB-intelligence-slider-red', $slider).addClass('NB-active');
  3156. } else if (real_value > 0) {
  3157. $('.NB-intelligence-slider-green', $slider).addClass('NB-active');
  3158. } else {
  3159. $('.NB-intelligence-slider-yellow', $slider).addClass('NB-active');
  3160. }
  3161. },
  3162. move_intelligence_slider: function(direction) {
  3163. var value = this.model.preference('unread_view') + direction;
  3164. this.slide_intelligence_slider(value);
  3165. },
  3166. switch_feed_view_unread_view: function(unread_view) {
  3167. if (!_.isNumber(unread_view)) unread_view = this.get_unread_view_score();
  3168. var $sidebar = this.$s.$sidebar;
  3169. var unread_view_name = this.get_unread_view_name(unread_view);
  3170. var $next_story_button = $('.task_story_next_unread');
  3171. var $story_title_indicator = $('.NB-story-title-indicator', this.$story_titles);
  3172. $sidebar.removeClass('unread_view_positive')
  3173. .removeClass('unread_view_neutral')
  3174. .removeClass('unread_view_negative')
  3175. .addClass('unread_view_'+unread_view_name);
  3176. $next_story_button.removeClass('task_story_next_positive')
  3177. .removeClass('task_story_next_neutral')
  3178. .removeClass('task_story_next_negative')
  3179. .addClass('task_story_next_'+unread_view_name);
  3180. $story_title_indicator.removeClass('unread_threshold_positive')
  3181. .removeClass('unread_threshold_neutral')
  3182. .removeClass('unread_threshold_negative')
  3183. .addClass('unread_threshold_'+unread_view_name);
  3184. },
  3185. get_unread_view_score: function() {
  3186. if (this.flags['unread_threshold_temporarily']) {
  3187. var score_name = this.flags['unread_threshold_temporarily'];
  3188. if (score_name == 'neutral') {
  3189. return 0;
  3190. } else if (score_name == 'negative') {
  3191. return -1;
  3192. }
  3193. }
  3194. return this.model.preference('unread_view');
  3195. },
  3196. get_unread_view_name: function(unread_view) {
  3197. if (this.flags['unread_threshold_temporarily']) {
  3198. return this.flags['unread_threshold_temporarily'];
  3199. }
  3200. if (typeof unread_view == 'undefined') {
  3201. unread_view = this.get_unread_view_score();
  3202. }
  3203. return (unread_view > 0
  3204. ? 'positive'
  3205. : unread_view < 0
  3206. ? 'negative'
  3207. : 'neutral');
  3208. },
  3209. get_unread_count: function(visible_only, feed_id) {
  3210. var total = 0;
  3211. var $folder;
  3212. feed_id = feed_id || this.active_feed;
  3213. var feed = this.model.get_feed(feed_id);
  3214. if (feed_id == 'starred') {
  3215. // Umm, no. Not yet.
  3216. } else if (feed) {
  3217. if (!visible_only) {
  3218. total = feed.get('ng') + feed.get('nt') + feed.get('ps');
  3219. } else {
  3220. var unread_view_name = this.get_unread_view_name();
  3221. if (unread_view_name == 'positive') {
  3222. total = feed.get('ps');
  3223. } else if (unread_view_name == 'neutral') {
  3224. total = feed.get('ps') + feed.get('nt');
  3225. } else if (unread_view_name == 'negative') {
  3226. total = feed.get('ps') + feed.get('nt') + feed.get('ng');
  3227. }
  3228. }
  3229. return total;
  3230. } else if (this.flags['river_view'] && !this.flags['social_view']) {
  3231. if (feed_id == 'river:') {
  3232. $folder = this.$s.$feed_list;
  3233. } else {
  3234. $folder = $('li.folder.NB-selected');
  3235. }
  3236. var counts = this.list_feeds_with_unreads_in_folder($folder, true, visible_only);
  3237. return _.reduce(counts, function(m, c) { return m + c; }, 0);
  3238. } else if (this.flags['river_view'] && this.flags['social_view']) {
  3239. var unread_score = this.get_unread_view_score();
  3240. return NEWSBLUR.assets.social_feeds.reduce(function(m, feed) {
  3241. return m + feed.get('ps') + (unread_score >= 0 && feed.get('nt'));
  3242. }, 0);
  3243. }
  3244. },
  3245. show_story_titles_above_intelligence_level: function(opts) {
  3246. var defaults = {
  3247. 'unread_view_name': null,
  3248. 'animate': true,
  3249. 'follow': true,
  3250. 'temporary': false
  3251. };
  3252. var options = $.extend({}, defaults, opts);
  3253. var self = this;
  3254. var $story_titles = this.$s.$story_titles;
  3255. var unread_view_name = options['unread_view_name'] || this.get_unread_view_name();
  3256. var $stories_show, $stories_hide;
  3257. if (this.model.stories.length > 18) {
  3258. options['animate'] = false;
  3259. }
  3260. if (this.flags['unread_threshold_temporarily']) {
  3261. options['temporary'] = true;
  3262. }
  3263. if (unread_view_name == 'positive') {
  3264. $stories_show = $('.story,.NB-feed-story').filter('.NB-story-positive');
  3265. $stories_hide = $('.story,.NB-feed-story')
  3266. .filter('.NB-story-neutral,.NB-story-negative');
  3267. } else if (unread_view_name == 'neutral') {
  3268. $stories_show = $('.story,.NB-feed-story')
  3269. .filter('.NB-story-positive,.NB-story-neutral');
  3270. $stories_hide = $('.story,.NB-feed-story').filter('.NB-story-negative');
  3271. if (options['temporary']) {
  3272. $stories_show.filter('.NB-story-neutral').addClass('NB-story-hidden-visible');
  3273. } else {
  3274. $stories_show.filter('.NB-story-hidden-visible').removeClass('NB-story-hidden-visible');
  3275. }
  3276. } else if (unread_view_name == 'negative') {
  3277. $stories_show = $('.story,.NB-feed-story')
  3278. .filter('.NB-story-positive,.NB-story-neutral,.NB-story-negative');
  3279. $stories_hide = $();
  3280. if (options['temporary']) {
  3281. $stories_show.filter('.NB-story-negative,.NB-story-neutral:not(:visible)')
  3282. .addClass('NB-story-hidden-visible');
  3283. } else {
  3284. $stories_show.filter('.NB-story-hidden-visible').removeClass('NB-story-hidden-visible');
  3285. }
  3286. }
  3287. if ((this.story_view == 'feed' || this.flags['page_view_showing_feed_view']) &&
  3288. NEWSBLUR.assets.preference('feed_view_single_story')) {
  3289. // No need to show/hide feed view stories under single_story preference.
  3290. // If the user switches to feed/page, then no animation is happening
  3291. // and this will work anyway.
  3292. var active_story = this.active_story;
  3293. var $active_story = this.active_story && this.active_story.story_view.$el;
  3294. if ($active_story && $active_story.length || true) {
  3295. $stories_show = $stories_show.not('.NB-feed-story');
  3296. $stories_hide = $stories_hide.not('.NB-feed-story');
  3297. }
  3298. NEWSBLUR.log(["single story", $stories_show.length, $stories_hide.length, this.active_story, active_story && active_story.id]);
  3299. }
  3300. if (!options['animate']) {
  3301. $stories_hide.css({'display': 'none'});
  3302. $stories_show.css({'display': 'block'});
  3303. NEWSBLUR.app.story_titles.fill_out();
  3304. }
  3305. if (!NEWSBLUR.assets.preference('feed_view_single_story')) {
  3306. _.delay(function() {
  3307. NEWSBLUR.app.story_list.reset_story_positions();
  3308. }, 500);
  3309. }
  3310. if (options['animate'] && options['follow'] &&
  3311. ($stories_hide.length || $stories_show.length)) {
  3312. // NEWSBLUR.log(['Showing correct stories', this.story_view, unread_view_name, $stories_show.length, $stories_hide.length]);
  3313. if (this.model.preference('animations')) {
  3314. $stories_hide.slideUp(500, function() {
  3315. NEWSBLUR.app.story_titles.fill_out();
  3316. });
  3317. $stories_show.slideDown(500);
  3318. } else {
  3319. $stories_hide.css({'display': 'none'});
  3320. $stories_show.css({'display': 'block'});
  3321. NEWSBLUR.app.story_titles.fill_out();
  3322. }
  3323. setTimeout(function() {
  3324. if (!self.active_story) return;
  3325. NEWSBLUR.app.story_list.scroll_to_selected_story(self.active_story);
  3326. NEWSBLUR.app.story_titles.scroll_to_selected_story(self.active_story);
  3327. }, this.model.preference('animations') ? 550 : 0);
  3328. }
  3329. },
  3330. // ===================
  3331. // = Feed Refreshing =
  3332. // ===================
  3333. force_instafetch_stories: function(feed_id) {
  3334. var self = this;
  3335. feed_id = feed_id || this.active_feed;
  3336. var feed = this.model.get_feed(feed_id);
  3337. feed.set({
  3338. fetched_once: false,
  3339. has_exception: false
  3340. });
  3341. this.model.save_exception_retry(feed_id, _.bind(this.force_feed_refresh, this, feed_id),
  3342. this.show_stories_error);
  3343. },
  3344. setup_socket_realtime_unread_counts: function(force) {
  3345. if (!force && NEWSBLUR.Globals.is_anonymous) return;
  3346. // if (!force && !NEWSBLUR.Globals.is_premium) return;
  3347. if (this.socket && !this.socket.socket.connected) {
  3348. this.socket.socket.connect();
  3349. } else if (force || !this.socket || !this.socket.socket.connected) {
  3350. var port = _.string.startsWith(window.location.protocol, 'https') ? 8889 : 8888;
  3351. var server = window.location.protocol + '//' + window.location.hostname + ':' + port;
  3352. this.socket = this.socket || io.connect(server);
  3353. // this.socket.refresh_feeds = _.debounce(_.bind(this.force_feeds_refresh, this), 1000*10);
  3354. this.socket.on('connect', _.bind(function() {
  3355. var active_feeds = this.send_socket_active_feeds();
  3356. // NEWSBLUR.log(["Connected to real-time pubsub with " + active_feeds.length + " feeds."]);
  3357. this.socket.removeAllListeners('feed:update');
  3358. this.socket.on('feed:update', _.bind(function(feed_id, message) {
  3359. NEWSBLUR.log(['Real-time feed update', feed_id, message]);
  3360. this.feed_unread_count(feed_id);
  3361. }, this));
  3362. this.socket.removeAllListeners(NEWSBLUR.Globals.username);
  3363. this.socket.on('user:update', _.bind(function(username, feed_id) {
  3364. if (this.flags.social_view) return;
  3365. if (_.string.contains(feed_id, 'feed:')) {
  3366. feed_id = parseInt(feed_id.replace('feed:', ''), 10);
  3367. var active_feed_ids = [];
  3368. if (this.active_folder && this.active_folder.length) {
  3369. active_feed_ids = this.active_folder.feed_ids_in_folder();
  3370. }
  3371. if (feed_id != this.active_feed &&
  3372. !_.contains(active_feed_ids, feed_id)) {
  3373. NEWSBLUR.log(['Real-time user update', username, feed_id]);
  3374. this.feed_unread_count(feed_id);
  3375. }
  3376. } else if (_.string.contains(feed_id, 'social:')) {
  3377. if (feed_id != this.active_feed) {
  3378. NEWSBLUR.log(['Real-time user update', username, feed_id]);
  3379. this.feed_unread_count(feed_id);
  3380. }
  3381. }
  3382. }, this));
  3383. this.flags.feed_refreshing_in_realtime = true;
  3384. this.setup_feed_refresh();
  3385. // $('.NB-module-content-account-realtime-subtitle').html($.make('b', 'Updating in real-time'));
  3386. $('.NB-module-content-account-realtime').attr('title', 'Updating sites in real-time...').removeClass('NB-error');
  3387. }, this));
  3388. this.socket.on('disconnect', _.bind(function() {
  3389. NEWSBLUR.log(["Lost connection to real-time pubsub. Falling back to polling."]);
  3390. this.flags.feed_refreshing_in_realtime = false;
  3391. this.setup_feed_refresh();
  3392. // $('.NB-module-content-account-realtime-subtitle').html($.make('b', 'Updating every 60 sec'));
  3393. $('.NB-module-content-account-realtime').attr('title', 'Updating sites every ' + this.flags.refresh_interval + ' seconds...').addClass('NB-error');
  3394. }, this));
  3395. this.socket.on('error', _.bind(function() {
  3396. NEWSBLUR.log(["Can't connect to real-time pubsub."]);
  3397. this.flags.feed_refreshing_in_realtime = false;
  3398. // $('.NB-module-content-account-realtime-subtitle').html($.make('b', 'Updating every 60 sec'));
  3399. $('.NB-module-content-account-realtime').attr('title', 'Updating sites every ' + this.flags.refresh_interval + ' seconds...').addClass('NB-error');
  3400. _.delay(_.bind(this.setup_socket_realtime_unread_counts, this), 60*1000);
  3401. }, this));
  3402. }
  3403. },
  3404. send_socket_active_feeds: function() {
  3405. if (!this.socket) return;
  3406. var active_feeds = _.compact(this.model.feeds.map(function(feed) {
  3407. return feed.get('active') && feed.id;
  3408. }));
  3409. active_feeds = active_feeds.concat(this.model.social_feeds.pluck('id'));
  3410. if (active_feeds.length) {
  3411. this.socket.emit('subscribe:feeds', active_feeds, NEWSBLUR.Globals.username);
  3412. }
  3413. return active_feeds;
  3414. },
  3415. setup_feed_refresh: function(new_feeds) {
  3416. var self = this;
  3417. var refresh_interval = this.constants.FEED_REFRESH_INTERVAL;
  3418. var feed_count = this.model.feeds.size();
  3419. if (!NEWSBLUR.Globals.is_premium) {
  3420. refresh_interval *= 2;
  3421. }
  3422. if (feed_count > 250) {
  3423. refresh_interval *= 2;
  3424. }
  3425. if (feed_count > 500) {
  3426. refresh_interval *= 1.5;
  3427. }
  3428. if (this.flags['feed_refreshing_in_realtime'] && !this.flags['has_unfetched_feeds'] &&
  3429. this.socket && this.socket.socket.connected) {
  3430. refresh_interval *= 10;
  3431. }
  3432. if (new_feeds && feed_count < 250) {
  3433. refresh_interval = (1000 * 60) * 1/6;
  3434. } else if (new_feeds && feed_count < 500) {
  3435. refresh_interval = (1000 * 60) * 1/4;
  3436. }
  3437. // 10 second minimum
  3438. refresh_interval = Math.max(10*1000, refresh_interval);
  3439. clearInterval(this.flags.feed_refresh);
  3440. this.flags.feed_refresh = setInterval(function() {
  3441. if (!self.flags['pause_feed_refreshing']) {
  3442. self.force_feeds_refresh();
  3443. }
  3444. }, refresh_interval);
  3445. this.flags.refresh_interval = refresh_interval / 1000;
  3446. if (!this.socket || !this.socket.socket.connected) {
  3447. $('.NB-module-content-account-realtime').attr('title', 'Updating sites every ' + this.flags.refresh_interval + ' seconds...').addClass('NB-error');
  3448. }
  3449. NEWSBLUR.log(["Setting refresh interval to every " + refresh_interval/1000 + " seconds."]);
  3450. },
  3451. force_feed_refresh: function(feed_id, new_feed_id) {
  3452. var self = this;
  3453. feed_id = feed_id || this.active_feed;
  3454. new_feed_id = _.isNumber(new_feed_id) && new_feed_id || feed_id;
  3455. console.log(["force_feed_refresh", feed_id, new_feed_id]);
  3456. this.force_feeds_refresh(function() {
  3457. // Open the feed back up if it is being refreshed and is still open.
  3458. if (self.active_feed == feed_id || self.active_feed == new_feed_id) {
  3459. self.open_feed(new_feed_id, {force: true});
  3460. }
  3461. self.check_feed_fetch_progress();
  3462. }, true, new_feed_id, this.show_stories_error);
  3463. },
  3464. force_feeds_refresh: function(callback, replace_active_feed, feed_id, error_callback) {
  3465. if (callback) {
  3466. this.cache.refresh_callback = callback;
  3467. } else {
  3468. delete this.cache.refresh_callback;
  3469. }
  3470. this.flags['pause_feed_refreshing'] = true;
  3471. this.model.refresh_feeds(_.bind(function(updated_feeds) {
  3472. this.post_feed_refresh(updated_feeds, replace_active_feed, feed_id);
  3473. }, this), this.flags['has_unfetched_feeds'], feed_id, error_callback);
  3474. },
  3475. post_feed_refresh: function(updated_feeds, replace_active_feed, single_feed_id) {
  3476. var feeds = this.model.feeds;
  3477. if (this.cache.refresh_callback && $.isFunction(this.cache.refresh_callback)) {
  3478. this.cache.refresh_callback(feeds);
  3479. delete this.cache.refresh_callback;
  3480. }
  3481. this.flags['refresh_inline_feed_delay'] = false;
  3482. this.flags['pause_feed_refreshing'] = false;
  3483. this.check_feed_fetch_progress();
  3484. this.toggle_focus_in_slider();
  3485. },
  3486. feed_unread_count: function(feed_id) {
  3487. this.model.feed_unread_count(feed_id || this.active_feed);
  3488. },
  3489. // ===================
  3490. // = Mouse Indicator =
  3491. // ===================
  3492. setup_mousemove_on_views: function() {
  3493. this.hide_mouse_indicator();
  3494. if (this.story_view == 'story' ||
  3495. this.flags['feed_view_showing_story_view']) {
  3496. // this.hide_mouse_indicator();
  3497. } else {
  3498. _.delay(_.bind(this.show_mouse_indicator, this), 350);
  3499. }
  3500. },
  3501. hide_mouse_indicator: function() {
  3502. var self = this;
  3503. if (!this.flags['mouse_indicator_hidden']) {
  3504. this.flags['mouse_indicator_hidden'] = true;
  3505. this.$s.$mouse_indicator.animate({'opacity': 0, 'left': -10}, {
  3506. 'duration': 200,
  3507. 'queue': false,
  3508. 'complete': function() {
  3509. self.flags['mouse_indicator_hidden'] = true;
  3510. }
  3511. });
  3512. }
  3513. },
  3514. show_mouse_indicator: function() {
  3515. var self = this;
  3516. if (this.flags['mouse_indicator_hidden']) {
  3517. this.flags['mouse_indicator_hidden'] = false;
  3518. this.$s.$mouse_indicator.animate({'opacity': 1, 'left': 0}, {
  3519. 'duration': 200,
  3520. 'queue': false,
  3521. 'complete': function() {
  3522. self.flags['mouse_indicator_hidden'] = false;
  3523. }
  3524. });
  3525. }
  3526. },
  3527. handle_mouse_indicator_hover: function() {
  3528. var self = this;
  3529. var $callout = $('.NB-callout-mouse-indicator');
  3530. $('.NB-callout-text', $callout).text('Lock');
  3531. $callout.corner('5px');
  3532. this.$s.$mouse_indicator.hover(function() {
  3533. if (self.model.preference('lock_mouse_indicator')) {
  3534. $('.NB-callout-text', $callout).text('Unlock');
  3535. } else {
  3536. $('.NB-callout-text', $callout).text('Lock');
  3537. }
  3538. self.flags['still_hovering_on_mouse_indicator'] = true;
  3539. setTimeout(function() {
  3540. if (self.flags['still_hovering_on_mouse_indicator']) {
  3541. $callout.css({
  3542. 'display': 'block'
  3543. }).animate({
  3544. 'opacity': 1,
  3545. 'left': '20px'
  3546. }, {'duration': 200, 'queue': false});
  3547. }
  3548. }, 50);
  3549. }, function() {
  3550. self.flags['still_hovering_on_mouse_indicator'] = false;
  3551. $callout.animate({'opacity': 0, 'left': '-100px'}, {'duration': 200, 'queue': false});
  3552. });
  3553. },
  3554. lock_mouse_indicator: function() {
  3555. var self = this;
  3556. var $callout = $('.NB-callout-mouse-indicator');
  3557. if (self.model.preference('lock_mouse_indicator')) {
  3558. self.model.preference('lock_mouse_indicator', 0);
  3559. $('.NB-callout-text', $callout).text('Unlocked');
  3560. } else {
  3561. self.model.preference('lock_mouse_indicator', this.cache.mouse_position_y - NEWSBLUR.app.story_list.cache.story_pane_position);
  3562. $('.NB-callout-text', $callout).text('Locked');
  3563. }
  3564. setTimeout(function() {
  3565. self.flags['still_hovering_on_mouse_indicator'] = true;
  3566. $callout.fadeOut(200);
  3567. }, 500);
  3568. },
  3569. position_mouse_indicator: function() {
  3570. var position = this.model.preference('lock_mouse_indicator');
  3571. var container = this.layout.contentLayout.state.container.innerHeight - 30;
  3572. if (position <= 0 || position > container) {
  3573. position = 50; // Start with a 50 offset
  3574. } else {
  3575. position = position - 8; // Compensate for mouse indicator height.
  3576. }
  3577. this.$s.$mouse_indicator.css('top', position);
  3578. // console.log(["position_mouse_indicator", NEWSBLUR.reader.cache.mouse_position_y, position]);
  3579. this.cache.mouse_position_y = position;
  3580. },
  3581. // ==========================
  3582. // = Login and Signup Forms =
  3583. // ==========================
  3584. handle_login_and_signup_forms: function() {
  3585. var self = this;
  3586. var $hidden_inputs = $('.NB-signup-hidden');
  3587. var $signup_username = $('input[name=signup-username]');
  3588. $signup_username.bind('focus', function() {
  3589. $hidden_inputs.slideDown(300);
  3590. }).bind('blur', function() {
  3591. if ($signup_username.val().length < 1) {
  3592. $hidden_inputs.slideUp(300);
  3593. }
  3594. });
  3595. },
  3596. // ==================
  3597. // = Features Board =
  3598. // ==================
  3599. load_feature_page: function(direction) {
  3600. var self = this;
  3601. var $module = $('.NB-module-features');
  3602. var $next = $('.NB-module-features .NB-module-next-page');
  3603. var $previous = $('.NB-module-features .NB-module-previous-page');
  3604. $module.addClass('NB-loading');
  3605. if (direction == -1 && this.counts['feature_page'] <= 0) {
  3606. $module.removeClass('NB-loading');
  3607. this.counts['feature_page'] = 0;
  3608. return;
  3609. }
  3610. if (direction == 1 && this.flags['features_last_page']) {
  3611. $module.removeClass('NB-loading');
  3612. return;
  3613. }
  3614. this.model.get_features_page(this.counts['feature_page']+direction, function(features) {
  3615. $module.removeClass('NB-loading');
  3616. self.counts['feature_page'] += direction;
  3617. var $table = $.make('table', { className: 'NB-features', cellSpacing: 0, cellPadding: 0 });
  3618. for (var f in features) {
  3619. if (f == 3) break;
  3620. var feature = features[f];
  3621. var $tr = $.make('tr', { className: 'NB-module-feature' }, [
  3622. $.make('td', { className: 'NB-module-feature-date' }, feature.date),
  3623. $.make('td', { className: 'NB-module-feature-description' }, feature.description)
  3624. ]);
  3625. $table.append($tr);
  3626. }
  3627. $('.NB-module-features .NB-features').replaceWith($table);
  3628. var features_count = features.length;
  3629. if (features_count < 4) {
  3630. $next.addClass('NB-disabled');
  3631. self.flags['features_last_page'] = true;
  3632. } else {
  3633. $next.removeClass('NB-disabled');
  3634. self.flags['features_last_page'] = false;
  3635. }
  3636. if (self.counts['feature_page'] > 0) {
  3637. $previous.removeClass('NB-disabled');
  3638. } else {
  3639. $previous.addClass('NB-disabled');
  3640. }
  3641. });
  3642. },
  3643. setup_howitworks_hovers: function() {
  3644. var $page_indicators = $('.NB-module-howitworks .NB-module-page-indicator');
  3645. $page_indicators.bind('mouseenter', _.bind(function(e) {
  3646. var page = $(e.target).prevAll('.NB-module-page-indicator').length;
  3647. this.load_howitworks_page(page);
  3648. }, this));
  3649. },
  3650. load_howitworks_page: function(page) {
  3651. var self = this;
  3652. var $next = $('.NB-module-howitworks .NB-module-next-page');
  3653. var $previous = $('.NB-module-howitworks .NB-module-previous-page');
  3654. var $pages = $('.NB-howitworks-page');
  3655. var $page_indicators = $('.NB-module-howitworks .NB-module-page-indicator');
  3656. var pages_count = $pages.length;
  3657. if (page == -1) {
  3658. return;
  3659. }
  3660. if (page >= pages_count) {
  3661. return;
  3662. }
  3663. $pages.removeClass("NB-active");
  3664. $page_indicators.removeClass("NB-active");
  3665. $pages.eq(page).addClass("NB-active");
  3666. $page_indicators.eq(page).addClass("NB-active");
  3667. if (page >= pages_count - 1) {
  3668. $next.addClass('NB-disabled');
  3669. } else {
  3670. $next.removeClass('NB-disabled');
  3671. }
  3672. if (page <= 0) {
  3673. $previous.addClass('NB-disabled');
  3674. } else {
  3675. $previous.removeClass('NB-disabled');
  3676. }
  3677. },
  3678. // ===============================
  3679. // = Interactions and Activities =
  3680. // ===============================
  3681. load_interactions_page: function(direction) {
  3682. var self = this;
  3683. var $module = $('.NB-module-interactions');
  3684. $module.addClass('NB-loading');
  3685. direction = direction || 0;
  3686. this.model.load_interactions_page(this.counts['interactions_page']+direction,
  3687. function(resp) {
  3688. $module.removeClass('NB-loading');
  3689. if (!resp) return;
  3690. $module.replaceWith(resp);
  3691. $module = $('.NB-module-interactions');
  3692. var page = $module[0].className.match(/NB-page-(\d+)/)[1];
  3693. self.counts['interactions_page'] = parseInt(page, 10);
  3694. self.load_javascript_elements_on_page();
  3695. }, function() {
  3696. $module.removeClass('NB-loading');
  3697. });
  3698. },
  3699. load_activities_page: function(direction) {
  3700. var self = this;
  3701. var $module = $('.NB-module-activities');
  3702. $module.addClass('NB-loading');
  3703. direction = direction || 0;
  3704. this.model.load_activities_page(this.counts['activities_page']+direction,
  3705. function(resp) {
  3706. $module.removeClass('NB-loading');
  3707. if (!resp) return;
  3708. $module.replaceWith(resp);
  3709. $module = $('.NB-module-activities');
  3710. var page = $module[0].className.match(/NB-page-(\d+)/)[1];
  3711. self.counts['activities_page'] = parseInt(page, 10);
  3712. self.load_javascript_elements_on_page();
  3713. }, function() {
  3714. $module.removeClass('NB-loading');
  3715. });
  3716. },
  3717. setup_interactions_module: function() {
  3718. clearInterval(this.locks.load_interactions_module);
  3719. if (!NEWSBLUR.Globals.debug) {
  3720. this.locks.load_interactions_module = setInterval(_.bind(function() {
  3721. this.load_interactions_page();
  3722. }, this), 5*60*1000);
  3723. }
  3724. },
  3725. setup_activities_module: function() {
  3726. clearInterval(this.locks.load_activities_module);
  3727. if (!NEWSBLUR.Globals.debug) {
  3728. this.locks.load_activities_module = setInterval(_.bind(function() {
  3729. this.load_activities_page();
  3730. }, this), 5*60*1000);
  3731. }
  3732. },
  3733. // ========
  3734. // = FTUX =
  3735. // ========
  3736. setup_ftux_add_feed_callout: function(message) {
  3737. var self = this;
  3738. if (this.flags['bouncing_callout']) return;
  3739. $('.NB-callout-ftux .NB-callout-text').text(message || 'First things first...');
  3740. $('.NB-callout-ftux').corner('5px');
  3741. $('.NB-callout-ftux').css({
  3742. 'opacity': 0,
  3743. 'display': 'block'
  3744. }).animate({
  3745. 'opacity': 1,
  3746. 'bottom': 6
  3747. }, {
  3748. 'duration': 750,
  3749. 'easing': 'easeInOutQuint'
  3750. }).each(function() {
  3751. var $this = $(this);
  3752. self.flags['bouncing_callout'] = setInterval(function() {
  3753. $this.animate({'bottom': '+=2px'}, {'duration': 200, 'easing': 'easeInOutQuint'})
  3754. .animate({'bottom': '+=0px'}, {'duration': 50})
  3755. .animate({'bottom': '-=2px'}, {'duration': 200, 'easing': 'easeInOutQuint'});
  3756. }, 1000);
  3757. });
  3758. },
  3759. setup_ftux_signup_callout: function() {
  3760. var self = this;
  3761. if (!this.flags['bouncing_callout']) {
  3762. $('.NB-callout-ftux-signup .NB-callout-text').text('Signup');
  3763. $('.NB-callout-ftux-signup').corner('5px');
  3764. $('.NB-callout-ftux-signup').css({
  3765. 'opacity': 0,
  3766. 'display': 'block'
  3767. }).animate({
  3768. 'opacity': 1,
  3769. 'bottom': 36
  3770. }, {
  3771. 'duration': 750,
  3772. 'easing': 'easeInOutQuint'
  3773. }).each(function() {
  3774. var $this = $(this);
  3775. self.flags['bouncing_callout'] = setInterval(function() {
  3776. $this.animate({'bottom': '+=2px'}, {'duration': 200, 'easing': 'easeInOutQuint'})
  3777. .animate({'bottom': '+=0px'}, {'duration': 50})
  3778. .animate({'bottom': '-=2px'}, {'duration': 200, 'easing': 'easeInOutQuint'});
  3779. }, 10000);
  3780. });
  3781. }
  3782. },
  3783. // =============================
  3784. // = Import from Google Reader =
  3785. // =============================
  3786. post_google_reader_connect: function(data) {
  3787. if (NEWSBLUR.intro) {
  3788. NEWSBLUR.intro.start_import_from_google_reader(data);
  3789. } else {
  3790. this.start_import_from_google_reader();
  3791. }
  3792. },
  3793. start_import_from_google_reader: function() {
  3794. var self = this;
  3795. var $progress = this.$s.$feeds_progress;
  3796. var $bar = $('.NB-progress-bar', $progress);
  3797. var percentage = 0;
  3798. this.flags['import_from_google_reader_working'] = true;
  3799. $('.NB-progress-title', $progress).text('Importing from Google Reader');
  3800. $('.NB-progress-counts', $progress).hide();
  3801. $('.NB-progress-percentage', $progress).hide();
  3802. $bar.progressbar({
  3803. value: percentage
  3804. });
  3805. this.animate_progress_bar($bar, 5);
  3806. this.model.start_import_from_google_reader($.rescope(this.finish_import_from_google_reader, this));
  3807. this.show_progress_bar();
  3808. },
  3809. finish_import_from_google_reader: function(e, data) {
  3810. var $progress = this.$s.$feeds_progress;
  3811. var $bar = $('.NB-progress-bar', $progress);
  3812. this.flags['import_from_google_reader_working'] = false;
  3813. clearTimeout(this.locks['animate_progress_bar']);
  3814. if (data.code >= 1) {
  3815. $bar.progressbar({value: 100});
  3816. NEWSBLUR.assets.load_feeds();
  3817. $('.NB-progress-title', $progress).text('');
  3818. $('.NB-progress-link', $progress).html('');
  3819. } else {
  3820. NEWSBLUR.log(['Import Error!', data]);
  3821. this.$s.$feed_link_loader.fadeOut(250);
  3822. $progress.addClass('NB-progress-error');
  3823. $('.NB-progress-title', $progress).text('Error importing Google Reader');
  3824. $('.NB-progress-link', $progress).html($.make('a', {
  3825. className: 'NB-modal-submit-button NB-modal-submit-green',
  3826. href: NEWSBLUR.URLs['google-reader-authorize']
  3827. }, ['Try importing again']));
  3828. $('.left-center-footer').css('height', 'auto');
  3829. }
  3830. },
  3831. start_count_unreads_after_import: function() {
  3832. var self = this;
  3833. var $progress = this.$s.$feeds_progress;
  3834. var $bar = $('.NB-progress-bar', $progress);
  3835. var percentage = 0;
  3836. var feeds_count = _.keys(this.model.feeds).length;
  3837. if (!this.flags['pause_feed_refreshing'] || this.flags['has_unfetched_feeds']) return;
  3838. this.flags['count_unreads_after_import_working'] = true;
  3839. $('.NB-progress-title', $progress).text('Counting is difficult');
  3840. $('.NB-progress-counts', $progress).hide();
  3841. $('.NB-progress-percentage', $progress).hide();
  3842. $bar.progressbar({
  3843. value: percentage
  3844. });
  3845. setTimeout(function() {
  3846. if (self.flags['count_unreads_after_import_working']) {
  3847. self.animate_progress_bar($bar, feeds_count / 30);
  3848. self.show_progress_bar();
  3849. }
  3850. }, 500);
  3851. },
  3852. finish_count_unreads_after_import: function(e, data) {
  3853. $('.NB-progress-bar', this.$s.$feeds_progress).progressbar({
  3854. value: 100
  3855. });
  3856. this.flags['count_unreads_after_import_working'] = false;
  3857. clearTimeout(this.locks['animate_progress_bar']);
  3858. this.$s.$feed_link_loader.fadeOut(250);
  3859. this.setup_feed_refresh();
  3860. if (!this.flags['has_unfetched_feeds']) {
  3861. this.hide_progress_bar();
  3862. }
  3863. },
  3864. // =====================
  3865. // = Recommended Feeds =
  3866. // =====================
  3867. load_recommended_feeds: function() {
  3868. // Reload recommended feeds every 60 minutes.
  3869. clearInterval(this.locks.load_recommended_feed);
  3870. this.locks.load_recommended_feed = setInterval(_.bind(function() {
  3871. this.load_recommended_feed(0, true);
  3872. }, this), 60*60*1000);
  3873. },
  3874. load_feed_in_tryfeed_view: function(feed_id, options) {
  3875. options = options || {};
  3876. feed = _.extend({
  3877. id : feed_id,
  3878. feed_id : feed_id,
  3879. feed_title : options.feed && options.feed.feed_title,
  3880. temp : true
  3881. }, options.feed && options.feed.attributes);
  3882. var $tryfeed_container = this.$s.$tryfeed_header.closest('.NB-feeds-header-container');
  3883. this.reset_feed(options);
  3884. feed = this.model.set_feed(feed_id, feed);
  3885. $('.NB-feeds-header-title', this.$s.$tryfeed_header).text(feed.get('feed_title'));
  3886. $('.NB-feeds-header-icon', this.$s.$tryfeed_header).attr('src', $.favicon(feed));
  3887. $tryfeed_container.slideDown(350, _.bind(function() {
  3888. options.force = true;
  3889. options.try_feed = true;
  3890. this.open_feed(feed_id, options);
  3891. this.flags['showing_feed_in_tryfeed_view'] = true;
  3892. this.$s.$tryfeed_header.addClass('NB-selected');
  3893. }, this));
  3894. },
  3895. load_social_feed_in_tryfeed_view: function(social_feed, options) {
  3896. options = options || {};
  3897. if (_.isNumber(social_feed)) {
  3898. social_feed = this.model.get_feed('social:' + social_feed);
  3899. } else if (_.isString(social_feed)) {
  3900. social_feed = this.model.get_feed(social_feed);
  3901. }
  3902. if (!social_feed) {
  3903. social_feed = this.model.add_social_feed(options.feed);
  3904. }
  3905. var $tryfeed_container = this.$s.$tryfeed_header.closest('.NB-feeds-header-container');
  3906. this.reset_feed();
  3907. $('.NB-feeds-header-title', this.$s.$tryfeed_header).text(social_feed.get('username'));
  3908. $('.NB-feeds-header-icon', this.$s.$tryfeed_header).attr('src', $.favicon(social_feed));
  3909. $tryfeed_container.slideDown(350, _.bind(function() {
  3910. this.open_social_stories(social_feed.get('id'), options);
  3911. this.switch_taskbar_view('feed');
  3912. this.flags['showing_social_feed_in_tryfeed_view'] = true;
  3913. this.$s.$tryfeed_header.addClass('NB-selected');
  3914. }, this));
  3915. },
  3916. hide_tryfeed_view: function() {
  3917. var $tryfeed_container = this.$s.$tryfeed_header.closest('.NB-feeds-header-container');
  3918. $tryfeed_container.slideUp(350);
  3919. this.$s.$story_taskbar.find('.NB-tryfeed-add').remove();
  3920. this.$s.$story_taskbar.find('.NB-tryfeed-follow').remove();
  3921. this.flags['showing_feed_in_tryfeed_view'] = false;
  3922. this.flags['showing_social_feed_in_tryfeed_view'] = false;
  3923. },
  3924. show_tryfeed_add_button: function() {
  3925. if (this.$s.$story_taskbar.find('.NB-tryfeed-add:visible').length) return;
  3926. var $add = $.make('div', { className: 'NB-modal-submit' }, [
  3927. $.make('div', { className: 'NB-tryfeed-add NB-modal-submit-green NB-modal-submit-button' }, 'Add')
  3928. ]).css({'opacity': 0});
  3929. this.$s.$story_taskbar.find('.NB-taskbar').append($add);
  3930. $add.animate({'opacity': 1}, {'duration': 600});
  3931. },
  3932. correct_tryfeed_title: function() {
  3933. var feed = this.model.get_feed(this.active_feed);
  3934. $('.NB-feeds-header-title', this.$s.$tryfeed_header).text(feed.get('feed_title'));
  3935. this.make_feed_title_in_stories();
  3936. },
  3937. show_tryfeed_follow_button: function() {
  3938. if (this.$s.$story_taskbar.find('.NB-tryfeed-follow:visible').length) return;
  3939. var $add = $.make('div', { className: 'NB-modal-submit' }, [
  3940. $.make('div', { className: 'NB-tryfeed-follow NB-modal-submit-green NB-modal-submit-button' }, 'Follow')
  3941. ]).css({'opacity': 0});
  3942. this.$s.$story_taskbar.find('.NB-taskbar').append($add);
  3943. $add.animate({'opacity': 1}, {'duration': 600});
  3944. },
  3945. show_tryout_signup_button: function() {
  3946. if (this.$s.$story_taskbar.find('.NB-tryout-signup:visible').length) return;
  3947. var $add = $.make('div', { className: 'NB-modal-submit' }, [
  3948. $.make('div', { className: 'NB-tryout-signup NB-modal-submit-green NB-modal-submit-button' }, 'Sign Up')
  3949. ]).css({'opacity': 0});
  3950. this.$s.$story_taskbar.find('.NB-taskbar').append($add);
  3951. $add.animate({'opacity': 1}, {'duration': 600});
  3952. },
  3953. hide_tryout_signup_button: function() {
  3954. this.$s.$story_taskbar.find('.NB-tryout-signup:visible').remove();
  3955. },
  3956. add_recommended_feed: function(feed_id) {
  3957. feed_id = feed_id || this.active_feed;
  3958. var feed_address = this.model.get_feed(feed_id).get('feed_address');
  3959. this.open_add_feed_modal({url: feed_address});
  3960. },
  3961. follow_user_in_tryfeed: function(feed_id) {
  3962. var self = this;
  3963. var socialsub = this.model.get_feed(feed_id);
  3964. this.model.follow_user(socialsub.get('user_id'), function(data) {
  3965. NEWSBLUR.app.feed_list.make_social_feeds();
  3966. self.open_social_stories(feed_id);
  3967. });
  3968. },
  3969. approve_feed_in_moderation_queue: function(feed_id) {
  3970. var self = this;
  3971. var $module = $('.NB-module-recommended.NB-recommended-unmoderated');
  3972. $module.addClass('NB-loading');
  3973. var date = $('.NB-recommended-moderation-date').val();
  3974. this.model.approve_feed_in_moderation_queue(feed_id, date, function(resp) {
  3975. if (!resp) return;
  3976. $module.removeClass('NB-loading');
  3977. $module.replaceWith(resp);
  3978. self.load_javascript_elements_on_page();
  3979. });
  3980. },
  3981. decline_feed_in_moderation_queue: function(feed_id) {
  3982. var self = this;
  3983. var $module = $('.NB-module-recommended.NB-recommended-unmoderated');
  3984. $module.addClass('NB-loading');
  3985. this.model.decline_feed_in_moderation_queue(feed_id, function(resp) {
  3986. if (!resp) return;
  3987. $module.removeClass('NB-loading');
  3988. $module.replaceWith(resp);
  3989. self.load_javascript_elements_on_page();
  3990. });
  3991. },
  3992. load_recommended_feed: function(direction, refresh, unmoderated) {
  3993. var self = this;
  3994. var $module = unmoderated ?
  3995. $('.NB-module-recommended.NB-recommended-unmoderated') :
  3996. $('.NB-module-recommended:not(.NB-recommended-unmoderated)');
  3997. $module.addClass('NB-loading');
  3998. direction = direction || 0;
  3999. this.model.load_recommended_feed(this.counts['recommended_feed_page']+direction,
  4000. !!refresh, unmoderated, function(resp) {
  4001. $module.removeClass('NB-loading');
  4002. if (!resp) return;
  4003. $module.replaceWith(resp);
  4004. self.counts['recommended_feed_page'] += direction;
  4005. self.load_javascript_elements_on_page();
  4006. }, function() {
  4007. $module.removeClass('NB-loading');
  4008. });
  4009. },
  4010. // ====================
  4011. // = Dashboard Graphs =
  4012. // ====================
  4013. setup_dashboard_graphs: function() {
  4014. if (NEWSBLUR.Globals.debug) return;
  4015. // Reload dashboard graphs every 10 minutes.
  4016. clearInterval(this.locks.load_dashboard_graphs);
  4017. if (!NEWSBLUR.Globals.debug) {
  4018. this.locks.load_dashboard_graphs = setInterval(_.bind(function() {
  4019. this.load_dashboard_graphs();
  4020. }, this), NEWSBLUR.Globals.is_staff ? 60*1000 : 10*60*1000);
  4021. }
  4022. },
  4023. load_dashboard_graphs: function() {
  4024. var self = this;
  4025. var $module = $('.NB-module-site-stats');
  4026. $module.addClass('NB-loading');
  4027. this.model.load_dashboard_graphs(function(resp) {
  4028. $module.removeClass('NB-loading');
  4029. if (!resp) return;
  4030. $module.replaceWith(resp);
  4031. self.load_javascript_elements_on_page();
  4032. }, function() {
  4033. $module.removeClass('NB-loading');
  4034. });
  4035. },
  4036. setup_feedback_table: function() {
  4037. if (NEWSBLUR.Globals.debug) return;
  4038. // Reload feedback module every 10 minutes.
  4039. clearInterval(this.locks.load_feedback_table);
  4040. if (!NEWSBLUR.Globals.debug) {
  4041. this.locks.load_feedback_table = setInterval(_.bind(function() {
  4042. this.load_feedback_table();
  4043. }, this), NEWSBLUR.Globals.is_staff ? 60*1000 : 10*60*1000);
  4044. }
  4045. },
  4046. load_feedback_table: function() {
  4047. var self = this;
  4048. var $module = $('.NB-feedback-table');
  4049. $module.addClass('NB-loading');
  4050. this.model.load_feedback_table(function(resp) {
  4051. if (!resp) return;
  4052. $module.removeClass('NB-loading');
  4053. $module.replaceWith(resp);
  4054. self.load_javascript_elements_on_page();
  4055. }, $.noop);
  4056. },
  4057. // ===================
  4058. // = Unfetched Feeds =
  4059. // ===================
  4060. setup_unfetched_feed_check: function() {
  4061. this.locks.unfetched_feed_check = setInterval(_.bind(function() {
  4062. var unfetched_feeds = NEWSBLUR.assets.unfetched_feeds();
  4063. if (unfetched_feeds.length) {
  4064. this.force_instafetch_stories(unfetched_feeds[0].id);
  4065. }
  4066. }, this), 60*1*1000);
  4067. },
  4068. // ==========
  4069. // = Events =
  4070. // ==========
  4071. handle_clicks: function(elem, e) {
  4072. var self = this;
  4073. var stopPropagation = false;
  4074. // NEWSBLUR.log(['click', e, e.button]);
  4075. // = Taskbar ======================================================
  4076. $.targetIs(e, { tagSelector: '.NB-task-add' }, function($t, $p){
  4077. e.preventDefault();
  4078. self.open_add_feed_modal();
  4079. });
  4080. $.targetIs(e, { tagSelector: '.NB-task-manage' }, function($t, $p){
  4081. e.preventDefault();
  4082. if (!$t.hasClass('NB-disabled')) {
  4083. self.show_manage_menu('site', $t);
  4084. }
  4085. });
  4086. $.targetIs(e, { tagSelector: '.NB-taskbar-sidebar-toggle-close' }, function($t, $p){
  4087. e.preventDefault();
  4088. self.close_sidebar();
  4089. });
  4090. $.targetIs(e, { tagSelector: '.NB-taskbar-sidebar-toggle-open' }, function($t, $p){
  4091. e.preventDefault();
  4092. self.open_sidebar();
  4093. });
  4094. // = Context Menu ================================================
  4095. $.targetIs(e, { tagSelector: '.NB-menu-manage-open-input' }, function($t, $p){
  4096. e.preventDefault();
  4097. e.stopPropagation();
  4098. self.flags['showing_confirm_input_on_manage_menu'] = true;
  4099. $t.select().blur(function() {
  4100. self.flags['showing_confirm_input_on_manage_menu'] = false;
  4101. });
  4102. });
  4103. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-train' }, function($t, $p){
  4104. e.preventDefault();
  4105. if (!$t.hasClass('NB-disabled')) {
  4106. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4107. self.open_feed_intelligence_modal(1, feed_id, false);
  4108. }
  4109. });
  4110. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-recommend' }, function($t, $p){
  4111. e.preventDefault();
  4112. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4113. self.open_recommend_modal(feed_id);
  4114. });
  4115. $.targetIs(e, { tagSelector: '.NB-menu-manage-story-train' }, function($t, $p){
  4116. e.preventDefault();
  4117. if (!$t.hasClass('NB-disabled')) {
  4118. var feed_id = $t.closest('.NB-menu-manage').data('feed_id');
  4119. var story_id = $t.closest('.NB-menu-manage').data('story_id');
  4120. self.open_story_trainer(story_id, feed_id);
  4121. }
  4122. });
  4123. $.targetIs(e, { tagSelector: '.NB-menu-manage-trainer' }, function($t, $p){
  4124. e.preventDefault();
  4125. if (!$t.hasClass('NB-disabled')) {
  4126. self.open_trainer_modal();
  4127. }
  4128. });
  4129. $.targetIs(e, { tagSelector: '.NB-menu-manage-tutorial' }, function($t, $p){
  4130. e.preventDefault();
  4131. if (!$t.hasClass('NB-disabled')) {
  4132. self.open_tutorial_modal();
  4133. }
  4134. });
  4135. $.targetIs(e, { tagSelector: '.NB-menu-manage-intro' }, function($t, $p){
  4136. e.preventDefault();
  4137. if (!$t.hasClass('NB-disabled')) {
  4138. self.open_intro_modal();
  4139. }
  4140. });
  4141. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-stats' }, function($t, $p){
  4142. e.preventDefault();
  4143. if (!$t.hasClass('NB-disabled')) {
  4144. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4145. NEWSBLUR.log(['statistics feed_id', feed_id]);
  4146. self.open_feed_statistics_modal(feed_id);
  4147. }
  4148. });
  4149. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-settings' }, function($t, $p){
  4150. e.preventDefault();
  4151. if (!$t.hasClass('NB-disabled')) {
  4152. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4153. self.open_feed_exception_modal(feed_id);
  4154. }
  4155. });
  4156. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-reload' }, function($t, $p){
  4157. e.preventDefault();
  4158. if (!$t.hasClass('NB-disabled')) {
  4159. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4160. self.force_instafetch_stories(feed_id);
  4161. }
  4162. });
  4163. $.targetIs(e, { tagSelector: '.NB-menu-manage-delete' }, function($t, $p){
  4164. e.preventDefault();
  4165. e.stopPropagation();
  4166. if ($t.hasClass('NB-menu-manage-feed-delete-cancel') ||
  4167. $t.hasClass('NB-menu-manage-folder-delete-cancel')) {
  4168. self.hide_confirm_delete_menu_item();
  4169. } else if ($t.hasClass('NB-menu-manage-feed-delete') ||
  4170. $t.hasClass('NB-menu-manage-folder-delete')) {
  4171. self.show_confirm_delete_menu_item();
  4172. } else if ($t.hasClass('NB-menu-manage-socialfeed-delete-cancel')) {
  4173. self.hide_confirm_unfollow_menu_item();
  4174. } else if ($t.hasClass('NB-menu-manage-socialfeed-delete')) {
  4175. self.show_confirm_unfollow_menu_item();
  4176. }
  4177. });
  4178. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-delete-confirm' }, function($t, $p){
  4179. e.preventDefault();
  4180. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4181. var $feed = $t.parents('.NB-menu-manage').data('$feed');
  4182. self.manage_menu_delete_feed(feed_id, $feed);
  4183. });
  4184. $.targetIs(e, { tagSelector: '.NB-menu-manage-socialfeed-delete-confirm' }, function($t, $p){
  4185. e.preventDefault();
  4186. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4187. var $feed = $t.parents('.NB-menu-manage').data('$feed');
  4188. self.manage_menu_unfollow_feed(feed_id, $feed);
  4189. });
  4190. $.targetIs(e, { tagSelector: '.NB-menu-manage-folder-delete-confirm' }, function($t, $p){
  4191. e.preventDefault();
  4192. var folder_name = $t.parents('.NB-menu-manage').data('folder_name');
  4193. var $folder = $t.parents('.NB-menu-manage').data('$folder');
  4194. self.manage_menu_delete_folder(folder_name, $folder);
  4195. });
  4196. $.targetIs(e, { tagSelector: '.NB-menu-manage-move' }, function($t, $p){
  4197. e.preventDefault();
  4198. e.stopPropagation();
  4199. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4200. var $feed = $t.parents('.NB-menu-manage').data('$feed');
  4201. var folder_name = $t.parents('.NB-menu-manage').data('folder_name');
  4202. var $folder = $t.parents('.NB-menu-manage').data('$folder');
  4203. if ($t.hasClass('NB-menu-manage-feed-move-cancel') ||
  4204. $t.hasClass('NB-menu-manage-folder-move-cancel')) {
  4205. self.hide_confirm_move_menu_item();
  4206. } else {
  4207. self.show_confirm_move_menu_item(feed_id || folder_name, $feed || $folder);
  4208. }
  4209. });
  4210. $.targetIs(e, { tagSelector: '.NB-menu-manage-folder-move-save' }, function($t, $p){
  4211. e.preventDefault();
  4212. e.stopPropagation();
  4213. var folder_name = $t.parents('.NB-menu-manage').data('folder_name');
  4214. var $folder = $t.parents('.NB-menu-manage').data('$folder');
  4215. self.manage_menu_move_folder(folder_name, $folder);
  4216. });
  4217. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-move-save' }, function($t, $p){
  4218. e.preventDefault();
  4219. e.stopPropagation();
  4220. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4221. var $feed = $t.parents('.NB-menu-manage').data('$feed');
  4222. self.manage_menu_move_feed(feed_id, $feed);
  4223. });
  4224. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-move-confirm' }, function($t, $p){
  4225. e.preventDefault();
  4226. e.stopPropagation();
  4227. });
  4228. $.targetIs(e, { tagSelector: '.NB-menu-manage-folder-move-confirm' }, function($t, $p){
  4229. e.preventDefault();
  4230. e.stopPropagation();
  4231. });
  4232. $.targetIs(e, { tagSelector: '.NB-menu-manage-controls' }, function($t, $p){
  4233. e.preventDefault();
  4234. e.stopPropagation();
  4235. });
  4236. $.targetIs(e, { tagSelector: '.NB-menu-manage-rename' }, function($t, $p){
  4237. e.preventDefault();
  4238. e.stopPropagation();
  4239. if ($t.hasClass('NB-menu-manage-feed-rename-cancel') ||
  4240. $t.hasClass('NB-menu-manage-folder-rename-cancel')) {
  4241. self.hide_confirm_rename_menu_item();
  4242. } else {
  4243. self.show_confirm_rename_menu_item();
  4244. }
  4245. });
  4246. $.targetIs(e, { tagSelector: '.NB-menu-manage-folder-rename-save' }, function($t, $p){
  4247. e.preventDefault();
  4248. e.stopPropagation();
  4249. var folder_name = $t.parents('.NB-menu-manage').data('folder_name');
  4250. var $folder = $t.parents('.NB-menu-manage').data('$folder');
  4251. self.manage_menu_rename_folder(folder_name, $folder);
  4252. });
  4253. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-rename-save' }, function($t, $p){
  4254. e.preventDefault();
  4255. e.stopPropagation();
  4256. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4257. var $feed = $t.parents('.NB-menu-manage').data('$feed');
  4258. self.manage_menu_rename_feed(feed_id, $feed);
  4259. });
  4260. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-rename-confirm' }, function($t, $p){
  4261. e.preventDefault();
  4262. e.stopPropagation();
  4263. });
  4264. $.targetIs(e, { tagSelector: '.NB-menu-manage-folder-rename-confirm' }, function($t, $p){
  4265. e.preventDefault();
  4266. e.stopPropagation();
  4267. });
  4268. $.targetIs(e, { tagSelector: '.NB-menu-manage-story-share' }, function($t, $p){
  4269. e.preventDefault();
  4270. e.stopPropagation();
  4271. if ($t.hasClass('NB-menu-manage-story-share-cancel')) {
  4272. self.hide_confirm_story_share_menu_item();
  4273. } else {
  4274. self.show_confirm_story_share_menu_item();
  4275. }
  4276. });
  4277. $.targetIs(e, { tagSelector: '.NB-menu-manage-story-share-confirm' }, function($t, $p){
  4278. e.preventDefault();
  4279. e.stopPropagation();
  4280. });
  4281. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-mark-read' }, function($t, $p){
  4282. e.preventDefault();
  4283. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4284. self.mark_feed_as_read(feed_id);
  4285. });
  4286. $.targetIs(e, { tagSelector: '.NB-menu-manage-folder-mark-read' }, function($t, $p){
  4287. e.preventDefault();
  4288. var $folder = $t.parents('.NB-menu-manage').data('$folder');
  4289. var folder_view = NEWSBLUR.assets.folders.get_view($folder) ||
  4290. self.active_folder.folder_view;
  4291. self.mark_folder_as_read(folder_view.model);
  4292. });
  4293. $.targetIs(e, { tagSelector: '.NB-menu-manage-folder-subscribe' }, function($t, $p){
  4294. e.preventDefault();
  4295. var folder_name = $t.parents('.NB-menu-manage').data('folder_name');
  4296. var $folder = $t.parents('.NB-menu-manage').data('$folder');
  4297. self.open_add_feed_modal({folder_title: folder_name});
  4298. });
  4299. $.targetIs(e, { tagSelector: '.NB-menu-manage-folder-subfolder' }, function($t, $p){
  4300. e.preventDefault();
  4301. var folder_name = $t.parents('.NB-menu-manage').data('folder_name');
  4302. var $folder = $t.parents('.NB-menu-manage').data('$folder');
  4303. self.open_add_feed_modal({folder_title: folder_name, init_folder: true});
  4304. });
  4305. $.targetIs(e, { tagSelector: '.NB-menu-manage-story-open' }, function($t, $p){
  4306. e.preventDefault();
  4307. if (!self.flags['showing_confirm_input_on_manage_menu']) {
  4308. var story_id = $t.closest('.NB-menu-manage-story').data('story_id');
  4309. var story = self.model.get_story(story_id);
  4310. story.story_view.open_story_in_new_tab();
  4311. }
  4312. });
  4313. $.targetIs(e, { tagSelector: '.NB-menu-manage-story-star' }, function($t, $p){
  4314. e.preventDefault();
  4315. var story_id = $t.closest('.NB-menu-manage-story').data('story_id');
  4316. var story_view = NEWSBLUR.assets.get_story(story_id).story_view;
  4317. story_view.star_story();
  4318. });
  4319. $.targetIs(e, { tagSelector: '.NB-menu-manage-site-mark-read' }, function($t, $p){
  4320. e.preventDefault();
  4321. if (!$t.hasClass('NB-disabled')) {
  4322. self.open_mark_read_modal();
  4323. }
  4324. });
  4325. $.targetIs(e, { tagSelector: '.NB-menu-manage-social-profile' }, function($t, $p){
  4326. e.preventDefault();
  4327. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4328. self.open_social_profile_modal(feed_id);
  4329. });
  4330. $.targetIs(e, { tagSelector: '.NB-menu-manage-controls-feed .NB-menu-manage-view-setting-order li' }, function($t, $p){
  4331. e.preventDefault();
  4332. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4333. var $feed = $t.parents('.NB-menu-manage').data('$feed');
  4334. if ($t.hasClass('NB-view-setting-order-oldest')) {
  4335. self.change_view_setting(feed_id, {order: 'oldest'}, $feed);
  4336. } else {
  4337. self.change_view_setting(feed_id, {order: 'newest'}, $feed);
  4338. }
  4339. });
  4340. $.targetIs(e, { tagSelector: '.NB-menu-manage-controls-folder .NB-menu-manage-view-setting-order li' }, function($t, $p){
  4341. e.preventDefault();
  4342. var folder_name = $t.parents('.NB-menu-manage').data('folder_name');
  4343. var $folder = $t.parents('.NB-menu-manage').data('$folder');
  4344. if ($t.hasClass('NB-view-setting-order-oldest')) {
  4345. self.change_view_setting('river:'+folder_name, {order: 'oldest'}, $folder);
  4346. } else {
  4347. self.change_view_setting('river:'+folder_name, {order: 'newest'}, $folder);
  4348. }
  4349. });
  4350. $.targetIs(e, { tagSelector: '.NB-menu-manage-controls-feed .NB-menu-manage-view-setting-readfilter li' }, function($t, $p){
  4351. e.preventDefault();
  4352. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4353. var $feed = $t.parents('.NB-menu-manage').data('$feed');
  4354. if ($t.hasClass('NB-view-setting-readfilter-unread')) {
  4355. self.change_view_setting(feed_id, {read_filter: 'unread'}, $feed);
  4356. } else {
  4357. self.change_view_setting(feed_id, {read_filter: 'all'}, $feed);
  4358. }
  4359. });
  4360. $.targetIs(e, { tagSelector: '.NB-menu-manage-controls-folder .NB-menu-manage-view-setting-readfilter li' }, function($t, $p){
  4361. e.preventDefault();
  4362. var folder_name = $t.parents('.NB-menu-manage').data('folder_name');
  4363. var $folder = $t.parents('.NB-menu-manage').data('$folder');
  4364. if ($t.hasClass('NB-view-setting-readfilter-unread')) {
  4365. self.change_view_setting('river:'+folder_name, {read_filter: 'unread'}, $folder);
  4366. } else {
  4367. self.change_view_setting('river:'+folder_name, {read_filter: 'all'}, $folder);
  4368. }
  4369. });
  4370. $.targetIs(e, { tagSelector: '.NB-menu-manage-keyboard' }, function($t, $p){
  4371. e.preventDefault();
  4372. if (!$t.hasClass('NB-disabled')) {
  4373. self.open_keyboard_shortcuts_modal();
  4374. }
  4375. });
  4376. $.targetIs(e, { tagSelector: '.NB-menu-manage-feed-exception' }, function($t, $p){
  4377. e.preventDefault();
  4378. var feed_id = $t.parents('.NB-menu-manage').data('feed_id');
  4379. self.open_feed_exception_modal(feed_id);
  4380. });
  4381. $.targetIs(e, { tagSelector: '.NB-menu-manage-goodies' }, function($t, $p){
  4382. e.preventDefault();
  4383. if (!$t.hasClass('NB-disabled')) {
  4384. self.open_goodies_modal();
  4385. }
  4386. });
  4387. $.targetIs(e, { tagSelector: '.NB-menu-manage-friends' }, function($t, $p){
  4388. e.preventDefault();
  4389. if (!$t.hasClass('NB-disabled')) {
  4390. self.open_friends_modal();
  4391. }
  4392. });
  4393. $.targetIs(e, { tagSelector: '.NB-menu-manage-profile-editor' }, function($t, $p){
  4394. e.preventDefault();
  4395. if (!$t.hasClass('NB-disabled')) {
  4396. self.open_profile_editor_modal();
  4397. }
  4398. });
  4399. $.targetIs(e, { tagSelector: '.NB-menu-manage-preferences' }, function($t, $p){
  4400. e.preventDefault();
  4401. if (!$t.hasClass('NB-disabled')) {
  4402. self.open_preferences_modal();
  4403. }
  4404. });
  4405. $.targetIs(e, { tagSelector: '.NB-menu-manage-account' }, function($t, $p){
  4406. e.preventDefault();
  4407. if (!$t.hasClass('NB-disabled')) {
  4408. self.open_account_modal();
  4409. }
  4410. });
  4411. $.targetIs(e, { tagSelector: '.NB-menu-manage-feedchooser' }, function($t, $p){
  4412. e.preventDefault();
  4413. if (!$t.hasClass('NB-disabled')) {
  4414. self.open_feedchooser_modal();
  4415. }
  4416. });
  4417. $.targetIs(e, { tagSelector: '.NB-module-account-upgrade' }, function($t, $p){
  4418. e.preventDefault();
  4419. if (!$t.hasClass('NB-disabled')) {
  4420. self.open_feedchooser_modal();
  4421. }
  4422. });
  4423. $.targetIs(e, { tagSelector: '.NB-module-account-train' }, function($t, $p){
  4424. e.preventDefault();
  4425. if (!$t.hasClass('NB-disabled')) {
  4426. self.open_trainer_modal();
  4427. }
  4428. });
  4429. $.targetIs(e, { tagSelector: '.NB-module-friends-button' }, function($t, $p){
  4430. e.preventDefault();
  4431. if (!$t.hasClass('NB-disabled')) {
  4432. self.open_friends_modal();
  4433. }
  4434. });
  4435. $.targetIs(e, { tagSelector: '.NB-module-launch-tutorial' }, function($t, $p){
  4436. e.preventDefault();
  4437. if (!$t.hasClass('NB-disabled')) {
  4438. self.open_tutorial_modal();
  4439. }
  4440. });
  4441. $.targetIs(e, { tagSelector: '.NB-module-launch-intro' }, function($t, $p){
  4442. e.preventDefault();
  4443. if (!$t.hasClass('NB-disabled')) {
  4444. self.open_intro_modal();
  4445. }
  4446. });
  4447. $.targetIs(e, { tagSelector: '.NB-module-gettingstarted-hide' }, function($t, $p){
  4448. e.preventDefault();
  4449. if (!$t.hasClass('NB-disabled')) {
  4450. self.check_hide_getting_started(true);
  4451. }
  4452. });
  4453. $.targetIs(e, { tagSelector: '.NB-menu-manage-story-unread' }, function($t, $p){
  4454. e.preventDefault();
  4455. var story_id = $t.closest('.NB-menu-manage').data('story_id');
  4456. var story = self.model.get_story(story_id);
  4457. NEWSBLUR.assets.stories.mark_unread(story);
  4458. });
  4459. $.targetIs(e, { tagSelector: '.task_view_page:not(.NB-task-return)' }, function($t, $p){
  4460. e.preventDefault();
  4461. self.switch_taskbar_view('page');
  4462. });
  4463. $.targetIs(e, { tagSelector: '.task_view_feed' }, function($t, $p){
  4464. e.preventDefault();
  4465. self.switch_taskbar_view('feed');
  4466. });
  4467. $.targetIs(e, { tagSelector: '.task_view_story' }, function($t, $p){
  4468. e.preventDefault();
  4469. self.switch_taskbar_view('story');
  4470. });
  4471. $.targetIs(e, { tagSelector: '.NB-task-return' }, function($t, $p){
  4472. e.preventDefault();
  4473. NEWSBLUR.app.original_tab_view.load_feed_iframe();
  4474. });
  4475. $.targetIs(e, { tagSelector: '.NB-task-feed-settings' }, function($t, $p){
  4476. e.preventDefault();
  4477. self.open_feed_exception_modal();
  4478. });
  4479. $.targetIs(e, { tagSelector: '.task_button_story.task_story_next_unread' }, function($t, $p){
  4480. e.preventDefault();
  4481. self.open_next_unread_story_across_feeds();
  4482. });
  4483. $.targetIs(e, { tagSelector: '.task_button_story.task_story_next' }, function($t, $p){
  4484. e.preventDefault();
  4485. self.show_next_story(1);
  4486. });
  4487. $.targetIs(e, { tagSelector: '.task_button_story.task_story_previous' }, function($t, $p){
  4488. e.preventDefault();
  4489. self.show_previous_story();
  4490. });
  4491. $.targetIs(e, { tagSelector: '.NB-intelligence-slider-control' }, function($t, $p){
  4492. e.preventDefault();
  4493. var unread_value;
  4494. if ($t.hasClass('NB-intelligence-slider-red')) {
  4495. unread_value = -1;
  4496. } else if ($t.hasClass('NB-intelligence-slider-yellow')) {
  4497. unread_value = 0;
  4498. } else if ($t.hasClass('NB-intelligence-slider-green')) {
  4499. unread_value = 1;
  4500. }
  4501. self.slide_intelligence_slider(unread_value);
  4502. });
  4503. // =====================
  4504. // = Recommended Feeds =
  4505. // =====================
  4506. $.targetIs(e, { tagSelector: '.NB-recommended-statistics' }, function($t, $p){
  4507. e.preventDefault();
  4508. var feed_id = $t.closest('.NB-recommended').data('feed-id');
  4509. $('.NB-module-recommended').addClass('NB-loading');
  4510. self.model.load_canonical_feed(feed_id, function() {
  4511. $('.NB-module-recommended').removeClass('NB-loading');
  4512. self.open_feed_statistics_modal(feed_id);
  4513. });
  4514. });
  4515. $.targetIs(e, { tagSelector: '.NB-recommended-intelligence' }, function($t, $p){
  4516. e.preventDefault();
  4517. var feed_id = $t.closest('.NB-recommended').data('feed-id');
  4518. $('.NB-module-recommended').addClass('NB-loading');
  4519. self.model.load_canonical_feed(feed_id, function() {
  4520. $('.NB-module-recommended').removeClass('NB-loading');
  4521. self.open_feed_intelligence_modal(1, feed_id);
  4522. });
  4523. });
  4524. $.targetIs(e, { tagSelector: '.NB-recommended-try' }, function($t, $p){
  4525. e.preventDefault();
  4526. var $recommended_feeds = $('.NB-module-recommended');
  4527. var feed_id = $t.closest('.NB-recommended').data('feed-id');
  4528. self.open_feed(feed_id, {'feed': new NEWSBLUR.Models.Feed({
  4529. 'feed_title': $('.NB-recommended-title', $recommended_feeds).text(),
  4530. 'favicon_url': $('.NB-recommended-favicon', $recommended_feeds).attr('src'),
  4531. 'temp': true
  4532. })});
  4533. });
  4534. $.targetIs(e, { tagSelector: '.NB-recommended-add' }, function($t, $p){
  4535. e.preventDefault();
  4536. var feed_id = $t.closest('.NB-recommended').data('feed-id');
  4537. $('.NB-module-recommended').addClass('NB-loading');
  4538. self.model.load_canonical_feed(feed_id, function() {
  4539. $('.NB-module-recommended').removeClass('NB-loading');
  4540. self.add_recommended_feed(feed_id);
  4541. });
  4542. });
  4543. $.targetIs(e, { tagSelector: '.NB-recommended-decline' }, function($t, $p){
  4544. e.preventDefault();
  4545. var feed_id = $t.closest('.NB-recommended').data('feed-id');
  4546. self.decline_feed_in_moderation_queue(feed_id);
  4547. });
  4548. $.targetIs(e, { tagSelector: '.NB-recommended-approve' }, function($t, $p){
  4549. e.preventDefault();
  4550. var feed_id = $t.closest('.NB-recommended').data('feed-id');
  4551. self.approve_feed_in_moderation_queue(feed_id);
  4552. });
  4553. $.targetIs(e, { tagSelector: '.NB-module-recommended .NB-module-next-page' }, function($t, $p){
  4554. e.preventDefault();
  4555. if (!$t.hasClass('NB-disabled')) {
  4556. var unmoderated = $t.closest('.NB-module-recommended').hasClass('NB-recommended-unmoderated');
  4557. self.load_recommended_feed(1, false, unmoderated);
  4558. }
  4559. });
  4560. $.targetIs(e, { tagSelector: '.NB-module-recommended .NB-module-previous-page' }, function($t, $p){
  4561. e.preventDefault();
  4562. if (!$t.hasClass('NB-disabled')) {
  4563. var unmoderated = $t.closest('.NB-module-recommended').hasClass('NB-recommended-unmoderated');
  4564. self.load_recommended_feed(-1, false, unmoderated);
  4565. }
  4566. });
  4567. $.targetIs(e, { tagSelector: '.NB-tryfeed-add' }, function($t, $p){
  4568. e.preventDefault();
  4569. var feed_id = self.active_feed;
  4570. self.add_recommended_feed(feed_id);
  4571. });
  4572. $.targetIs(e, { tagSelector: '.NB-tryfeed-follow' }, function($t, $p){
  4573. e.preventDefault();
  4574. var feed_id = self.active_feed;
  4575. self.follow_user_in_tryfeed(feed_id);
  4576. });
  4577. $.targetIs(e, { tagSelector: '.NB-tryout-signup' }, function($t, $p){
  4578. e.preventDefault();
  4579. self.show_splash_page();
  4580. if (NEWSBLUR.welcome) {
  4581. NEWSBLUR.welcome.show_signin_form();
  4582. }
  4583. });
  4584. // = Interactions Module ==========================================
  4585. $.targetIs(e, { tagSelector: '.NB-interaction-follow, .NB-activity-follow' }, function($t, $p){
  4586. e.preventDefault();
  4587. var user_id = $t.data('userId');
  4588. var username = $t.closest('.NB-interaction').find('.NB-interaction-username').text();
  4589. self.model.add_user_profiles([{user_id: user_id, username: username}]);
  4590. self.open_social_profile_modal(user_id);
  4591. });
  4592. $.targetIs(e, { tagSelector: '.NB-interaction-comment_reply, .NB-interaction-reply_reply, .NB-interaction-story_reshare, .NB-interaction-comment_like, .NB-activity-comment_reply, .NB-activity-comment_like, .NB-activity-sharedstory' }, function($t, $p){
  4593. e.preventDefault();
  4594. var $interaction = $t.closest('.NB-interaction');
  4595. var feed_id = $interaction.data('feedId');
  4596. var story_id = $interaction.data('contentId');
  4597. var user_id = $interaction.data('userId');
  4598. var username = $interaction.data('username');
  4599. self.close_social_profile();
  4600. if (self.model.get_feed(feed_id)) {
  4601. self.open_social_stories(feed_id, {'story_id': story_id});
  4602. } else {
  4603. var socialsub = self.model.add_social_feed({
  4604. id: feed_id,
  4605. user_id: user_id,
  4606. username: username
  4607. });
  4608. self.load_social_feed_in_tryfeed_view(socialsub, {'story_id': story_id});
  4609. }
  4610. });
  4611. // = Activities Module ==========================================
  4612. $.targetIs(e, { tagSelector: '.NB-activity-star' }, function($t, $p){
  4613. e.preventDefault();
  4614. var story_id = $t.closest('.NB-interaction').data('contentId');
  4615. self.close_social_profile();
  4616. self.open_starred_stories({'story_id': story_id});
  4617. });
  4618. $.targetIs(e, { tagSelector: '.NB-activity-feedsub' }, function($t, $p){
  4619. e.preventDefault();
  4620. var feed_id = $t.closest('.NB-interaction').data('feedId');
  4621. self.close_social_profile();
  4622. self.open_feed(feed_id);
  4623. });
  4624. // = One-offs =====================================================
  4625. var clicked = false;
  4626. $.targetIs(e, { tagSelector: '#mouse-indicator' }, function($t, $p){
  4627. e.preventDefault();
  4628. self.lock_mouse_indicator();
  4629. });
  4630. $.targetIs(e, { tagSelector: '.NB-load-user-profile img' }, function($t, $p){
  4631. e.preventDefault();
  4632. self.open_social_profile_modal();
  4633. });
  4634. $.targetIs(e, { tagSelector: '.NB-progress-close' }, function($t, $p){
  4635. e.preventDefault();
  4636. self.hide_unfetched_feed_progress(true);
  4637. });
  4638. $.targetIs(e, { tagSelector: '.NB-module-next-page', childOf: '.NB-module-features' }, function($t, $p){
  4639. e.preventDefault();
  4640. self.load_feature_page(1);
  4641. });
  4642. $.targetIs(e, { tagSelector: '.NB-module-previous-page', childOf: '.NB-module-features' }, function($t, $p){
  4643. e.preventDefault();
  4644. self.load_feature_page(-1);
  4645. });
  4646. $.targetIs(e, { tagSelector: '.NB-module-next-page', childOf: '.NB-module-howitworks' }, function($t, $p){
  4647. e.preventDefault();
  4648. var page = $('.NB-howitworks-page.NB-active').prevAll('.NB-howitworks-page').length;
  4649. self.load_howitworks_page(page+1);
  4650. });
  4651. $.targetIs(e, { tagSelector: '.NB-module-previous-page', childOf: '.NB-module-howitworks' }, function($t, $p){
  4652. e.preventDefault();
  4653. var page = $('.NB-howitworks-page.NB-active').prevAll('.NB-howitworks-page').length;
  4654. self.load_howitworks_page(page-1);
  4655. });
  4656. $.targetIs(e, { tagSelector: '.NB-module-page-indicator', childOf: '.NB-module-howitworks' }, function($t, $p){
  4657. e.preventDefault();
  4658. var page = $t.prevAll('.NB-module-page-indicator').length;
  4659. self.load_howitworks_page(page);
  4660. });
  4661. $.targetIs(e, { tagSelector: '.NB-module-next-page', childOf: '.NB-module-interactions' }, function($t, $p){
  4662. e.preventDefault();
  4663. if (!$t.hasClass('NB-disabled')) {
  4664. self.load_interactions_page(1);
  4665. }
  4666. });
  4667. $.targetIs(e, { tagSelector: '.NB-module-previous-page', childOf: '.NB-module-interactions' }, function($t, $p){
  4668. e.preventDefault();
  4669. if (!$t.hasClass('NB-disabled')) {
  4670. self.load_interactions_page(-1);
  4671. }
  4672. });
  4673. $.targetIs(e, { tagSelector: '.NB-module-next-page', childOf: '.NB-module-activities' }, function($t, $p){
  4674. e.preventDefault();
  4675. if (!$t.hasClass('NB-disabled')) {
  4676. self.load_activities_page(1);
  4677. }
  4678. });
  4679. $.targetIs(e, { tagSelector: '.NB-module-previous-page', childOf: '.NB-module-activities' }, function($t, $p){
  4680. e.preventDefault();
  4681. if (!$t.hasClass('NB-disabled')) {
  4682. self.load_activities_page(-1);
  4683. }
  4684. });
  4685. $.targetIs(e, { tagSelector: '.NB-splash-meta-about' }, function($t, $p){
  4686. e.preventDefault();
  4687. NEWSBLUR.about = new NEWSBLUR.About();
  4688. });
  4689. $.targetIs(e, { tagSelector: '.NB-splash-meta-faq' }, function($t, $p){
  4690. e.preventDefault();
  4691. NEWSBLUR.faq = new NEWSBLUR.Faq();
  4692. });
  4693. },
  4694. handle_keyup: function(elem, e) {
  4695. var self = this;
  4696. },
  4697. handle_keystrokes: function() {
  4698. var self = this;
  4699. var $document = $(document);
  4700. NEWSBLUR.hotkeys.initialize();
  4701. $document.bind('keydown', '?', function(e) {
  4702. e.preventDefault();
  4703. self.open_keyboard_shortcuts_modal();
  4704. });
  4705. $document.bind('keydown', 'shift+/', function(e) {
  4706. e.preventDefault();
  4707. self.open_keyboard_shortcuts_modal();
  4708. });
  4709. $document.bind('keydown', '/', function(e) {
  4710. e.preventDefault();
  4711. self.open_keyboard_shortcuts_modal();
  4712. });
  4713. $document.bind('keydown', 'down', function(e) {
  4714. e.preventDefault();
  4715. self.show_next_story(1);
  4716. });
  4717. $document.bind('keydown', 'up', function(e) {
  4718. e.preventDefault();
  4719. self.show_next_story(-1);
  4720. });
  4721. $document.bind('keydown', 'j', function(e) {
  4722. e.preventDefault();
  4723. self.show_next_story(1);
  4724. });
  4725. $document.bind('keydown', 'k', function(e) {
  4726. e.preventDefault();
  4727. self.show_next_story(-1);
  4728. });
  4729. $document.bind('keydown', 'shift+j', function(e) {
  4730. e.preventDefault();
  4731. self.show_next_feed(1);
  4732. });
  4733. $document.bind('keydown', 'shift+k', function(e) {
  4734. e.preventDefault();
  4735. self.show_next_feed(-1);
  4736. });
  4737. $document.bind('keydown', 'shift+down', function(e) {
  4738. e.preventDefault();
  4739. self.show_next_feed(1);
  4740. });
  4741. $document.bind('keydown', 'shift+up', function(e) {
  4742. e.preventDefault();
  4743. self.show_next_feed(-1);
  4744. });
  4745. $document.bind('keydown', 'left', function(e) {
  4746. e.preventDefault();
  4747. self.switch_taskbar_view_direction(-1);
  4748. });
  4749. $document.bind('keydown', 'right', function(e) {
  4750. e.preventDefault();
  4751. self.switch_taskbar_view_direction(1);
  4752. });
  4753. $document.bind('keydown', 'h', function(e) {
  4754. e.preventDefault();
  4755. self.switch_taskbar_view_direction(-1);
  4756. });
  4757. $document.bind('keydown', 'l', function(e) {
  4758. e.preventDefault();
  4759. self.switch_taskbar_view_direction(1);
  4760. });
  4761. $document.bind('keydown', 'r', function(e) {
  4762. e.preventDefault();
  4763. self.reload_feed();
  4764. });
  4765. $document.bind('keydown', 'enter', function(e) {
  4766. e.preventDefault();
  4767. NEWSBLUR.app.story_tab_view.open_story(null, true);
  4768. });
  4769. $document.bind('keydown', 'return', function(e) {
  4770. e.preventDefault();
  4771. NEWSBLUR.app.story_tab_view.open_story(null, true);
  4772. });
  4773. $document.bind('keydown', 'space', function(e) {
  4774. e.preventDefault();
  4775. self.page_in_story(0.4, 1);
  4776. });
  4777. $document.bind('keydown', 'shift+space', function(e) {
  4778. e.preventDefault();
  4779. self.page_in_story(0.65, -1);
  4780. });
  4781. $document.bind('keydown', 'shift+u', function(e) {
  4782. e.preventDefault();
  4783. self.toggle_sidebar();
  4784. });
  4785. $document.bind('keydown', 'shift+t', function(e) {
  4786. e.preventDefault();
  4787. self.toggle_story_titles_pane(true);
  4788. });
  4789. $document.bind('keydown', 'n', function(e) {
  4790. e.preventDefault();
  4791. self.open_next_unread_story_across_feeds();
  4792. });
  4793. $document.bind('keydown', 'p', function(e) {
  4794. e.preventDefault();
  4795. self.show_previous_story();
  4796. });
  4797. $document.bind('keydown', 'c', function(e) {
  4798. e.preventDefault();
  4799. NEWSBLUR.app.story_list.scroll_to_selected_story(self.active_story, {
  4800. scroll_to_comments: true,
  4801. scroll_offset: -50
  4802. });
  4803. });
  4804. $document.bind('keydown', 'm', function(e) {
  4805. e.preventDefault();
  4806. self.show_last_unread_story();
  4807. });
  4808. $document.bind('keydown', 'b', function(e) {
  4809. e.preventDefault();
  4810. self.show_previous_story();
  4811. });
  4812. $document.bind('keydown', 's', function(e) {
  4813. e.preventDefault();
  4814. if (self.active_story) {
  4815. var story_id = self.active_story.id;
  4816. var story_view = NEWSBLUR.assets.get_story(story_id).story_view;
  4817. story_view.star_story();
  4818. }
  4819. });
  4820. $document.bind('keypress', '+', function(e) {
  4821. e.preventDefault();
  4822. self.move_intelligence_slider(1);
  4823. });
  4824. $document.bind('keypress', '-', function(e) {
  4825. e.preventDefault();
  4826. self.move_intelligence_slider(-1);
  4827. });
  4828. $document.bind('keypress', 'd', function(e) {
  4829. e.preventDefault();
  4830. self.show_splash_page();
  4831. });
  4832. $document.bind('keydown', 'esc', function(e) {
  4833. e.preventDefault();
  4834. if (!_.keys($.modal.impl.d).length) {
  4835. self.show_splash_page();
  4836. }
  4837. });
  4838. $document.bind('keypress', 't', function(e) {
  4839. e.preventDefault();
  4840. self.open_story_trainer();
  4841. });
  4842. $document.bind('keypress', 'a', function(e) {
  4843. e.preventDefault();
  4844. self.open_add_feed_modal();
  4845. });
  4846. $document.bind('keypress', 'f', function(e) {
  4847. e.preventDefault();
  4848. self.open_feed_intelligence_modal(1);
  4849. });
  4850. $document.bind('keypress', 'o', function(e) {
  4851. e.preventDefault();
  4852. var story_id = self.active_story;
  4853. if (!story_id) return;
  4854. var story = self.model.get_story(story_id);
  4855. story.story_view.open_story_in_new_tab();
  4856. });
  4857. $document.bind('keypress', 'e', function(e) {
  4858. e.preventDefault();
  4859. var story = self.active_story;
  4860. if (!story) return;
  4861. self.send_story_to_email(story);
  4862. });
  4863. $document.bind('keydown', 'shift+a', function(e) {
  4864. e.preventDefault();
  4865. if (self.flags.social_view && self.flags.river_view) {
  4866. return;
  4867. } else if (self.flags.social_view && !self.flags.river_view) {
  4868. self.mark_feed_as_read();
  4869. } else if (self.flags.river_view) {
  4870. if (self.active_feed == 'river:') {
  4871. self.open_mark_read_modal({days: 0});
  4872. } else {
  4873. self.mark_folder_as_read();
  4874. }
  4875. } else if (!self.flags.river_view && !self.flags.social_view) {
  4876. self.mark_feed_as_read();
  4877. }
  4878. });
  4879. $document.bind('keydown', 'shift+e', function(e) {
  4880. e.preventDefault();
  4881. self.open_river_stories();
  4882. });
  4883. $document.bind('keydown', 'u', function(e) {
  4884. e.preventDefault();
  4885. self.mark_active_story_read();
  4886. });
  4887. $document.bind('keydown', 'm', function(e) {
  4888. e.preventDefault();
  4889. self.mark_active_story_read();
  4890. });
  4891. $document.bind('keydown', 'g', function(e) {
  4892. e.preventDefault();
  4893. NEWSBLUR.app.feed_selector.toggle();
  4894. });
  4895. $document.bind('keydown', 'shift+s', function(e) {
  4896. e.preventDefault();
  4897. if (self.active_story) {
  4898. var $story_title = self.active_story.story_title_view.$el;
  4899. self.active_story.story_title_view.mouseenter_manage_icon();
  4900. self.show_manage_menu('story', $story_title, {story_id: self.active_story.id});
  4901. self.show_confirm_story_share_menu_item(self.active_story.id);
  4902. }
  4903. });
  4904. }
  4905. });
  4906. })(jQuery);