From 7dbd481a6da54bbe5e00e7f52459ee0e162520ff Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 26 Jan 2013 14:24:37 +0100 Subject: [PATCH] Add Reply Hiding in the Meny, with settings. Save hiding settings of individual replies. Close #628. Close #796. --- 4chan_x.user.js | 134 +++++++++++++++++++++++++++++++++++--------- src/features.coffee | 95 ++++++++++++++++++++++++------- src/main.coffee | 7 +++ 3 files changed, 189 insertions(+), 47 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 1f0c22361..991de23e7 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -766,7 +766,7 @@ }, menu: { init: function() { - var apply, div, option; + var apply, div, makeStub; if (g.VIEW !== 'index') { return; } @@ -774,14 +774,14 @@ className: 'hide-thread-link', textContent: 'Hide thread' }); - option = $.el('label', { - innerHTML: " Make stub" - }); apply = $.el('a', { textContent: 'Apply', href: 'javascript:;' }); $.on(apply, 'click', ThreadHiding.menu.hide); + makeStub = $.el('label', { + innerHTML: " Make stub" + }); return Menu.addEntry({ el: div, open: function(post) { @@ -795,9 +795,9 @@ }, children: [ { - el: option - }, { el: apply + }, { + el: makeStub } ] }); @@ -901,13 +901,17 @@ }); }, node: function() { - var thread, _ref; + var data, thread; if (!this.isReply || this.isClone) { return; } if (thread = ReplyHiding.hiddenPosts.threads[this.thread]) { - if (_ref = this.ID, __indexOf.call(thread, _ref) >= 0) { - ReplyHiding.hide(this); + if (data = thread[this]) { + if (data.thisPost) { + ReplyHiding.hide(this, data.makeStub, data.hideRecursively); + } else { + Recursive.hide(this, data.makeStub); + } } } if (!Conf['Thread/Reply Hiding Buttons']) { @@ -959,6 +963,67 @@ } }); }, + menu: { + init: function() { + var apply, div, makeStub, replies, thisPost; + div = $.el('div', { + className: 'hide-reply-link', + textContent: 'Hide reply' + }); + apply = $.el('a', { + textContent: 'Apply', + href: 'javascript:;' + }); + $.on(apply, 'click', ReplyHiding.menu.hide); + thisPost = $.el('label', { + innerHTML: ' This post' + }); + replies = $.el('label', { + innerHTML: " Hide replies" + }); + makeStub = $.el('label', { + innerHTML: " Make stub" + }); + return Menu.addEntry({ + el: div, + open: function(post) { + if (!post.isReply || post.isClone) { + return false; + } + ReplyHiding.menu.post = post; + return true; + }, + children: [ + { + el: apply + }, { + el: thisPost + }, { + el: replies + }, { + el: makeStub + } + ] + }); + }, + hide: function() { + var makeStub, parent, post, replies, thisPost; + parent = this.parentNode; + thisPost = $('input[name=thisPost]', parent).checked; + replies = $('input[name=replies]', parent).checked; + makeStub = $('input[name=makeStub]', parent).checked; + post = ReplyHiding.menu.post; + if (thisPost) { + ReplyHiding.hide(post, makeStub, replies); + } else if (replies) { + Recursive.hide(post, makeStub); + } else { + return; + } + ReplyHiding.saveHiddenState(post, true, thisPost, makeStub, replies); + return Menu.close(); + } + }, makeButton: function(post, type) { var a; a = $.el('a', { @@ -971,28 +1036,35 @@ }); return a; }, - toggle: function(post) { - var hiddenPosts, index, thread; + saveHiddenState: function(post, isHiding, thisPost, makeStub, hideRecursively) { + var hiddenPosts, thread; hiddenPosts = ReplyHiding.getHiddenPosts(); - if (post.isHidden) { - ReplyHiding.show(post); - thread = hiddenPosts.threads[post.thread]; - if ((index = thread.indexOf(post.ID)) > -1) { - if (thread.length === 1) { - delete hiddenPosts.threads[post.thread]; - } else { - thread.splice(index, 1); - } - } - } else { - ReplyHiding.hide(post); + if (isHiding) { if (!(thread = hiddenPosts.threads[post.thread])) { - thread = hiddenPosts.threads[post.thread] = []; + thread = hiddenPosts.threads[post.thread] = {}; + } + thread[post] = { + thisPost: thisPost !== false, + makeStub: makeStub, + hideRecursively: hideRecursively + }; + } else { + thread = hiddenPosts.threads[post.thread]; + delete thread[post]; + if (!Object.keys(thread).length) { + delete hiddenPosts.threads[post.thread]; } - thread.push(post.ID); } return $.set("hiddenPosts." + g.BOARD, hiddenPosts); }, + toggle: function(post) { + if (post.isHidden) { + ReplyHiding.show(post); + } else { + ReplyHiding.hide(post); + } + return ReplyHiding.saveHiddenState(post, post.isHidden); + }, hide: function(post, makeStub, hideRecursively) { var a, postInfo, quotelink, _i, _len, _ref; if (makeStub == null) { @@ -1014,6 +1086,7 @@ $.addClass(quotelink, 'filtered'); } if (!makeStub) { + post.nodes.root.hidden = true; return; } a = ReplyHiding.makeButton(post, 'show'); @@ -1033,6 +1106,8 @@ if (post.nodes.stub) { $.rm(post.nodes.stub); delete post.nodes.stub; + } else { + post.nodes.root.hidden = false; } post.isHidden = false; _ref = Get.allQuotelinksLinkingTo(post); @@ -1079,7 +1154,7 @@ _ref = g.posts; for (ID in _ref) { post = _ref[ID]; - if (!post.isReply || post.isHidden) { + if (!post.isReply) { continue; } _ref1 = post.quotes; @@ -3596,6 +3671,13 @@ $.log(err, 'Thread Hiding - Menu'); } } + if (Conf['Reply Hiding']) { + try { + ReplyHiding.menu.init(); + } catch (err) { + $.log(err, 'Reply Hiding - Menu'); + } + } if (Conf['Delete Link']) { try { DeleteLink.init(); diff --git a/src/features.coffee b/src/features.coffee index 43b7d4d1f..716f51935 100644 --- a/src/features.coffee +++ b/src/features.coffee @@ -67,14 +67,14 @@ ThreadHiding = className: 'hide-thread-link' textContent: 'Hide thread' - option = $.el 'label', - innerHTML: " Make stub" - apply = $.el 'a', textContent: 'Apply' href: 'javascript:;' $.on apply, 'click', ThreadHiding.menu.hide + makeStub = $.el 'label', + innerHTML: " Make stub" + Menu.addEntry el: div open: (post) -> @@ -83,13 +83,12 @@ ThreadHiding = return false ThreadHiding.menu.thread = thread true - children: [{el: option}, {el: apply}] + children: [{el: apply}, {el: makeStub}] hide: -> makeStub = $('input', @parentNode).checked {thread} = ThreadHiding.menu ThreadHiding.hide thread, makeStub ThreadHiding.saveHiddenState thread, makeStub - # need to save if we made a stub or not Menu.close() makeButton: (thread, type) -> @@ -169,8 +168,11 @@ ReplyHiding = node: -> return if !@isReply or @isClone if thread = ReplyHiding.hiddenPosts.threads[@thread] - if @ID in thread - ReplyHiding.hide @ + if data = thread[@] + if data.thisPost + ReplyHiding.hide @, data.makeStub, data.hideRecursively + else + Recursive.hide @, data.makeStub return unless Conf['Thread/Reply Hiding Buttons'] $.replace $('.sideArrows', @nodes.root), ReplyHiding.makeButton @, 'hide' @@ -203,6 +205,47 @@ ReplyHiding = hiddenPosts.threads = threads $.set "hiddenPosts.#{g.BOARD}", hiddenPosts + menu: + init: -> + div = $.el 'div', + className: 'hide-reply-link' + textContent: 'Hide reply' + + apply = $.el 'a', + textContent: 'Apply' + href: 'javascript:;' + $.on apply, 'click', ReplyHiding.menu.hide + + thisPost = $.el 'label', + innerHTML: ' This post' + replies = $.el 'label', + innerHTML: " Hide replies" + makeStub = $.el 'label', + innerHTML: " Make stub" + + Menu.addEntry + el: div + open: (post) -> + if !post.isReply or post.isClone + return false + ReplyHiding.menu.post = post + true + children: [{el: apply}, {el: thisPost}, {el: replies}, {el: makeStub}] + hide: -> + parent = @parentNode + thisPost = $('input[name=thisPost]', parent).checked + replies = $('input[name=replies]', parent).checked + makeStub = $('input[name=makeStub]', parent).checked + {post} = ReplyHiding.menu + if thisPost + ReplyHiding.hide post, makeStub, replies + else if replies + Recursive.hide post, makeStub + else + return + ReplyHiding.saveHiddenState post, true, thisPost, makeStub, replies + Menu.close() + makeButton: (post, type) -> a = $.el 'a', className: "#{type}-reply-button" @@ -211,24 +254,29 @@ ReplyHiding = $.on a, 'click', -> ReplyHiding.toggle post a - toggle: (post) -> + saveHiddenState: (post, isHiding, thisPost, makeStub, hideRecursively) -> # Get fresh hidden posts. hiddenPosts = ReplyHiding.getHiddenPosts() + if isHiding + unless thread = hiddenPosts.threads[post.thread] + thread = hiddenPosts.threads[post.thread] = {} + thread[post] = + thisPost: thisPost isnt false # undefined -> true + makeStub: makeStub + hideRecursively: hideRecursively + else + thread = hiddenPosts.threads[post.thread] + delete thread[post] + unless Object.keys(thread).length + delete hiddenPosts.threads[post.thread] + $.set "hiddenPosts.#{g.BOARD}", hiddenPosts + + toggle: (post) -> if post.isHidden ReplyHiding.show post - thread = hiddenPosts.threads[post.thread] - if (index = thread.indexOf post.ID) > -1 - # Was manually hidden, not by recursion/filtering. - if thread.length is 1 - delete hiddenPosts.threads[post.thread] - else - thread.splice index, 1 else ReplyHiding.hide post - unless thread = hiddenPosts.threads[post.thread] - thread = hiddenPosts.threads[post.thread] = [] - thread.push post.ID - $.set "hiddenPosts.#{g.BOARD}", hiddenPosts + ReplyHiding.saveHiddenState post, post.isHidden hide: (post, makeStub=Conf['Stubs'], hideRecursively=Conf['Recursive Hiding']) -> return if post.isHidden @@ -239,7 +287,10 @@ ReplyHiding = for quotelink in Get.allQuotelinksLinkingTo post $.addClass quotelink, 'filtered' - return unless makeStub + unless makeStub + post.nodes.root.hidden = true + return + a = ReplyHiding.makeButton post, 'show' postInfo = if Conf['Anonymize'] @@ -258,6 +309,8 @@ ReplyHiding = if post.nodes.stub $.rm post.nodes.stub delete post.nodes.stub + else + post.nodes.root.hidden = false post.isHidden = false for quotelink in Get.allQuotelinksLinkingTo post $.rmClass quotelink, 'filtered' @@ -288,7 +341,7 @@ Recursive = {fullID} = post Recursive.toHide.push fullID for ID, post of g.posts - continue if !post.isReply or post.isHidden + continue if !post.isReply for quote in post.quotes if quote is fullID ReplyHiding.hide post, makeStub, true diff --git a/src/main.coffee b/src/main.coffee index 85a7fd72e..aaffecf9e 100644 --- a/src/main.coffee +++ b/src/main.coffee @@ -364,6 +364,13 @@ Main = # XXX handle error $.log err, 'Thread Hiding - Menu' + if Conf['Reply Hiding'] + try + ReplyHiding.menu.init() + catch err + # XXX handle error + $.log err, 'Reply Hiding - Menu' + if Conf['Delete Link'] try DeleteLink.init()