From 154ad07cd7e57e2b5df0f1e829b273a379dc3a15 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 25 Jan 2014 17:01:06 +0100 Subject: [PATCH 01/14] Initial index catalog mode work. --- css/style.css | 28 +++++++++++++++++ html/General/Thread-catalog-view.html | 8 +++++ src/General/Build.coffee | 44 +++++++++++++++++++++++++-- src/General/Index.coffee | 26 +++++++++++----- src/General/Thread.coffee | 4 +++ 5 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 html/General/Thread-catalog-view.html diff --git a/css/style.css b/css/style.css index f697b45e2..8d23bde6c 100644 --- a/css/style.css +++ b/css/style.css @@ -401,6 +401,34 @@ a[href="javascript:;"] { .summary { text-decoration: none; } +.catalog-mode { + text-align: center; +} +.catalog-thread { + display: inline-block; + vertical-align: top; + padding-top: 5px; + width: 165px; + max-height: 320px; + overflow: hidden; + word-break: break-word; +} +.thumb { + max-width: 150px; + max-height: 150px; + box-shadow: 0 0 5px rgba(0, 0, 0, .25); +} +.thread-stats { + cursor: help; + font-size: 10px; + font-weight: 700; + line-height: .8; + margin-top: 1px; + float: none; +} +.catalog-thread .subject { + font-weight: 700; +} /* Announcement Hiding */ :root.hide-announcement #globalMessage, diff --git a/html/General/Thread-catalog-view.html b/html/General/Thread-catalog-view.html new file mode 100644 index 000000000..9592c56a0 --- /dev/null +++ b/html/General/Thread-catalog-view.html @@ -0,0 +1,8 @@ + + + +
+ #{postCount} / #{fileCount} / #{pageCount} +
+#{subject} +
#{comment}
diff --git a/src/General/Build.coffee b/src/General/Build.coffee index 6fa1278b8..ad1c14558 100644 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -254,9 +254,49 @@ Build = [posts, files] = if Conf['Show Replies'] [data.omitted_posts, data.omitted_images] else - # XXX data.images is not accurate. - [data.replies, data.omitted_images + data.last_replies.filter((data) -> !!data.ext).length] + [data.replies, data.images] nodes.push Build.summary board.ID, data.no, posts, files $.add root, nodes root + threadCatalog: (thread) -> + for data in Index.liveThreadData + break if data.no is thread.ID + + if data.spoiler and !Conf['Reveal Spoilers'] + src = "#{Build.staticPath}spoiler" + if spoilerRange = Build.spoilerRange[thread.board] + # Randomize the spoiler image. + src += "-#{thread.board}" + Math.floor 1 + spoilerRange * Math.random() + src += '.png' + imgWidth = imgHeight = 100 + else if data.filedeleted + src = "#{Build.staticPath}filedeleted-res#{Build.gifIcon}" + imgWidth = 127 + imgHeight = 13 + else + src = thread.OP.file.thumbURL + max = Math.max data.tn_w, data.tn_h + imgWidth = data.tn_w * 150 / max + imgHeight = data.tn_h * 150 / max + + postCount = data.replies + 1 + fileCount = data.images + !!data.ext + pageCount = Math.floor Index.liveThreadIDs.indexOf(thread.ID) / Index.threadsNumPerPage + + subject = if thread.OP.info.subject + "
#{thread.OP.info.subject}
" + else + '' + comment = thread.OP.nodes.comment.innerHTML.replace /(
){2,}/g, '
' + + root = $.el 'div', + className: 'catalog-thread' + innerHTML: <%= importHTML('General/Thread-catalog-view') %> + + if data.bumplimit + $.addClass $('.post-count', root), 'warning' + if data.imagelimit + $.addClass $('.file-count', root), 'warning' + + root diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 79a935099..1d763746f 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -14,6 +14,7 @@ Index = subEntries: [ { el: $.el 'label', innerHTML: ' Paged' } { el: $.el 'label', innerHTML: ' All threads' } + { el: $.el 'label', innerHTML: ' Catalog' } ] for label in modeEntry.subEntries input = label.el.firstChild @@ -68,6 +69,7 @@ Index = $.addClass doc, 'index-loading' @update() @root = $.el 'div', className: 'board' + Index.cb.rootClass() @pagelist = $.el 'div', className: 'pagelist' hidden: true @@ -101,7 +103,10 @@ Index = $.replace $('.pagelist'), Index.pagelist cb: + rootClass: -> + (if Conf['Index Mode'] is 'catalog' then $.addClass else $.rmClass) Index.root, 'catalog-mode' mode: -> + Index.cb.rootClass() Index.togglePagelist() Index.buildIndex() sort: -> @@ -368,14 +373,21 @@ Index = Index.sortedNodes.splice offset++ * 2, 0, Index.sortedNodes.splice(i, 2)... return buildIndex: -> - if Conf['Index Mode'] is 'paged' - pageNum = Index.getCurrentPage() - nodesPerPage = Index.threadsNumPerPage * 2 - nodes = Index.sortedNodes[nodesPerPage * pageNum ... nodesPerPage * (pageNum + 1)] - else - nodes = Index.sortedNodes + switch Conf['Index Mode'] + when 'paged' + pageNum = Index.getCurrentPage() + nodesPerPage = Index.threadsNumPerPage * 2 + nodes = Index.sortedNodes[nodesPerPage * pageNum ... nodesPerPage * (pageNum + 1)] + when 'catalog' + nodes = Index.sortedNodes + .filter((n, i) -> !(i % 2)) + .map((threadRoot) -> Get.threadFromRoot threadRoot) + .filter((thread) -> !thread.isHidden) + .map (thread) -> thread.getCatalogView() + else + nodes = Index.sortedNodes $.rmAll Index.root - Index.buildReplies nodes if Conf['Show Replies'] + Index.buildReplies nodes if Conf['Show Replies'] and Conf['Index Mode'] isnt 'catalog' $.event 'IndexBuild', nodes $.add Index.root, nodes diff --git a/src/General/Thread.coffee b/src/General/Thread.coffee index 410a4288a..d7dd92fa3 100644 --- a/src/General/Thread.coffee +++ b/src/General/Thread.coffee @@ -39,6 +39,10 @@ class Thread $ '[title="Quote this post"]', @OP.nodes.info $.after root, [$.tn(' '), icon] + getCatalogView: -> + return @catalogView if @catalogView + @catalogView = Build.threadCatalog @ + kill: -> @isDead = true @timeOfDeath = Date.now() From 2024e0c50d943f5ceb5771d4924910dd3731f85b Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 25 Jan 2014 19:00:26 +0100 Subject: [PATCH 02/14] Add sticky/closed status icons in the catalog. --- css/style.css | 23 +++++++++++++++++++++++ html/General/Thread-catalog-view.html | 3 ++- src/General/Build.coffee | 26 ++++++++++++++++++++------ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/css/style.css b/css/style.css index 8d23bde6c..18a7a1e32 100644 --- a/css/style.css +++ b/css/style.css @@ -413,11 +413,34 @@ a[href="javascript:;"] { overflow: hidden; word-break: break-word; } +.catalog-thread > a { + display: inline-block; + position: relative; +} .thumb { max-width: 150px; max-height: 150px; box-shadow: 0 0 5px rgba(0, 0, 0, .25); } +.thunb.spoiler-file { + width: 100px; + height: 100px; +} +.thumb.deleted-file { + width: 127px; + height: 13px; + padding: 20px 11px; +} +.thumb.no-file { + width: 77px; + height: 13px; + padding: 20px 36px; +} +.thread-icons { + position: absolute; + top: 1px; + right: 1px; +} .thread-stats { cursor: help; font-size: 10px; diff --git a/html/General/Thread-catalog-view.html b/html/General/Thread-catalog-view.html index 9592c56a0..cf87775c9 100644 --- a/html/General/Thread-catalog-view.html +++ b/html/General/Thread-catalog-view.html @@ -1,5 +1,6 @@ - + +
#{postCount} / #{fileCount} / #{pageCount} diff --git a/src/General/Build.coffee b/src/General/Build.coffee index ad1c14558..def630799 100644 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -260,25 +260,28 @@ Build = $.add root, nodes root threadCatalog: (thread) -> + {staticPath, gifIcon} = Build for data in Index.liveThreadData break if data.no is thread.ID if data.spoiler and !Conf['Reveal Spoilers'] - src = "#{Build.staticPath}spoiler" + src = "#{staticPath}spoiler" if spoilerRange = Build.spoilerRange[thread.board] # Randomize the spoiler image. src += "-#{thread.board}" + Math.floor 1 + spoilerRange * Math.random() src += '.png' - imgWidth = imgHeight = 100 + imgClass = 'spoiler-file' else if data.filedeleted - src = "#{Build.staticPath}filedeleted-res#{Build.gifIcon}" - imgWidth = 127 - imgHeight = 13 - else + src = "#{staticPath}filedeleted-res#{gifIcon}" + imgClass = 'deleted-file' + else if thread.OP.file src = thread.OP.file.thumbURL max = Math.max data.tn_w, data.tn_h imgWidth = data.tn_w * 150 / max imgHeight = data.tn_h * 150 / max + else + src = "#{staticPath}nofile.png" + imgClass = 'no-file' postCount = data.replies + 1 fileCount = data.images + !!data.ext @@ -294,6 +297,17 @@ Build = className: 'catalog-thread' innerHTML: <%= importHTML('General/Thread-catalog-view') %> + if thread.isSticky + $.add $('.thread-icons', root), $.el 'img', + src: "#{staticPath}sticky#{gifIcon}" + className: 'stickyIcon' + title: 'Sticky' + if thread.isClosed + $.add $('.thread-icons', root), $.el 'img', + src: "#{staticPath}closed#{gifIcon}" + className: 'closedIcon' + title: 'Closed' + if data.bumplimit $.addClass $('.post-count', root), 'warning' if data.imagelimit From efd28e8ae42dba993dd48b425dce3c928160b7e6 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 26 Jan 2014 17:02:55 +0100 Subject: [PATCH 03/14] Update page/sticky/closed status on index refresh for the catalog. --- src/General/Thread.coffee | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/General/Thread.coffee b/src/General/Thread.coffee index d7dd92fa3..0ab71f599 100644 --- a/src/General/Thread.coffee +++ b/src/General/Thread.coffee @@ -16,7 +16,7 @@ class Thread icon = $ '.page-num', @OP.nodes.post for key in ['title', 'textContent'] icon[key] = icon[key].replace /\d+/, pageNum - return + $('.page-count', @catalogView).textContent = pageNum if @catalogView setStatus: (type, status) -> name = "is#{type}" return if @[name] is status @@ -25,20 +25,26 @@ class Thread typeLC = type.toLowerCase() unless status $.rm $ ".#{typeLC}Icon", @OP.nodes.info + $.rm $ ".#{typeLC}Icon", @catalogView if @catalogView return + icon = $.el 'img', - src: "//s.4cdn.org/image/#{typeLC}#{if window.devicePixelRatio >= 2 then '@2x' else ''}.gif" + src: "#{Build.staticPath}#{typeLC}#{Build.gifIcon}" alt: type title: type className: "#{typeLC}Icon" root = if type is 'Closed' and @isSticky $ '.stickyIcon', @OP.nodes.info else if g.VIEW is 'index' - $ '.page-num', @OP.nodes.info + $ '.page-num', @OP.nodes.info else $ '[title="Quote this post"]', @OP.nodes.info $.after root, [$.tn(' '), icon] + return unless @catalogView + root = $ '.thread-icons', @catalogView + (if type is 'Sticky' and @isClosed then $.prepend else $.add) root, icon.cloneNode() + getCatalogView: -> return @catalogView if @catalogView @catalogView = Build.threadCatalog @ From bdf2b4a6ba4a4396c035c9f3eaf0bc794a18d0ee Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 26 Jan 2014 17:20:29 +0100 Subject: [PATCH 04/14] Update thread post/file count on index refresh in the catalog. --- src/General/Index.coffee | 2 ++ src/General/Thread.coffee | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 1d763746f..b86aa8ce2 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -294,6 +294,8 @@ Index = Index.nodes.push threadRoot, $.el 'hr' if thread = g.BOARD.threads[threadData.no] thread.setPage Math.floor i / Index.threadsNumPerPage + thread.setCount 'post', threadData.replies + 1, threadData.bumplimit + thread.setCount 'file', threadData.images + !!threadData.ext, threadData.imagelimit thread.setStatus 'Sticky', !!threadData.sticky thread.setStatus 'Closed', !!threadData.closed else diff --git a/src/General/Thread.coffee b/src/General/Thread.coffee index 0ab71f599..85a95ce05 100644 --- a/src/General/Thread.coffee +++ b/src/General/Thread.coffee @@ -17,6 +17,11 @@ class Thread for key in ['title', 'textContent'] icon[key] = icon[key].replace /\d+/, pageNum $('.page-count', @catalogView).textContent = pageNum if @catalogView + setCount: (type, count, reachedLimit) -> + return unless @catalogView + el = $ ".#{type}-count", @catalogView + el.textContent = count + (if reachedLimit then $.addClass else $.rmClass) el, 'warning' setStatus: (type, status) -> name = "is#{type}" return if @[name] is status From 76230405930496d8d294bddf688f7d11ec180516 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 26 Jan 2014 18:19:23 +0100 Subject: [PATCH 05/14] Add filter-highlight to threads on the catalog. --- css/style.css | 4 ++++ src/Filtering/Filter.coffee | 1 + src/General/Build.coffee | 2 ++ 3 files changed, 7 insertions(+) diff --git a/css/style.css b/css/style.css index 18a7a1e32..41991048a 100644 --- a/css/style.css +++ b/css/style.css @@ -420,6 +420,7 @@ a[href="javascript:;"] { .thumb { max-width: 150px; max-height: 150px; + border-radius: 2px; box-shadow: 0 0 5px rgba(0, 0, 0, .25); } .thunb.spoiler-file { @@ -648,6 +649,9 @@ a.hide-announcement { .filter-highlight > .reply { box-shadow: -5px 0 rgba(255, 0, 0, .5); } +.filter-highlight .thumb { + border: 2px solid rgba(255, 0, 0, .5); +} /* Thread & Reply Hiding */ .hide-thread-button, diff --git a/src/Filtering/Filter.coffee b/src/Filtering/Filter.coffee index eee0dfae9..f1362b48f 100644 --- a/src/Filtering/Filter.coffee +++ b/src/Filtering/Filter.coffee @@ -110,6 +110,7 @@ Filter = # Highlight $.addClass @nodes.root, result.class + @thread.highlight = result.class if !@isReply and result.top @thread.isOnTop = true diff --git a/src/General/Build.coffee b/src/General/Build.coffee index def630799..82b51686e 100644 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -297,6 +297,8 @@ Build = className: 'catalog-thread' innerHTML: <%= importHTML('General/Thread-catalog-view') %> + $.addClass root, thread.highlight if thread.highlight + if thread.isSticky $.add $('.thread-icons', root), $.el 'img', src: "#{staticPath}sticky#{gifIcon}" From 509156a95667f4b835808d9f1d804741b425a753 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 26 Jan 2014 20:29:21 +0100 Subject: [PATCH 06/14] Don't use the IndexBuild event for hiding threads. --- src/Filtering/ThreadHiding.coffee | 6 +++--- src/General/Index.coffee | 2 +- src/Monitoring/ThreadWatcher.coffee | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Filtering/ThreadHiding.coffee b/src/Filtering/ThreadHiding.coffee index 6d5635201..b0ed6c60c 100644 --- a/src/Filtering/ThreadHiding.coffee +++ b/src/Filtering/ThreadHiding.coffee @@ -4,7 +4,7 @@ ThreadHiding = @db = new DataBoard 'hiddenThreads' @syncCatalog() - $.on d, 'IndexBuild', @onIndexBuild + $.on d, 'IndexRefresh', @onIndexRefresh Thread.callbacks.push name: 'Thread Hiding' cb: @node @@ -15,8 +15,8 @@ ThreadHiding = return unless Conf['Thread Hiding'] $.prepend @OP.nodes.root, ThreadHiding.makeButton @, 'hide' - onIndexBuild: ({detail: nodes}) -> - for root, i in nodes by 2 + onIndexRefresh: -> + for root, i in Index.nodes by 2 thread = Get.threadFromRoot root continue unless thread.isHidden unless thread.stub diff --git a/src/General/Index.coffee b/src/General/Index.coffee index b86aa8ce2..8b5a42320 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -390,8 +390,8 @@ Index = nodes = Index.sortedNodes $.rmAll Index.root Index.buildReplies nodes if Conf['Show Replies'] and Conf['Index Mode'] isnt 'catalog' - $.event 'IndexBuild', nodes $.add Index.root, nodes + $.event 'IndexBuild', nodes isSearching: false clearSearch: -> diff --git a/src/Monitoring/ThreadWatcher.coffee b/src/Monitoring/ThreadWatcher.coffee index 3eac7ae4c..ab570ebb0 100644 --- a/src/Monitoring/ThreadWatcher.coffee +++ b/src/Monitoring/ThreadWatcher.coffee @@ -72,9 +72,8 @@ ThreadWatcher = else if Conf['Auto Watch Reply'] ThreadWatcher.add board.threads[threadID] onIndexRefresh: -> - {db} = ThreadWatcher boardID = g.BOARD.ID - for threadID, data of db.data.boards[boardID] when not data.isDead and threadID not of g.BOARD.threads + for threadID, data of ThreadWatcher.db.data.boards[boardID] when not data.isDead and threadID not of g.BOARD.threads if Conf['Auto Prune'] ThreadWatcher.db.delete {boardID, threadID} else From a8002930f4e3250070c26fe8d142e7fa04bf78d5 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 26 Jan 2014 22:18:29 +0100 Subject: [PATCH 07/14] Warn users of the official catalog of the incoming support removal. --- src/General/Index.coffee | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 8b5a42320..13be9c5d7 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -1,5 +1,15 @@ Index = init: -> + if g.VIEW is 'catalog' + $.ready -> + span = $.el 'a', + href: '<%= meta.repo %>blob/<%= meta.mainBranch %>/CHANGELOG.md' + textContent: 'Support for the official catalog to be removed' + title: '<%= meta.name %> now has a "catalog" Index mode.' + className: 'btn-wrap warning' + target: '_blank' + $.add $.id('info'), span + return if g.VIEW isnt 'index' or g.BOARD.ID is 'f' @button = $.el 'a', From 1d43fbc498f5f768d9de3ab7cb25987381b960c6 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Tue, 28 Jan 2014 09:59:49 +0100 Subject: [PATCH 08/14] Shift+click to hide threads in the catalog. --- src/Filtering/Filter.coffee | 3 ++- src/Filtering/ThreadHiding.coffee | 2 +- src/General/Build.coffee | 2 +- src/General/Thread.coffee | 11 +++++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Filtering/Filter.coffee b/src/Filtering/Filter.coffee index f1362b48f..b24b06238 100644 --- a/src/Filtering/Filter.coffee +++ b/src/Filtering/Filter.coffee @@ -110,7 +110,8 @@ Filter = # Highlight $.addClass @nodes.root, result.class - @thread.highlight = result.class + unless result.class in @highlights + (@highlights or= []).push result.class if !@isReply and result.top @thread.isOnTop = true diff --git a/src/Filtering/ThreadHiding.coffee b/src/Filtering/ThreadHiding.coffee index b0ed6c60c..155a94be1 100644 --- a/src/Filtering/ThreadHiding.coffee +++ b/src/Filtering/ThreadHiding.coffee @@ -1,6 +1,6 @@ ThreadHiding = init: -> - return if g.VIEW isnt 'index' or !Conf['Thread Hiding'] and !Conf['Thread Hiding Link'] + return if g.VIEW isnt 'index' @db = new DataBoard 'hiddenThreads' @syncCatalog() diff --git a/src/General/Build.coffee b/src/General/Build.coffee index 82b51686e..b257ae628 100644 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -297,7 +297,7 @@ Build = className: 'catalog-thread' innerHTML: <%= importHTML('General/Thread-catalog-view') %> - $.addClass root, thread.highlight if thread.highlight + $.addClass root, thread.OP.highlights... if thread.OP.highlights if thread.isSticky $.add $('.thread-icons', root), $.el 'img', diff --git a/src/General/Thread.coffee b/src/General/Thread.coffee index 85a95ce05..0051c3f21 100644 --- a/src/General/Thread.coffee +++ b/src/General/Thread.coffee @@ -53,6 +53,17 @@ class Thread getCatalogView: -> return @catalogView if @catalogView @catalogView = Build.threadCatalog @ + $.on $('.thumb', @catalogView), 'click', @onCatalogViewClick + @catalogView + onCatalogViewClick: (e) => + return if e.button isnt 0 + if e.shiftKey + $.rm @catalogView + ThreadHiding.hide @ + ThreadHiding.saveHiddenState @ + else + return + e.preventDefault() kill: -> @isDead = true From 9f682bea14388ac85cd33f2fb62b904e472e4549 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Tue, 28 Jan 2014 10:26:46 +0100 Subject: [PATCH 09/14] Alt+click to pin threads in the catalog. --- css/style.css | 1 + src/Filtering/Filter.coffee | 2 +- src/General/Build.coffee | 1 + src/General/DataBoard.coffee | 2 +- src/General/Index.coffee | 23 +++++++++++++++++++++++ src/General/Thread.coffee | 8 ++++++++ 6 files changed, 35 insertions(+), 2 deletions(-) diff --git a/css/style.css b/css/style.css index 41991048a..5abad3b16 100644 --- a/css/style.css +++ b/css/style.css @@ -649,6 +649,7 @@ a.hide-announcement { .filter-highlight > .reply { box-shadow: -5px 0 rgba(255, 0, 0, .5); } +.pinned .thumb, .filter-highlight .thumb { border: 2px solid rgba(255, 0, 0, .5); } diff --git a/src/Filtering/Filter.coffee b/src/Filtering/Filter.coffee index b24b06238..85c86d215 100644 --- a/src/Filtering/Filter.coffee +++ b/src/Filtering/Filter.coffee @@ -110,7 +110,7 @@ Filter = # Highlight $.addClass @nodes.root, result.class - unless result.class in @highlights + unless @highlights and result.class in @highlights (@highlights or= []).push result.class if !@isReply and result.top @thread.isOnTop = true diff --git a/src/General/Build.coffee b/src/General/Build.coffee index b257ae628..cbcb86b06 100644 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -297,6 +297,7 @@ Build = className: 'catalog-thread' innerHTML: <%= importHTML('General/Thread-catalog-view') %> + $.addClass root, 'pinned' if thread.isPinned $.addClass root, thread.OP.highlights... if thread.OP.highlights if thread.isSticky diff --git a/src/General/DataBoard.coffee b/src/General/DataBoard.coffee index aba14d68d..dc4319816 100644 --- a/src/General/DataBoard.coffee +++ b/src/General/DataBoard.coffee @@ -1,5 +1,5 @@ class DataBoard - @keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads'] + @keys = ['pinnedThreads', 'hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads'] constructor: (@key, sync, dontClean) -> @data = Conf[key] diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 13be9c5d7..54386601b 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -12,6 +12,11 @@ Index = return if g.VIEW isnt 'index' or g.BOARD.ID is 'f' + @db = new DataBoard 'pinnedThreads' + Thread.callbacks.push + name: 'Thread Pinning' + cb: @node + @button = $.el 'a', className: 'index-refresh-shortcut fa fa-refresh' title: 'Refresh Index' @@ -112,6 +117,24 @@ Index = $.asap (-> $('.pagelist') or d.readyState isnt 'loading'), -> $.replace $('.pagelist'), Index.pagelist + node: -> + return unless data = Index.db.get {boardID: @board.ID, threadID: @ID} + @pin() if data.isPinned + togglePin: (thread) -> + if thread.isPinned + thread.unpin() + Index.db.delete + boardID: thread.board.ID + threadID: thread.ID + else + thread.pin() + Index.db.set + boardID: thread.board.ID + threadID: thread.ID + val: isPinned: thread.isPinned + Index.sort() + Index.buildIndex() + cb: rootClass: -> (if Conf['Index Mode'] is 'catalog' then $.addClass else $.rmClass) Index.root, 'catalog-mode' diff --git a/src/General/Thread.coffee b/src/General/Thread.coffee index 0051c3f21..3103d08f1 100644 --- a/src/General/Thread.coffee +++ b/src/General/Thread.coffee @@ -61,9 +61,17 @@ class Thread $.rm @catalogView ThreadHiding.hide @ ThreadHiding.saveHiddenState @ + else if e.altKey + Index.togglePin @ else return e.preventDefault() + pin: -> + @isOnTop = @isPinned = true + $.addClass @catalogView, 'pinned' if @catalogView + unpin: -> + @isOnTop = @isPinned = false + $.rmClass @catalogView, 'pinned' if @catalogView kill: -> @isDead = true From a4ef601748778e8b6c4b3b79869e03d5b1da0e8e Mon Sep 17 00:00:00 2001 From: Mayhem Date: Wed, 29 Jan 2014 14:31:38 +0100 Subject: [PATCH 10/14] Refactor the catalog thread views business with a class. --- Gruntfile.coffee | 1 + src/General/Build.coffee | 6 ++--- src/General/CatalogThread.coffee | 14 ++++++++++++ src/General/Index.coffee | 38 ++++++++++++++++++++++++++------ src/General/Thread.coffee | 27 ++++++----------------- 5 files changed, 56 insertions(+), 30 deletions(-) create mode 100644 src/General/CatalogThread.coffee diff --git a/Gruntfile.coffee b/Gruntfile.coffee index c97e8e155..64a932158 100644 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -40,6 +40,7 @@ module.exports = (grunt) -> # <--| 'src/General/Board.coffee' 'src/General/Thread.coffee' + 'src/General/CatalogThread.coffee' 'src/General/Post.coffee' 'src/General/Clone.coffee' 'src/General/DataBoard.coffee' diff --git a/src/General/Build.coffee b/src/General/Build.coffee index cbcb86b06..548cee44e 100644 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -259,10 +259,9 @@ Build = $.add root, nodes root - threadCatalog: (thread) -> + catalogThread: (thread) -> {staticPath, gifIcon} = Build - for data in Index.liveThreadData - break if data.no is thread.ID + data = Index.liveThreadData[Index.liveThreadIDs.indexOf thread.ID] if data.spoiler and !Conf['Reveal Spoilers'] src = "#{staticPath}spoiler" @@ -297,6 +296,7 @@ Build = className: 'catalog-thread' innerHTML: <%= importHTML('General/Thread-catalog-view') %> + root.dataset.fullID = thread.fullID $.addClass root, 'pinned' if thread.isPinned $.addClass root, thread.OP.highlights... if thread.OP.highlights diff --git a/src/General/CatalogThread.coffee b/src/General/CatalogThread.coffee new file mode 100644 index 000000000..ae8f832d0 --- /dev/null +++ b/src/General/CatalogThread.coffee @@ -0,0 +1,14 @@ +class CatalogThread + @callbacks = [] + toString: -> @ID + + constructor: (root, @thread) -> + @ID = @thread.ID + @board = @thread.board + @nodes = + root: root + thumb: $ '.thumb', root + postCount: $ '.post-count', root + fileCount: $ '.file-count', root + pageCount: $ '.page-count', root + @thread.catalogView = @ diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 54386601b..1ce167006 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -15,7 +15,10 @@ Index = @db = new DataBoard 'pinnedThreads' Thread.callbacks.push name: 'Thread Pinning' - cb: @node + cb: @threadNode + CatalogThread.callbacks.push + name: 'Catalog Features' + cb: @catalogNode @button = $.el 'a', className: 'index-refresh-shortcut fa fa-refresh' @@ -117,9 +120,24 @@ Index = $.asap (-> $('.pagelist') or d.readyState isnt 'loading'), -> $.replace $('.pagelist'), Index.pagelist - node: -> + threadNode: -> return unless data = Index.db.get {boardID: @board.ID, threadID: @ID} @pin() if data.isPinned + catalogNode: -> + $.on @nodes.thumb, 'click', Index.onClick + onClick: (e) -> + return if e.button isnt 0 + root = @parentNode.parentNode + thread = g.threads[root.dataset.fullID] + if e.shiftKey + $.rm root + ThreadHiding.hide thread + ThreadHiding.saveHiddenState thread + else if e.altKey + Index.togglePin thread + else + return + e.preventDefault() togglePin: (thread) -> if thread.isPinned thread.unpin() @@ -374,6 +392,16 @@ Index = Main.handleErrors errors if errors Main.callbackNodes Post, posts + buildCatalogViews: -> + threads = Index.sortedNodes + .filter((n, i) -> !(i % 2)) + .map((threadRoot) -> Get.threadFromRoot threadRoot) + .filter (thread) -> !thread.isHidden + catalogThreads = [] + for thread in threads when !thread.catalogView + catalogThreads.push new CatalogThread Build.catalogThread(thread), thread + Main.callbackNodes CatalogThread, catalogThreads + threads.map (thread) -> thread.catalogView.nodes.root sort: -> switch Conf['Index Sort'] when 'bump' @@ -414,11 +442,7 @@ Index = nodesPerPage = Index.threadsNumPerPage * 2 nodes = Index.sortedNodes[nodesPerPage * pageNum ... nodesPerPage * (pageNum + 1)] when 'catalog' - nodes = Index.sortedNodes - .filter((n, i) -> !(i % 2)) - .map((threadRoot) -> Get.threadFromRoot threadRoot) - .filter((thread) -> !thread.isHidden) - .map (thread) -> thread.getCatalogView() + nodes = Index.buildCatalogViews() else nodes = Index.sortedNodes $.rmAll Index.root diff --git a/src/General/Thread.coffee b/src/General/Thread.coffee index 3103d08f1..8037f09d2 100644 --- a/src/General/Thread.coffee +++ b/src/General/Thread.coffee @@ -10,16 +10,19 @@ class Thread @postLimit = false @fileLimit = false + @OP = null + @catalogView = null + g.threads[@fullID] = board.threads[@] = @ setPage: (pageNum) -> icon = $ '.page-num', @OP.nodes.post for key in ['title', 'textContent'] icon[key] = icon[key].replace /\d+/, pageNum - $('.page-count', @catalogView).textContent = pageNum if @catalogView + @catalogView.nodes.pageCount.textContent = pageNum if @catalogView setCount: (type, count, reachedLimit) -> return unless @catalogView - el = $ ".#{type}-count", @catalogView + el = @catalogView.nodes["#{type}Count"] el.textContent = count (if reachedLimit then $.addClass else $.rmClass) el, 'warning' setStatus: (type, status) -> @@ -50,28 +53,12 @@ class Thread root = $ '.thread-icons', @catalogView (if type is 'Sticky' and @isClosed then $.prepend else $.add) root, icon.cloneNode() - getCatalogView: -> - return @catalogView if @catalogView - @catalogView = Build.threadCatalog @ - $.on $('.thumb', @catalogView), 'click', @onCatalogViewClick - @catalogView - onCatalogViewClick: (e) => - return if e.button isnt 0 - if e.shiftKey - $.rm @catalogView - ThreadHiding.hide @ - ThreadHiding.saveHiddenState @ - else if e.altKey - Index.togglePin @ - else - return - e.preventDefault() pin: -> @isOnTop = @isPinned = true - $.addClass @catalogView, 'pinned' if @catalogView + $.addClass @catalogView.nodes.root, 'pinned' if @catalogView unpin: -> @isOnTop = @isPinned = false - $.rmClass @catalogView, 'pinned' if @catalogView + $.rmClass @catalogView.nodes.root, 'pinned' if @catalogView kill: -> @isDead = true From 5383dbde05c6787729d108660c5ee66ee8c9600c Mon Sep 17 00:00:00 2001 From: Mayhem Date: Wed, 29 Jan 2014 14:48:52 +0100 Subject: [PATCH 11/14] Remove quotelinks in threads in the catalog. --- src/General/Build.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/General/Build.coffee b/src/General/Build.coffee index 548cee44e..f5d81b137 100644 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -300,6 +300,9 @@ Build = $.addClass root, 'pinned' if thread.isPinned $.addClass root, thread.OP.highlights... if thread.OP.highlights + for quotelink in $$ '.quotelink', root.lastElementChild + $.replace quotelink, [quotelink.childNodes...] + if thread.isSticky $.add $('.thread-icons', root), $.el 'img', src: "#{staticPath}sticky#{gifIcon}" From 6dc91cfbdc3c2afd5c0ca1bc903bcf4a9db888dc Mon Sep 17 00:00:00 2001 From: Mayhem Date: Wed, 29 Jan 2014 15:01:29 +0100 Subject: [PATCH 12/14] Add Image Hover support in the catalog. Close #836 --- src/Images/ImageHover.coffee | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Images/ImageHover.coffee b/src/Images/ImageHover.coffee index 9494b0c71..f205c941c 100644 --- a/src/Images/ImageHover.coffee +++ b/src/Images/ImageHover.coffee @@ -5,11 +5,20 @@ ImageHover = Post.callbacks.push name: 'Image Hover' cb: @node + CatalogThread.callbacks.push + name: 'Image Hover' + cb: @catalogNode node: -> return unless @file?.isImage $.on @file.thumb, 'mouseover', ImageHover.mouseover + catalogNode: -> + return unless @thread.OP.file?.isImage + $.on @nodes.thumb, 'mouseover', ImageHover.mouseover mouseover: (e) -> - post = Get.postFromNode @ + post = if $.hasClass @, 'thumb' + g.posts[@parentNode.parentNode.dataset.fullID] + else + Get.postFromNode @ el = $.el 'img', id: 'ihover' src: post.file.URL From 10dfa74be0f0e0c9665fc41c1766942be41481bf Mon Sep 17 00:00:00 2001 From: Mayhem Date: Wed, 29 Jan 2014 15:16:12 +0100 Subject: [PATCH 13/14] Catalog changelog. --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2c95cd74..eab556a9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +- More index navigation improvements: + - New index mode: `catalog` + - When in catalog mode, use `Shift+Click` to hide, and `Alt+Click` to pin threads. + - Existing features affect the catalog mode such as: +
    +
  • Filter (hiding, highlighting) +
  • Thread Hiding +
  • Linkify +
  • Image Hover +
