I was wrong. Still broken, but getting there

This commit is contained in:
Zixaphir 2014-01-05 13:12:06 -07:00
parent c1427e4494
commit 3f60a05edc
6 changed files with 277 additions and 133 deletions

View File

@ -1480,9 +1480,27 @@
} }
this.rmi(item); this.rmi(item);
next = root.next; next = root.next;
next.prev = root.next = item; next.prev = item;
item.prev = root; item.next = next;
return item.next = next; root.next = item;
return item.prev = root;
};
RandomAccessList.prototype.prepend = function(item) {
var ID, first;
ID = item.ID;
if (!this[ID]) {
this.push(item);
}
first = this.first;
if (this !== first) {
item.next = first;
}
if (first) {
first.prev = item;
}
this.first = item;
return delete item.prev;
}; };
RandomAccessList.prototype.shift = function() { RandomAccessList.prototype.shift = function() {
@ -1533,6 +1551,19 @@
} }
}; };
RandomAccessList.prototype.closest = function(ID) {
var item, prev;
item = this.first;
while (item) {
if (item.ID > ID) {
prev = item.prev.prev;
break;
}
item = item.next;
}
return (prev ? prev.ID : -1);
};
return RandomAccessList; return RandomAccessList;
})(); })();
@ -4928,7 +4959,9 @@
el: this.controls, el: this.controls,
order: 98 order: 98
}); });
$.on(d, '4chanXInitFinished', this.setup); if (!Conf['Unread Count']) {
$.on(d, '4chanXInitFinished', QuoteThreading.setup);
}
return Post.callbacks.push({ return Post.callbacks.push({
name: 'Quote Threading', name: 'Quote Threading',
cb: this.node cb: this.node
@ -4977,17 +5010,18 @@
return this.cb = QuoteThreading.nodeinsert; return this.cb = QuoteThreading.nodeinsert;
}, },
nodeinsert: function() { nodeinsert: function() {
var bottom, height, post, root, threadContainer, top, _ref; var ID, bottom, height, post, posts, root, threadContainer, top, _ref;
post = g.posts[this.threaded]; post = g.posts[this.threaded];
delete this.threaded; posts = Unread.posts;
delete this.cb; this.threaded;
this.cb;
if (this.thread.OP === post) { if (this.thread.OP === post) {
return false; return false;
} }
if (QuoteThreading.hasRun) { if (QuoteThreading.hasRun) {
height = doc.clientHeight; height = doc.clientHeight;
_ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top;
if (!(Unread.posts[post.ID] || ((bottom < height) && (top > 0)))) { if (!(posts[post.ID] || ((bottom < height) && (top > 0)))) {
return false; return false;
} }
} }
@ -5002,12 +5036,24 @@
threadContainer = root.nextSibling; threadContainer = root.nextSibling;
} }
$.add(threadContainer, this.nodes.root); $.add(threadContainer, this.nodes.root);
Unread.posts.after(post.ID, this); if (!posts[this.ID]) {
posts.push(this);
}
if (posts[post.ID]) {
posts.after(post, this);
} else {
if ((ID = posts.closest(ID)) !== -1) {
posts.after(posts[ID], this);
} else {
posts.prepend(this);
}
}
return true; return true;
}, },
toggle: function() { toggle: function() {
var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref;
Unread.replies = new RandomAccessList; Unread.posts = new RandomAccessList;
Unread.ready();
thread = $('.thread'); thread = $('.thread');
replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread);
QuoteThreading.enabled = this.checked; QuoteThreading.enabled = this.checked;
@ -5015,9 +5061,14 @@
QuoteThreading.hasRun = false; QuoteThreading.hasRun = false;
for (_i = 0, _len = replies.length; _i < _len; _i++) { for (_i = 0, _len = replies.length; _i < _len; _i++) {
reply = replies[_i]; reply = replies[_i];
QuoteThreading.node.call(node = Get.postFromRoot(reply)); node = Get.postFromRoot(reply);
if (node.cb) { if (node.cb) {
node.cb(); node.cb.call(node);
} else {
QuoteThreading.node.call(node);
if (node.cb) {
node.cb.call(node);
}
} }
} }
QuoteThreading.hasRun = true; QuoteThreading.hasRun = true;
@ -5045,7 +5096,8 @@
kb: function() { kb: function() {
var control; var control;
control = $.id('threadingControl'); control = $.id('threadingControl');
return control.click(); control.checked = !control.checked;
return QuoteThreading.toggle.call(control);
} }
}; };
@ -9477,6 +9529,22 @@
}); });
this.posts = new RandomAccessList; this.posts = new RandomAccessList;
this.postsQuotingYou = []; this.postsQuotingYou = [];
this.qr = QR.db ? function(_arg) {
var ID, board, data, thread;
board = _arg.board, thread = _arg.thread, ID = _arg.ID;
data = {
boardID: board.ID,
threadID: thread.ID,
postID: ID
};
if (QR.db.get(data)) {
return true;
} else {
return false;
}
} : function() {
return false;
};
return Thread.callbacks.push({ return Thread.callbacks.push({
name: 'Unread', name: 'Unread',
cb: this.node cb: this.node
@ -9509,6 +9577,9 @@
} }
} }
Unread.addPosts(posts); Unread.addPosts(posts);
if (Conf['Quote Threading']) {
QuoteThreading.setup();
}
if (Conf['Scroll to Last Read Post']) { if (Conf['Scroll to Last Read Post']) {
return Unread.scroll(); return Unread.scroll();
} }
@ -9562,30 +9633,16 @@
return Unread.update(); return Unread.update();
}, },
addPosts: function(posts) { addPosts: function(posts) {
var ID, db, post, _i, _len, _ref; var ID, post, _i, _len, _ref;
db = QR.db ? function(_arg) {
var ID, board, data, thread;
board = _arg.board, thread = _arg.thread, ID = _arg.ID;
data = {
boardID: board.ID,
threadID: thread.ID,
postID: ID
};
if (QR.db.get(data)) {
return true;
} else {
return false;
}
} : function() {
return false;
};
for (_i = 0, _len = posts.length; _i < _len; _i++) { for (_i = 0, _len = posts.length; _i < _len; _i++) {
post = posts[_i]; post = posts[_i];
ID = post.ID; ID = post.ID;
if (ID <= Unread.lastReadPost || post.isHidden || db(post)) { if (ID <= Unread.lastReadPost || post.isHidden || Unread.qr(post)) {
continue; continue;
} }
Unread.posts.push(post); if (!(post.prev || post.next)) {
Unread.posts.push(post);
}
Unread.addPostQuotingYou(post); Unread.addPostQuotingYou(post);
} }
if (Conf['Unread Line']) { if (Conf['Unread Line']) {
@ -9663,25 +9720,24 @@
} }
return arr.splice(0, i); return arr.splice(0, i);
}, },
read: $.debounce(50, function(e) { read: function(e) {
var ID, height, post, posts; var ID, height, post, posts;
if (d.hidden || !Unread.posts.length) { if (d.hidden || !Unread.posts.length) {
return; return;
} }
height = doc.clientHeight; height = doc.clientHeight;
posts = Unread.posts; posts = Unread.posts;
post = posts.first; while (post = posts.first) {
while (post) { if (!(Header.getBottomOf(post.nodes.root) > -1)) {
if (Header.getBottomOf(post.nodes.root) > -1) { break;
ID = post.ID; }
if (Conf['Mark Quotes of You']) { ID = post.ID;
if (post.info.yours) { if (Conf['Mark Quotes of You'] && post.info.yours) {
QuoteYou.lastRead = post.nodes.root; QuoteYou.lastRead = post.nodes.root;
} }
} posts.rm(ID);
post = post.next; if (post === posts.first) {
posts.rm(ID); c.log(posts);
} else {
break; break;
} }
} }
@ -9696,7 +9752,7 @@
if (e) { if (e) {
return Unread.update(); return Unread.update();
} }
}), },
saveLastReadPost: $.debounce(2 * $.SECOND, function() { saveLastReadPost: $.debounce(2 * $.SECOND, function() {
if (Unread.thread.isDead) { if (Unread.thread.isDead) {
return; return;

View File

@ -1486,9 +1486,27 @@
} }
this.rmi(item); this.rmi(item);
next = root.next; next = root.next;
next.prev = root.next = item; next.prev = item;
item.prev = root; item.next = next;
return item.next = next; root.next = item;
return item.prev = root;
};
RandomAccessList.prototype.prepend = function(item) {
var ID, first;
ID = item.ID;
if (!this[ID]) {
this.push(item);
}
first = this.first;
if (this !== first) {
item.next = first;
}
if (first) {
first.prev = item;
}
this.first = item;
return delete item.prev;
}; };
RandomAccessList.prototype.shift = function() { RandomAccessList.prototype.shift = function() {
@ -1539,6 +1557,19 @@
} }
}; };
RandomAccessList.prototype.closest = function(ID) {
var item, prev;
item = this.first;
while (item) {
if (item.ID > ID) {
prev = item.prev.prev;
break;
}
item = item.next;
}
return (prev ? prev.ID : -1);
};
return RandomAccessList; return RandomAccessList;
})(); })();
@ -4931,7 +4962,9 @@
el: this.controls, el: this.controls,
order: 98 order: 98
}); });
$.on(d, '4chanXInitFinished', this.setup); if (!Conf['Unread Count']) {
$.on(d, '4chanXInitFinished', QuoteThreading.setup);
}
return Post.callbacks.push({ return Post.callbacks.push({
name: 'Quote Threading', name: 'Quote Threading',
cb: this.node cb: this.node
@ -4980,17 +5013,18 @@
return this.cb = QuoteThreading.nodeinsert; return this.cb = QuoteThreading.nodeinsert;
}, },
nodeinsert: function() { nodeinsert: function() {
var bottom, height, post, root, threadContainer, top, _ref; var ID, bottom, height, post, posts, root, threadContainer, top, _ref;
post = g.posts[this.threaded]; post = g.posts[this.threaded];
delete this.threaded; posts = Unread.posts;
delete this.cb; this.threaded;
this.cb;
if (this.thread.OP === post) { if (this.thread.OP === post) {
return false; return false;
} }
if (QuoteThreading.hasRun) { if (QuoteThreading.hasRun) {
height = doc.clientHeight; height = doc.clientHeight;
_ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top;
if (!(Unread.posts[post.ID] || ((bottom < height) && (top > 0)))) { if (!(posts[post.ID] || ((bottom < height) && (top > 0)))) {
return false; return false;
} }
} }
@ -5005,12 +5039,24 @@
threadContainer = root.nextSibling; threadContainer = root.nextSibling;
} }
$.add(threadContainer, this.nodes.root); $.add(threadContainer, this.nodes.root);
Unread.posts.after(post.ID, this); if (!posts[this.ID]) {
posts.push(this);
}
if (posts[post.ID]) {
posts.after(post, this);
} else {
if ((ID = posts.closest(ID)) !== -1) {
posts.after(posts[ID], this);
} else {
posts.prepend(this);
}
}
return true; return true;
}, },
toggle: function() { toggle: function() {
var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref;
Unread.replies = new RandomAccessList; Unread.posts = new RandomAccessList;
Unread.ready();
thread = $('.thread'); thread = $('.thread');
replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread);
QuoteThreading.enabled = this.checked; QuoteThreading.enabled = this.checked;
@ -5018,9 +5064,14 @@
QuoteThreading.hasRun = false; QuoteThreading.hasRun = false;
for (_i = 0, _len = replies.length; _i < _len; _i++) { for (_i = 0, _len = replies.length; _i < _len; _i++) {
reply = replies[_i]; reply = replies[_i];
QuoteThreading.node.call(node = Get.postFromRoot(reply)); node = Get.postFromRoot(reply);
if (node.cb) { if (node.cb) {
node.cb(); node.cb.call(node);
} else {
QuoteThreading.node.call(node);
if (node.cb) {
node.cb.call(node);
}
} }
} }
QuoteThreading.hasRun = true; QuoteThreading.hasRun = true;
@ -5048,7 +5099,8 @@
kb: function() { kb: function() {
var control; var control;
control = $.id('threadingControl'); control = $.id('threadingControl');
return control.click(); control.checked = !control.checked;
return QuoteThreading.toggle.call(control);
} }
}; };
@ -9460,6 +9512,22 @@
}); });
this.posts = new RandomAccessList; this.posts = new RandomAccessList;
this.postsQuotingYou = []; this.postsQuotingYou = [];
this.qr = QR.db ? function(_arg) {
var ID, board, data, thread;
board = _arg.board, thread = _arg.thread, ID = _arg.ID;
data = {
boardID: board.ID,
threadID: thread.ID,
postID: ID
};
if (QR.db.get(data)) {
return true;
} else {
return false;
}
} : function() {
return false;
};
return Thread.callbacks.push({ return Thread.callbacks.push({
name: 'Unread', name: 'Unread',
cb: this.node cb: this.node
@ -9492,6 +9560,9 @@
} }
} }
Unread.addPosts(posts); Unread.addPosts(posts);
if (Conf['Quote Threading']) {
QuoteThreading.setup();
}
if (Conf['Scroll to Last Read Post']) { if (Conf['Scroll to Last Read Post']) {
return Unread.scroll(); return Unread.scroll();
} }
@ -9545,30 +9616,16 @@
return Unread.update(); return Unread.update();
}, },
addPosts: function(posts) { addPosts: function(posts) {
var ID, db, post, _i, _len, _ref; var ID, post, _i, _len, _ref;
db = QR.db ? function(_arg) {
var ID, board, data, thread;
board = _arg.board, thread = _arg.thread, ID = _arg.ID;
data = {
boardID: board.ID,
threadID: thread.ID,
postID: ID
};
if (QR.db.get(data)) {
return true;
} else {
return false;
}
} : function() {
return false;
};
for (_i = 0, _len = posts.length; _i < _len; _i++) { for (_i = 0, _len = posts.length; _i < _len; _i++) {
post = posts[_i]; post = posts[_i];
ID = post.ID; ID = post.ID;
if (ID <= Unread.lastReadPost || post.isHidden || db(post)) { if (ID <= Unread.lastReadPost || post.isHidden || Unread.qr(post)) {
continue; continue;
} }
Unread.posts.push(post); if (!(post.prev || post.next)) {
Unread.posts.push(post);
}
Unread.addPostQuotingYou(post); Unread.addPostQuotingYou(post);
} }
if (Conf['Unread Line']) { if (Conf['Unread Line']) {
@ -9646,25 +9703,24 @@
} }
return arr.splice(0, i); return arr.splice(0, i);
}, },
read: $.debounce(50, function(e) { read: function(e) {
var ID, height, post, posts; var ID, height, post, posts;
if (d.hidden || !Unread.posts.length) { if (d.hidden || !Unread.posts.length) {
return; return;
} }
height = doc.clientHeight; height = doc.clientHeight;
posts = Unread.posts; posts = Unread.posts;
post = posts.first; while (post = posts.first) {
while (post) { if (!(Header.getBottomOf(post.nodes.root) > -1)) {
if (Header.getBottomOf(post.nodes.root) > -1) { break;
ID = post.ID; }
if (Conf['Mark Quotes of You']) { ID = post.ID;
if (post.info.yours) { if (Conf['Mark Quotes of You'] && post.info.yours) {
QuoteYou.lastRead = post.nodes.root; QuoteYou.lastRead = post.nodes.root;
} }
} posts.rm(ID);
post = post.next; if (post === posts.first) {
posts.rm(ID); c.log(posts);
} else {
break; break;
} }
} }
@ -9679,7 +9735,7 @@
if (e) { if (e) {
return Unread.update(); return Unread.update();
} }
}), },
saveLastReadPost: $.debounce(2 * $.SECOND, function() { saveLastReadPost: $.debounce(2 * $.SECOND, function() {
if (Unread.thread.isDead) { if (Unread.thread.isDead) {
return; return;

View File

@ -1,6 +1,5 @@
Main = Main =
init: -> init: ->
# flatten Config into Conf # flatten Config into Conf
# and get saved or default values # and get saved or default values
flatten = (parent, obj) -> flatten = (parent, obj) ->

View File

@ -19,9 +19,19 @@ class RandomAccessList
@rmi item @rmi item
{next} = root {next} = root
next.prev = root.next = item next.prev = item
item.prev = root
item.next = next item.next = next
root.next = item
item.prev = root
prepend: (item) ->
{ID} = item
@push item unless @[ID]
{first} = @
item.next = first unless @ is first
first.prev = item if first
@first = item
delete item.prev
shift: -> shift: ->
@rm @first.ID @rm @first.ID
@ -54,3 +64,12 @@ class RandomAccessList
next.prev = prev next.prev = prev
else else
@last = prev @last = prev
closest: (ID) ->
item = @first
while item
if item.ID > ID
{prev} = item.prev
break
item = item.next
return (if prev then prev.ID else -1)

View File

@ -8,6 +8,16 @@ Unread =
@posts = new RandomAccessList @posts = new RandomAccessList
@postsQuotingYou = [] @postsQuotingYou = []
@qr = if QR.db
({board, thread, ID}) ->
data =
boardID: board.ID
threadID: thread.ID
postID: ID
return if QR.db.get data then true else false
else ->
return false
Thread.callbacks.push Thread.callbacks.push
name: 'Unread' name: 'Unread'
cb: @node cb: @node
@ -30,6 +40,7 @@ Unread =
for ID, post of Unread.thread.posts for ID, post of Unread.thread.posts
posts.push post if post.isReply posts.push post if post.isReply
Unread.addPosts posts Unread.addPosts posts
QuoteThreading.setup() if Conf['Quote Threading']
Unread.scroll() if Conf['Scroll to Last Read Post'] Unread.scroll() if Conf['Scroll to Last Read Post']
scroll: -> scroll: ->
@ -68,20 +79,10 @@ Unread =
Unread.update() Unread.update()
addPosts: (posts) -> addPosts: (posts) ->
db = if QR.db
({board, thread, ID}) ->
data =
boardID: board.ID
threadID: thread.ID
postID: ID
return if QR.db.get data then true else false
else ->
return false
for post in posts for post in posts
{ID} = post {ID} = post
continue if ID <= Unread.lastReadPost or post.isHidden or db post continue if ID <= Unread.lastReadPost or post.isHidden or Unread.qr post
Unread.posts.push post Unread.posts.push post unless post.prev or post.next
Unread.addPostQuotingYou post Unread.addPostQuotingYou post
if Conf['Unread Line'] if Conf['Unread Line']
# Force line on visible threads if there were no unread posts previously. # Force line on visible threads if there were no unread posts previously.
@ -135,22 +136,21 @@ Unread =
break if post.ID > Unread.lastReadPost break if post.ID > Unread.lastReadPost
arr.splice 0, i arr.splice 0, i
read: $.debounce 50, (e) -> read: (e) ->
return if d.hidden or !Unread.posts.length return if d.hidden or !Unread.posts.length
height = doc.clientHeight height = doc.clientHeight
{posts} = Unread {posts} = Unread
while post = posts.first
break unless Header.getBottomOf(post.nodes.root) > -1 # post is not completely read
post = posts.first {ID} = post
if Conf['Mark Quotes of You'] and post.info.yours
QuoteYou.lastRead = post.nodes.root
posts.rm ID
while post if post is posts.first
if Header.getBottomOf(post.nodes.root) > -1 # post is not completely read c.log posts
{ID} = post
if Conf['Mark Quotes of You']
if post.info.yours
QuoteYou.lastRead = post.nodes.root
post = post.next
posts.rm ID
else
break break
return unless ID return unless ID

View File

@ -18,7 +18,7 @@ QuoteThreading =
el: @controls el: @controls
order: 98 order: 98
$.on d, '4chanXInitFinished', @setup $.on d, '4chanXInitFinished', QuoteThreading.setup unless Conf['Unread Count']
Post.callbacks.push Post.callbacks.push
name: 'Quote Threading' name: 'Quote Threading'
@ -28,9 +28,7 @@ QuoteThreading =
$.off d, '4chanXInitFinished', QuoteThreading.setup $.off d, '4chanXInitFinished', QuoteThreading.setup
{posts} = g {posts} = g
for ID, post of posts post.cb.call post for ID, post of posts when post.cb
if post.cb
post.cb.call post
QuoteThreading.hasRun = true QuoteThreading.hasRun = true
@ -58,10 +56,11 @@ QuoteThreading =
@cb = QuoteThreading.nodeinsert @cb = QuoteThreading.nodeinsert
nodeinsert: -> nodeinsert: ->
post = g.posts[@threaded] post = g.posts[@threaded]
{posts} = Unread
delete @threaded @threaded
delete @cb @cb
return false if @thread.OP is post return false if @thread.OP is post
@ -70,7 +69,7 @@ QuoteThreading =
{bottom, top} = post.nodes.root.getBoundingClientRect() {bottom, top} = post.nodes.root.getBoundingClientRect()
# Post is unread or is fully visible. # Post is unread or is fully visible.
return false unless Unread.posts[post.ID] or ((bottom < height) and (top > 0)) return false unless posts[post.ID] or ((bottom < height) and (top > 0))
root = post.nodes.root root = post.nodes.root
unless $.hasClass root, 'threadOP' unless $.hasClass root, 'threadOP'
@ -83,20 +82,34 @@ QuoteThreading =
$.add threadContainer, @nodes.root $.add threadContainer, @nodes.root
Unread.posts.after post.ID, @ posts.push @ unless posts[@ID]
if posts[post.ID]
posts.after post, @
else
if (ID = posts.closest ID) isnt -1
posts.after posts[ID], @
else
posts.prepend @
return true return true
toggle: -> toggle: ->
Unread.replies = new RandomAccessList Unread.posts = new RandomAccessList
Unread.ready()
thread = $ '.thread' thread = $ '.thread'
replies = $$ '.thread > .replyContainer, .threadContainer > .replyContainer', thread replies = $$ '.thread > .replyContainer, .threadContainer > .replyContainer', thread
QuoteThreading.enabled = @checked QuoteThreading.enabled = @checked
if @checked if @checked
QuoteThreading.hasRun = false QuoteThreading.hasRun = false
for reply in replies for reply in replies
QuoteThreading.node.call node = Get.postFromRoot reply node = Get.postFromRoot reply
node.cb() if node.cb if node.cb
node.cb.call node
else
QuoteThreading.node.call node
node.cb.call node if node.cb
QuoteThreading.hasRun = true QuoteThreading.hasRun = true
else else
replies.sort (a, b) -> replies.sort (a, b) ->
@ -111,4 +124,5 @@ QuoteThreading =
kb: -> kb: ->
control = $.id 'threadingControl' control = $.id 'threadingControl'
control.click() control.checked = not control.checked
QuoteThreading.toggle.call control