From 8db43ab04be4ca2ed9e0d6b95286b96fdb4f407b Mon Sep 17 00:00:00 2001 From: ccd0 Date: Sun, 7 Dec 2014 23:31:49 -0800 Subject: [PATCH] Add "Pin watched threads" option. #187 Also add Alt+click and menu item to watch threads in catalog. --- src/General/Config.coffee | 1 + src/General/Index.coffee | 23 ++++++++++----- src/General/css/style.css | 2 ++ src/Monitoring/ThreadWatcher.coffee | 44 ++++++++++++++++++++++++++--- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/General/Config.coffee b/src/General/Config.coffee index a52bee23c..5414f5957 100755 --- a/src/General/Config.coffee +++ b/src/General/Config.coffee @@ -589,6 +589,7 @@ http://iqdb.org/?url=%TURL 'Index Sort': 'bump' 'Index Size': 'small' 'Show Replies': true + 'Pin Watched Threads': true 'Anchor Hidden Threads': true 'Refreshed Navigation': false diff --git a/src/General/Index.coffee b/src/General/Index.coffee index df1f44e77..21fbb2d32 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -24,25 +24,27 @@ Index = Header.addShortcut @button, 1 repliesEntry = el: UI.checkbox 'Show Replies', ' Show replies' + pinEntry = el: UI.checkbox 'Pin Watched Threads', ' Pin watched threads' anchorEntry = el: UI.checkbox 'Anchor Hidden Threads', ' Anchor hidden threads' refNavEntry = el: UI.checkbox 'Refreshed Navigation', ' Refreshed navigation' - anchorEntry.el.title = 'Move hidden threads at the end of the index.' + pinEntry.el.title = 'Move watched threads to the start of the index.' + anchorEntry.el.title = 'Move hidden threads to the end of the index.' refNavEntry.el.title = 'Refresh index when navigating through pages.' - for label in [repliesEntry, anchorEntry, refNavEntry] + for label in [repliesEntry, pinEntry, anchorEntry, refNavEntry] input = label.el.firstChild {name} = input $.on input, 'change', $.cb.checked switch name when 'Show Replies' $.on input, 'change', @cb.replies - when 'Anchor Hidden Threads' + when 'Pin Watched Threads', 'Anchor Hidden Threads' $.on input, 'change', @cb.sort Header.menu.addEntry el: $.el 'span', textContent: 'Index Navigation' order: 98 - subEntries: [repliesEntry, anchorEntry, refNavEntry] + subEntries: [repliesEntry, pinEntry, anchorEntry, refNavEntry] $.addClass doc, 'index-loading', "#{Conf['Index Mode'].replace /\ /g, '-'}-mode" @root = $.el 'div', className: 'board' @@ -252,9 +254,9 @@ Index = 1 else +window.location.pathname.split('/')[2] or 1 - userPageNav: (page) -> + userPageNav: (page, noRefresh) -> state = Index.pushState {page} - if Conf['Refreshed Navigation'] + if Conf['Refreshed Navigation'] and !noRefresh Index.update state else Index.pageLoad state if state.page @@ -542,7 +544,7 @@ Index = # Sticky threads Index.sortOnTop (thread) -> thread.isSticky # Highlighted threads - Index.sortOnTop (thread) -> thread.isOnTop + Index.sortOnTop (thread) -> thread.isOnTop or Conf['Pin Watched Threads'] and ThreadWatcher.isWatched thread # Non-hidden threads Index.sortOnTop((thread) -> !thread.isHidden) if Conf['Anchor Hidden Threads'] @@ -561,6 +563,11 @@ Index = nodes = Index.buildCatalogViews() Index.sizeCatalogViews nodes else + if Index.followedThreadID? + i = 0 + i++ while Index.followedThreadID isnt Get.threadFromRoot(Index.sortedNodes[i]).ID + page = i // Index.threadsNumPerPage + 1 + Index.pushState {page} if page isnt Index.getCurrentPage() nodes = Index.buildSinglePage Index.getCurrentPage() $.rmAll Index.root $.rmAll Header.hover @@ -569,6 +576,8 @@ Index = else Index.buildReplies nodes if Conf['Show Replies'] Index.buildStructure nodes + if Index.followedThreadID? and (post = g.posts["#{g.BOARD}.#{Index.followedThreadID}"]) + Header.scrollTo post.nodes.root buildSinglePage: (pageNum) -> nodesPerPage = Index.threadsNumPerPage diff --git a/src/General/css/style.css b/src/General/css/style.css index 0c2125d68..50f41f52a 100755 --- a/src/General/css/style.css +++ b/src/General/css/style.css @@ -890,6 +890,7 @@ span.hide-announcement { -webkit-align-self: stretch; align-self: stretch; } +.catalog-thread.watched .werkTyme-filename, .filter-highlight .werkTyme-filename { border: 2px solid rgba(255, 0, 0, .5); } @@ -911,6 +912,7 @@ span.hide-announcement { .filter-highlight > .reply { box-shadow: -5px 0 rgba(255, 0, 0, .5); } +.catalog-thread.watched .catalog-thumb, .filter-highlight .catalog-thumb { border: 2px solid rgba(255, 0, 0, .5); } diff --git a/src/Monitoring/ThreadWatcher.coffee b/src/Monitoring/ThreadWatcher.coffee index e56f99310..acb6a9a2c 100755 --- a/src/Monitoring/ThreadWatcher.coffee +++ b/src/Monitoring/ThreadWatcher.coffee @@ -42,6 +42,29 @@ ThreadWatcher = Thread.callbacks.push name: 'Thread Watcher' cb: @node + CatalogThread.callbacks.push + name: 'Thread Watcher' + cb: @catalogNode + + if g.VIEW is 'index' and Conf['JSON Navigation'] and Conf['Menu'] and g.BOARD.ID isnt 'f' + Menu.menu.addEntry + el: $.el 'a', href: 'javascript:;' + order: 6 + open: ({thread}) -> + return false if Conf['Index Mode'] isnt 'catalog' + @el.textContent = if ThreadWatcher.isWatched thread + 'Unwatch thread' + else + 'Watch thread' + $.off @el, 'click', @cb if @cb + @cb = -> + $.event 'CloseMenu' + ThreadWatcher.toggle thread + $.on @el, 'click', @cb + true + + isWatched: (thread) -> + ThreadWatcher.db?.get {boardID: thread.board.ID, threadID: thread.ID} node: -> toggler = $.el 'img', @@ -49,6 +72,13 @@ ThreadWatcher = $.on toggler, 'click', ThreadWatcher.cb.toggle $.before $('input', @OP.nodes.post), toggler + catalogNode: -> + $.addClass @nodes.root, 'watched' if ThreadWatcher.isWatched @thread + $.on @nodes.thumb.parentNode, 'click', (e) => + return unless e.button is 0 and e.altKey + ThreadWatcher.toggle @thread + e.preventDefault() + ready: -> $.off d, '4chanXInitFinished', ThreadWatcher.ready return unless Main.isThisPageLegit() @@ -83,7 +113,10 @@ ThreadWatcher = ThreadWatcher.refresh() $.event 'CloseMenu' toggle: -> - ThreadWatcher.toggle Get.postFromNode(@).thread + {thread} = Get.postFromNode @ + Index.followedThreadID = thread.ID + ThreadWatcher.toggle thread + delete Index.followedThreadID rm: -> [boardID, threadID] = @parentNode.dataset.fullID.split '.' ThreadWatcher.rm boardID, +threadID @@ -240,14 +273,17 @@ ThreadWatcher = for threadID in threads.keys thread = threads[threadID] toggler = $ '.watch-thread-link', thread.OP.nodes.post - watched = ThreadWatcher.db.get {boardID: thread.board.ID, threadID} - helper = if watched then ['addClass', 'Unwatch'] else ['rmClass', 'Watch'] + helper = if ThreadWatcher.isWatched thread then ['addClass', 'Unwatch'] else ['rmClass', 'Watch'] $[helper[0]] toggler, 'watched' + $[helper[0]] thread.catalogView.nodes.root, 'watched' if thread.catalogView toggler.title = "#{helper[1]} Thread" for refresher in ThreadWatcher.menu.refreshers refresher() - return + + if Index.nodes and Conf['Pin Watched Threads'] + Index.sort() + Index.buildIndex() toggle: (thread) -> boardID = thread.board.ID