Add Unread Count.

Remove the "read thread" keybind.
Fix #714.
This commit is contained in:
Nicolas Stepien 2013-02-16 18:15:27 +01:00
parent 03fdfa8c68
commit 1771713d6f
5 changed files with 130 additions and 3 deletions

View File

@ -43,7 +43,7 @@
*/ */
(function() { (function() {
var $, $$, Anonymize, ArchiveLink, AutoGIF, Board, Build, Clone, Conf, Config, DeleteLink, DownloadLink, FileInfo, Filter, Get, Header, ImageExpand, ImageHover, Main, Menu, Notification, Polyfill, Post, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, Quotify, Recursive, Redirect, RelativeDates, ReplyHiding, ReportLink, RevealSpoilers, Sauce, Settings, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, Time, UI, d, doc, g, var $, $$, Anonymize, ArchiveLink, AutoGIF, Board, Build, Clone, Conf, Config, DeleteLink, DownloadLink, FileInfo, Filter, Get, Header, ImageExpand, ImageHover, Main, Menu, Notification, Polyfill, Post, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, Quotify, Recursive, Redirect, RelativeDates, ReplyHiding, ReportLink, RevealSpoilers, Sauce, Settings, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, Time, UI, Unread, d, doc, g,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
__hasProp = {}.hasOwnProperty, __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
@ -151,7 +151,6 @@
'submit QR': ['alt+s', 'Submit post.'], 'submit QR': ['alt+s', 'Submit post.'],
'watch': ['w', 'Watch thread.'], 'watch': ['w', 'Watch thread.'],
'update': ['u', 'Update the thread now.'], 'update': ['u', 'Update the thread now.'],
'read thread': ['r', 'Mark thread as read.'],
'expand image': ['E', 'Expand selected image.'], 'expand image': ['E', 'Expand selected image.'],
'expand images': ['e', 'Expand all images.'], 'expand images': ['e', 'Expand all images.'],
'front page': ['0', 'Jump to page 0.'], 'front page': ['0', 'Jump to page 0.'],
@ -3907,6 +3906,80 @@
} }
}; };
Unread = {
init: function() {
if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Favicon']) {
return;
}
$.on(d, 'ThreadUpdate', this.onUpdate);
$.on(d, 'QRPostSuccessful', this.post);
$.on(d, 'scroll visibilitychange', this.read);
return Thread.prototype.callbacks.push({
name: 'Unread',
cb: this.node
});
},
node: function() {
var ID, post, posts, _ref;
Unread.yourPosts = [];
Unread.posts = [];
Unread.title = d.title;
posts = [];
_ref = this.posts;
for (ID in _ref) {
post = _ref[ID];
if (post.isReply) {
posts.push(post);
}
}
Unread.addPosts(posts);
return Unread.update();
},
addPosts: function(newPosts) {
var height, index, post, _i, _len;
if (!d.hidden) {
height = doc.clientHeight;
}
for (_i = 0, _len = newPosts.length; _i < _len; _i++) {
post = newPosts[_i];
if ((index = Unread.yourPosts.indexOf(post.ID)) !== -1) {
Unread.yourPosts.splice(index, 1);
} else if (!post.isHidden && (d.hidden || post.nodes.root.getBoundingClientRect().bottom > height)) {
Unread.posts.push(post);
}
}
},
onUpdate: function(e) {
if (!e.detail[404]) {
Unread.addPosts(e.detail.newPosts);
}
return Unread.update();
},
post: function(e) {
return Unread.yourPosts.push(+e.detail.postID);
},
read: function() {
var bottom, height, i, post, _i, _len, _ref;
height = doc.clientHeight;
_ref = Unread.posts;
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
post = _ref[i];
bottom = post.nodes.root.getBoundingClientRect().bottom;
if (bottom > height) {
break;
}
}
if (!i) {
return;
}
Unread.posts = Unread.posts.slice(i);
return Unread.update();
},
update: function() {
return d.title = "(" + Unread.posts.length + ") " + Unread.title;
}
};
ThreadStats = { ThreadStats = {
init: function() { init: function() {
if (g.VIEW !== 'thread' || !Conf['Thread Stats']) { if (g.VIEW !== 'thread' || !Conf['Thread Stats']) {
@ -5618,6 +5691,7 @@
initFeature('Auto-GIF', AutoGIF); initFeature('Auto-GIF', AutoGIF);
initFeature('Image Hover', ImageHover); initFeature('Image Hover', ImageHover);
initFeature('Thread Excerpt', ThreadExcerpt); initFeature('Thread Excerpt', ThreadExcerpt);
initFeature('Unread', Unread);
initFeature('Thread Stats', ThreadStats); initFeature('Thread Stats', ThreadStats);
initFeature('Thread Updater', ThreadUpdater); initFeature('Thread Updater', ThreadUpdater);
console.timeEnd('All initializations'); console.timeEnd('All initializations');

View File

@ -21,6 +21,7 @@ alpha
Added Thread & Post Hiding in the Menu, with individual settings. Added Thread & Post Hiding in the Menu, with individual settings.
Thread & Post Hiding Buttons can now be disabled in the settings. Thread & Post Hiding Buttons can now be disabled in the settings.
Recursive Hiding will be automatically applied when manually hiding a post. Recursive Hiding will be automatically applied when manually hiding a post.
Visible posts will not be taken into account towards the unread count.
Fix Chrome's install warning saying that 4chan X would execute on all domains. Fix Chrome's install warning saying that 4chan X would execute on all domains.
Fix Quote Backlinks not affecting inlined quotes. Fix Quote Backlinks not affecting inlined quotes.
Fix Quote Highlighting not affecting inlined quotes. Fix Quote Highlighting not affecting inlined quotes.

View File

@ -141,7 +141,6 @@ Config =
# Thread related # Thread related
'watch': ['w', 'Watch thread.'] 'watch': ['w', 'Watch thread.']
'update': ['u', 'Update the thread now.'] 'update': ['u', 'Update the thread now.']
'read thread': ['r', 'Mark thread as read.']
# Images # Images
'expand image': ['E', 'Expand selected image.'] 'expand image': ['E', 'Expand selected image.']
'expand images': ['e', 'Expand all images.'] 'expand images': ['e', 'Expand all images.']

View File

@ -2430,6 +2430,58 @@ ThreadExcerpt =
node: -> node: ->
d.title = Get.threadExcerpt @ d.title = Get.threadExcerpt @
Unread =
init: ->
return if g.VIEW isnt 'thread' or !Conf['Unread Count'] and !Conf['Unread Favicon']
$.on d, 'ThreadUpdate', @onUpdate
$.on d, 'QRPostSuccessful', @post
$.on d, 'scroll visibilitychange', @read
Thread::callbacks.push
name: 'Unread'
cb: @node
node: ->
Unread.yourPosts = []
Unread.posts = []
Unread.title = d.title
posts = []
for ID, post of @posts
posts.push post if post.isReply
Unread.addPosts posts
Unread.update()
addPosts: (newPosts) ->
unless d.hidden
height = doc.clientHeight
for post in newPosts
if (index = Unread.yourPosts.indexOf post.ID) isnt -1
Unread.yourPosts.splice index, 1
else if !post.isHidden and (d.hidden or post.nodes.root.getBoundingClientRect().bottom > height)
Unread.posts.push post
return
onUpdate: (e) ->
unless e.detail[404]
Unread.addPosts e.detail.newPosts
Unread.update()
post: (e) ->
Unread.yourPosts.push +e.detail.postID
read: ->
height = doc.clientHeight
for post, i in Unread.posts
{bottom} = post.nodes.root.getBoundingClientRect()
break if bottom > height # post is not completely read
return unless i
Unread.posts = Unread.posts[i..]
Unread.update()
update: ->
d.title = "(#{Unread.posts.length}) #{Unread.title}"
ThreadStats = ThreadStats =
init: -> init: ->
return if g.VIEW isnt 'thread' or !Conf['Thread Stats'] return if g.VIEW isnt 'thread' or !Conf['Thread Stats']

View File

@ -334,6 +334,7 @@ Main =
initFeature 'Auto-GIF', AutoGIF initFeature 'Auto-GIF', AutoGIF
initFeature 'Image Hover', ImageHover initFeature 'Image Hover', ImageHover
initFeature 'Thread Excerpt', ThreadExcerpt initFeature 'Thread Excerpt', ThreadExcerpt
initFeature 'Unread', Unread
initFeature 'Thread Stats', ThreadStats initFeature 'Thread Stats', ThreadStats
initFeature 'Thread Updater', ThreadUpdater initFeature 'Thread Updater', ThreadUpdater
console.timeEnd 'All initializations' console.timeEnd 'All initializations'