Merge pull request #1405 from MayhemYDG/index
Index navigation improvements - EP04
This commit is contained in:
commit
20ceb570e1
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,3 +1,15 @@
|
|||||||
|
- 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:
|
||||||
|
<ul>
|
||||||
|
<li> Filter (hiding, highlighting)
|
||||||
|
<li> Thread Hiding
|
||||||
|
<li> Linkify
|
||||||
|
<li> Auto-GIF
|
||||||
|
<li> Image Hover
|
||||||
|
</ul>
|
||||||
|
- 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 `Original filename` variable to Sauce panel.
|
||||||
- Added a `Reset Settings` button in the settings.
|
- Added a `Reset Settings` button in the settings.
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@ module.exports = (grunt) ->
|
|||||||
# <--|
|
# <--|
|
||||||
'src/General/Board.coffee'
|
'src/General/Board.coffee'
|
||||||
'src/General/Thread.coffee'
|
'src/General/Thread.coffee'
|
||||||
|
'src/General/CatalogThread.coffee'
|
||||||
'src/General/Post.coffee'
|
'src/General/Post.coffee'
|
||||||
'src/General/Clone.coffee'
|
'src/General/Clone.coffee'
|
||||||
'src/General/DataBoard.coffee'
|
'src/General/DataBoard.coffee'
|
||||||
|
|||||||
@ -401,6 +401,58 @@ a[href="javascript:;"] {
|
|||||||
.summary {
|
.summary {
|
||||||
text-decoration: none;
|
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;
|
||||||
|
}
|
||||||
|
.catalog-thread > a {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.thumb {
|
||||||
|
max-width: 150px;
|
||||||
|
max-height: 150px;
|
||||||
|
border-radius: 2px;
|
||||||
|
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;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: .8;
|
||||||
|
margin-top: 1px;
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
.catalog-thread .subject {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
/* Announcement Hiding */
|
/* Announcement Hiding */
|
||||||
:root.hide-announcement #globalMessage,
|
:root.hide-announcement #globalMessage,
|
||||||
@ -597,6 +649,10 @@ a.hide-announcement {
|
|||||||
.filter-highlight > .reply {
|
.filter-highlight > .reply {
|
||||||
box-shadow: -5px 0 rgba(255, 0, 0, .5);
|
box-shadow: -5px 0 rgba(255, 0, 0, .5);
|
||||||
}
|
}
|
||||||
|
.pinned .thumb,
|
||||||
|
.filter-highlight .thumb {
|
||||||
|
border: 2px solid rgba(255, 0, 0, .5);
|
||||||
|
}
|
||||||
|
|
||||||
/* Thread & Reply Hiding */
|
/* Thread & Reply Hiding */
|
||||||
.hide-thread-button,
|
.hide-thread-button,
|
||||||
|
|||||||
9
html/General/Thread-catalog-view.html
Normal file
9
html/General/Thread-catalog-view.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<a href="/#{thread.board}/res/#{thread.ID}" target="_blank">
|
||||||
|
<img src="#{src}" class="thumb #{imgClass or ''}" #{if imgWidth then "width='#{imgWidth}'"} #{if imgHeight then "height='#{imgHeight}'"}>
|
||||||
|
<div class="thread-icons"></div>
|
||||||
|
</a>
|
||||||
|
<div class="thread-stats" title="Post count / File count / Page count">
|
||||||
|
<span class="post-count">#{postCount}</span> / <span class="file-count">#{fileCount}</span> / <span class="page-count">#{pageCount}</span>
|
||||||
|
</div>
|
||||||
|
#{subject}
|
||||||
|
<div class="comment">#{comment}</div>
|
||||||
@ -110,6 +110,8 @@ Filter =
|
|||||||
|
|
||||||
# Highlight
|
# Highlight
|
||||||
$.addClass @nodes.root, result.class
|
$.addClass @nodes.root, result.class
|
||||||
|
unless @highlights and result.class in @highlights
|
||||||
|
(@highlights or= []).push result.class
|
||||||
if !@isReply and result.top
|
if !@isReply and result.top
|
||||||
@thread.isOnTop = true
|
@thread.isOnTop = true
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
ThreadHiding =
|
ThreadHiding =
|
||||||
init: ->
|
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'
|
@db = new DataBoard 'hiddenThreads'
|
||||||
@syncCatalog()
|
@syncCatalog()
|
||||||
$.on d, 'IndexBuild', @onIndexBuild
|
$.on d, 'IndexRefresh', @onIndexRefresh
|
||||||
Thread.callbacks.push
|
Thread.callbacks.push
|
||||||
name: 'Thread Hiding'
|
name: 'Thread Hiding'
|
||||||
cb: @node
|
cb: @node
|
||||||
@ -15,8 +15,8 @@ ThreadHiding =
|
|||||||
return unless Conf['Thread Hiding']
|
return unless Conf['Thread Hiding']
|
||||||
$.prepend @OP.nodes.root, ThreadHiding.makeButton @, 'hide'
|
$.prepend @OP.nodes.root, ThreadHiding.makeButton @, 'hide'
|
||||||
|
|
||||||
onIndexBuild: ({detail: nodes}) ->
|
onIndexRefresh: ->
|
||||||
for root, i in nodes by 2
|
for root, i in Index.nodes by 2
|
||||||
thread = Get.threadFromRoot root
|
thread = Get.threadFromRoot root
|
||||||
continue unless thread.isHidden
|
continue unless thread.isHidden
|
||||||
unless thread.stub
|
unless thread.stub
|
||||||
|
|||||||
@ -254,9 +254,69 @@ Build =
|
|||||||
[posts, files] = if Conf['Show Replies']
|
[posts, files] = if Conf['Show Replies']
|
||||||
[data.omitted_posts, data.omitted_images]
|
[data.omitted_posts, data.omitted_images]
|
||||||
else
|
else
|
||||||
# XXX data.images is not accurate.
|
[data.replies, data.images]
|
||||||
[data.replies, data.omitted_images + data.last_replies.filter((data) -> !!data.ext).length]
|
|
||||||
nodes.push Build.summary board.ID, data.no, posts, files
|
nodes.push Build.summary board.ID, data.no, posts, files
|
||||||
|
|
||||||
$.add root, nodes
|
$.add root, nodes
|
||||||
root
|
root
|
||||||
|
catalogThread: (thread) ->
|
||||||
|
{staticPath, gifIcon} = Build
|
||||||
|
data = Index.liveThreadData[Index.liveThreadIDs.indexOf thread.ID]
|
||||||
|
|
||||||
|
if data.spoiler and !Conf['Reveal Spoilers']
|
||||||
|
src = "#{staticPath}spoiler"
|
||||||
|
if spoilerRange = Build.spoilerRange[thread.board]
|
||||||
|
# Randomize the spoiler image.
|
||||||
|
src += "-#{thread.board}" + Math.floor 1 + spoilerRange * Math.random()
|
||||||
|
src += '.png'
|
||||||
|
imgClass = 'spoiler-file'
|
||||||
|
else if data.filedeleted
|
||||||
|
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
|
||||||
|
pageCount = Math.floor Index.liveThreadIDs.indexOf(thread.ID) / Index.threadsNumPerPage
|
||||||
|
|
||||||
|
subject = if thread.OP.info.subject
|
||||||
|
"<div class='subject'>#{thread.OP.info.subject}</div>"
|
||||||
|
else
|
||||||
|
''
|
||||||
|
comment = thread.OP.nodes.comment.innerHTML.replace /(<br>){2,}/g, '<br>'
|
||||||
|
|
||||||
|
root = $.el 'div',
|
||||||
|
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
|
||||||
|
|
||||||
|
for quotelink in $$ '.quotelink', root.lastElementChild
|
||||||
|
$.replace quotelink, [quotelink.childNodes...]
|
||||||
|
|
||||||
|
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
|
||||||
|
$.addClass $('.file-count', root), 'warning'
|
||||||
|
|
||||||
|
root
|
||||||
|
|||||||
14
src/General/CatalogThread.coffee
Normal file
14
src/General/CatalogThread.coffee
Normal file
@ -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 = @
|
||||||
@ -1,5 +1,5 @@
|
|||||||
class DataBoard
|
class DataBoard
|
||||||
@keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads']
|
@keys = ['pinnedThreads', 'hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads']
|
||||||
|
|
||||||
constructor: (@key, sync, dontClean) ->
|
constructor: (@key, sync, dontClean) ->
|
||||||
@data = Conf[key]
|
@data = Conf[key]
|
||||||
|
|||||||
@ -1,7 +1,25 @@
|
|||||||
Index =
|
Index =
|
||||||
init: ->
|
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'
|
return if g.VIEW isnt 'index' or g.BOARD.ID is 'f'
|
||||||
|
|
||||||
|
@db = new DataBoard 'pinnedThreads'
|
||||||
|
Thread.callbacks.push
|
||||||
|
name: 'Thread Pinning'
|
||||||
|
cb: @threadNode
|
||||||
|
CatalogThread.callbacks.push
|
||||||
|
name: 'Catalog Features'
|
||||||
|
cb: @catalogNode
|
||||||
|
|
||||||
@button = $.el 'a',
|
@button = $.el 'a',
|
||||||
className: 'index-refresh-shortcut fa fa-refresh'
|
className: 'index-refresh-shortcut fa fa-refresh'
|
||||||
title: 'Refresh Index'
|
title: 'Refresh Index'
|
||||||
@ -14,6 +32,7 @@ Index =
|
|||||||
subEntries: [
|
subEntries: [
|
||||||
{ el: $.el 'label', innerHTML: '<input type=radio name="Index Mode" value="paged"> Paged' }
|
{ el: $.el 'label', innerHTML: '<input type=radio name="Index Mode" value="paged"> Paged' }
|
||||||
{ el: $.el 'label', innerHTML: '<input type=radio name="Index Mode" value="all pages"> All threads' }
|
{ el: $.el 'label', innerHTML: '<input type=radio name="Index Mode" value="all pages"> All threads' }
|
||||||
|
{ el: $.el 'label', innerHTML: '<input type=radio name="Index Mode" value="catalog"> Catalog' }
|
||||||
]
|
]
|
||||||
for label in modeEntry.subEntries
|
for label in modeEntry.subEntries
|
||||||
input = label.el.firstChild
|
input = label.el.firstChild
|
||||||
@ -68,6 +87,7 @@ Index =
|
|||||||
$.addClass doc, 'index-loading'
|
$.addClass doc, 'index-loading'
|
||||||
@update()
|
@update()
|
||||||
@root = $.el 'div', className: 'board'
|
@root = $.el 'div', className: 'board'
|
||||||
|
Index.cb.rootClass()
|
||||||
@pagelist = $.el 'div',
|
@pagelist = $.el 'div',
|
||||||
className: 'pagelist'
|
className: 'pagelist'
|
||||||
hidden: true
|
hidden: true
|
||||||
@ -100,8 +120,44 @@ Index =
|
|||||||
$.asap (-> $('.pagelist') or d.readyState isnt 'loading'), ->
|
$.asap (-> $('.pagelist') or d.readyState isnt 'loading'), ->
|
||||||
$.replace $('.pagelist'), Index.pagelist
|
$.replace $('.pagelist'), Index.pagelist
|
||||||
|
|
||||||
|
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()
|
||||||
|
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:
|
cb:
|
||||||
|
rootClass: ->
|
||||||
|
(if Conf['Index Mode'] is 'catalog' then $.addClass else $.rmClass) Index.root, 'catalog-mode'
|
||||||
mode: ->
|
mode: ->
|
||||||
|
Index.cb.rootClass()
|
||||||
Index.togglePagelist()
|
Index.togglePagelist()
|
||||||
Index.buildIndex()
|
Index.buildIndex()
|
||||||
sort: ->
|
sort: ->
|
||||||
@ -289,6 +345,8 @@ Index =
|
|||||||
Index.nodes.push threadRoot, $.el 'hr'
|
Index.nodes.push threadRoot, $.el 'hr'
|
||||||
if thread = g.BOARD.threads[threadData.no]
|
if thread = g.BOARD.threads[threadData.no]
|
||||||
thread.setPage Math.floor i / Index.threadsNumPerPage
|
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 'Sticky', !!threadData.sticky
|
||||||
thread.setStatus 'Closed', !!threadData.closed
|
thread.setStatus 'Closed', !!threadData.closed
|
||||||
else
|
else
|
||||||
@ -334,6 +392,16 @@ Index =
|
|||||||
|
|
||||||
Main.handleErrors errors if errors
|
Main.handleErrors errors if errors
|
||||||
Main.callbackNodes Post, posts
|
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: ->
|
sort: ->
|
||||||
switch Conf['Index Sort']
|
switch Conf['Index Sort']
|
||||||
when 'bump'
|
when 'bump'
|
||||||
@ -368,16 +436,19 @@ Index =
|
|||||||
Index.sortedNodes.splice offset++ * 2, 0, Index.sortedNodes.splice(i, 2)...
|
Index.sortedNodes.splice offset++ * 2, 0, Index.sortedNodes.splice(i, 2)...
|
||||||
return
|
return
|
||||||
buildIndex: ->
|
buildIndex: ->
|
||||||
if Conf['Index Mode'] is 'paged'
|
switch Conf['Index Mode']
|
||||||
pageNum = Index.getCurrentPage()
|
when 'paged'
|
||||||
nodesPerPage = Index.threadsNumPerPage * 2
|
pageNum = Index.getCurrentPage()
|
||||||
nodes = Index.sortedNodes[nodesPerPage * pageNum ... nodesPerPage * (pageNum + 1)]
|
nodesPerPage = Index.threadsNumPerPage * 2
|
||||||
else
|
nodes = Index.sortedNodes[nodesPerPage * pageNum ... nodesPerPage * (pageNum + 1)]
|
||||||
nodes = Index.sortedNodes
|
when 'catalog'
|
||||||
|
nodes = Index.buildCatalogViews()
|
||||||
|
else
|
||||||
|
nodes = Index.sortedNodes
|
||||||
$.rmAll Index.root
|
$.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
|
$.add Index.root, nodes
|
||||||
|
$.event 'IndexBuild', nodes
|
||||||
|
|
||||||
isSearching: false
|
isSearching: false
|
||||||
clearSearch: ->
|
clearSearch: ->
|
||||||
|
|||||||
@ -10,13 +10,21 @@ class Thread
|
|||||||
@postLimit = false
|
@postLimit = false
|
||||||
@fileLimit = false
|
@fileLimit = false
|
||||||
|
|
||||||
|
@OP = null
|
||||||
|
@catalogView = null
|
||||||
|
|
||||||
g.threads[@fullID] = board.threads[@] = @
|
g.threads[@fullID] = board.threads[@] = @
|
||||||
|
|
||||||
setPage: (pageNum) ->
|
setPage: (pageNum) ->
|
||||||
icon = $ '.page-num', @OP.nodes.post
|
icon = $ '.page-num', @OP.nodes.post
|
||||||
for key in ['title', 'textContent']
|
for key in ['title', 'textContent']
|
||||||
icon[key] = icon[key].replace /\d+/, pageNum
|
icon[key] = icon[key].replace /\d+/, pageNum
|
||||||
return
|
@catalogView.nodes.pageCount.textContent = pageNum if @catalogView
|
||||||
|
setCount: (type, count, reachedLimit) ->
|
||||||
|
return unless @catalogView
|
||||||
|
el = @catalogView.nodes["#{type}Count"]
|
||||||
|
el.textContent = count
|
||||||
|
(if reachedLimit then $.addClass else $.rmClass) el, 'warning'
|
||||||
setStatus: (type, status) ->
|
setStatus: (type, status) ->
|
||||||
name = "is#{type}"
|
name = "is#{type}"
|
||||||
return if @[name] is status
|
return if @[name] is status
|
||||||
@ -25,20 +33,33 @@ class Thread
|
|||||||
typeLC = type.toLowerCase()
|
typeLC = type.toLowerCase()
|
||||||
unless status
|
unless status
|
||||||
$.rm $ ".#{typeLC}Icon", @OP.nodes.info
|
$.rm $ ".#{typeLC}Icon", @OP.nodes.info
|
||||||
|
$.rm $ ".#{typeLC}Icon", @catalogView if @catalogView
|
||||||
return
|
return
|
||||||
|
|
||||||
icon = $.el 'img',
|
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
|
alt: type
|
||||||
title: type
|
title: type
|
||||||
className: "#{typeLC}Icon"
|
className: "#{typeLC}Icon"
|
||||||
root = if type is 'Closed' and @isSticky
|
root = if type is 'Closed' and @isSticky
|
||||||
$ '.stickyIcon', @OP.nodes.info
|
$ '.stickyIcon', @OP.nodes.info
|
||||||
else if g.VIEW is 'index'
|
else if g.VIEW is 'index'
|
||||||
$ '.page-num', @OP.nodes.info
|
$ '.page-num', @OP.nodes.info
|
||||||
else
|
else
|
||||||
$ '[title="Quote this post"]', @OP.nodes.info
|
$ '[title="Quote this post"]', @OP.nodes.info
|
||||||
$.after root, [$.tn(' '), icon]
|
$.after root, [$.tn(' '), icon]
|
||||||
|
|
||||||
|
return unless @catalogView
|
||||||
|
root = $ '.thread-icons', @catalogView
|
||||||
|
(if type is 'Sticky' and @isClosed then $.prepend else $.add) root, icon.cloneNode()
|
||||||
|
|
||||||
|
pin: ->
|
||||||
|
@isOnTop = @isPinned = true
|
||||||
|
$.addClass @catalogView.nodes.root, 'pinned' if @catalogView
|
||||||
|
unpin: ->
|
||||||
|
@isOnTop = @isPinned = false
|
||||||
|
$.rmClass @catalogView.nodes.root, 'pinned' if @catalogView
|
||||||
|
|
||||||
kill: ->
|
kill: ->
|
||||||
@isDead = true
|
@isDead = true
|
||||||
@timeOfDeath = Date.now()
|
@timeOfDeath = Date.now()
|
||||||
|
|||||||
@ -5,6 +5,9 @@ AutoGIF =
|
|||||||
Post.callbacks.push
|
Post.callbacks.push
|
||||||
name: 'Auto-GIF'
|
name: 'Auto-GIF'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
CatalogThread.callbacks.push
|
||||||
|
name: 'Auto-GIF'
|
||||||
|
cb: @catalogNode
|
||||||
node: ->
|
node: ->
|
||||||
return if @isClone or @isHidden or @thread.isHidden or !@file?.isImage
|
return if @isClone or @isHidden or @thread.isHidden or !@file?.isImage
|
||||||
{thumb, URL} = @file
|
{thumb, URL} = @file
|
||||||
@ -13,8 +16,17 @@ AutoGIF =
|
|||||||
# Revealed spoilers do not have height/width set, this fixes auto-gifs dimensions.
|
# Revealed spoilers do not have height/width set, this fixes auto-gifs dimensions.
|
||||||
{style} = thumb
|
{style} = thumb
|
||||||
style.maxHeight = style.maxWidth = if @isReply then '125px' else '250px'
|
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'
|
gif = $.el 'img'
|
||||||
$.on gif, 'load', ->
|
$.on gif, 'load', ->
|
||||||
# Replace the thumbnail once the GIF has finished loading.
|
# Replace the thumbnail once the GIF has finished loading.
|
||||||
thumb.src = URL
|
thumb.src = URL
|
||||||
gif.src = URL
|
gif.src = URL
|
||||||
|
|
||||||
|
|||||||
@ -5,11 +5,20 @@ ImageHover =
|
|||||||
Post.callbacks.push
|
Post.callbacks.push
|
||||||
name: 'Image Hover'
|
name: 'Image Hover'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
CatalogThread.callbacks.push
|
||||||
|
name: 'Image Hover'
|
||||||
|
cb: @catalogNode
|
||||||
node: ->
|
node: ->
|
||||||
return unless @file?.isImage
|
return unless @file?.isImage
|
||||||
$.on @file.thumb, 'mouseover', ImageHover.mouseover
|
$.on @file.thumb, 'mouseover', ImageHover.mouseover
|
||||||
|
catalogNode: ->
|
||||||
|
return unless @thread.OP.file?.isImage
|
||||||
|
$.on @nodes.thumb, 'mouseover', ImageHover.mouseover
|
||||||
mouseover: (e) ->
|
mouseover: (e) ->
|
||||||
post = Get.postFromNode @
|
post = if $.hasClass @, 'thumb'
|
||||||
|
g.posts[@parentNode.parentNode.dataset.fullID]
|
||||||
|
else
|
||||||
|
Get.postFromNode @
|
||||||
el = $.el 'img',
|
el = $.el 'img',
|
||||||
id: 'ihover'
|
id: 'ihover'
|
||||||
src: post.file.URL
|
src: post.file.URL
|
||||||
|
|||||||
@ -72,9 +72,8 @@ ThreadWatcher =
|
|||||||
else if Conf['Auto Watch Reply']
|
else if Conf['Auto Watch Reply']
|
||||||
ThreadWatcher.add board.threads[threadID]
|
ThreadWatcher.add board.threads[threadID]
|
||||||
onIndexRefresh: ->
|
onIndexRefresh: ->
|
||||||
{db} = ThreadWatcher
|
|
||||||
boardID = g.BOARD.ID
|
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']
|
if Conf['Auto Prune']
|
||||||
ThreadWatcher.db.delete {boardID, threadID}
|
ThreadWatcher.db.delete {boardID, threadID}
|
||||||
else
|
else
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user