+ - Support for the official catalog will be removed in the future, once the catalog mode for the index is deemed satisfactory. - Added `Original filename` variable to Sauce panel. - Added a `Reset Settings` button in the settings. From 44e28961fdd11d3ded0a002937e09c4dd76c0438 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Wed, 29 Jan 2014 15:22:46 +0100 Subject: [PATCH 14/14] Add Auto-GIF support in the catalog. --- CHANGELOG.md | 1 + src/Images/AutoGIF.coffee | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eab556a9b..773f836d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@
  • Filter (hiding, highlighting)
  • Thread Hiding
  • Linkify +
  • Auto-GIF
  • Image Hover - Support for the official catalog will be removed in the future, once the catalog mode for the index is deemed satisfactory. diff --git a/src/Images/AutoGIF.coffee b/src/Images/AutoGIF.coffee index 71ccc7d8e..a80481407 100644 --- a/src/Images/AutoGIF.coffee +++ b/src/Images/AutoGIF.coffee @@ -5,6 +5,9 @@ AutoGIF = Post.callbacks.push name: 'Auto-GIF' cb: @node + CatalogThread.callbacks.push + name: 'Auto-GIF' + cb: @catalogNode node: -> return if @isClone or @isHidden or @thread.isHidden or !@file?.isImage {thumb, URL} = @file @@ -13,8 +16,17 @@ AutoGIF = # Revealed spoilers do not have height/width set, this fixes auto-gifs dimensions. {style} = thumb style.maxHeight = style.maxWidth = if @isReply then '125px' else '250px' + AutoGIF.replaceThumbnail thumb, URL + catalogNode: -> + {OP} = @thread + return unless OP.file?.isImage + {URL} = OP.file + return unless /gif$/.test URL + AutoGIF.replaceThumbnail @nodes.thumb, URL + replaceThumbnail: (thumb, URL) -> gif = $.el 'img' $.on gif, 'load', -> # Replace the thumbnail once the GIF has finished loading. thumb.src = URL gif.src = URL +