4chan-x/src/Miscellaneous/ExpandThread.coffee

124 lines
4.1 KiB
CoffeeScript

ExpandThread =
statuses: {}
init: ->
return if not (g.VIEW is 'index' and Conf['Thread Expansion'])
if Conf['JSON Index']
$.on d, 'IndexRefreshInternal', @onIndexRefresh
else
Callbacks.Thread.push
name: 'Expand Thread'
cb: -> ExpandThread.setButton @
setButton: (thread) ->
return if not (thread.nodes.root and (a = $ '.summary', thread.nodes.root))
a.textContent = Build.summaryText '+', a.textContent.match(/\d+/g)...
a.style.cursor = 'pointer'
$.on a, 'click', ExpandThread.cbToggle
disconnect: (refresh) ->
return if g.VIEW is 'thread' or !Conf['Thread Expansion']
for threadID, status of ExpandThread.statuses
status.req?.abort()
delete ExpandThread.statuses[threadID]
$.off d, 'IndexRefreshInternal', @onIndexRefresh unless refresh
onIndexRefresh: ->
ExpandThread.disconnect true
g.BOARD.threads.forEach (thread) ->
ExpandThread.setButton thread
cbToggle: (e) ->
return if $.modifiedClick e
e.preventDefault()
ExpandThread.toggle Get.threadFromNode @
cbToggleBottom: (e) ->
return if $.modifiedClick e
e.preventDefault()
thread = Get.threadFromNode @
$.rm @ # remove before fixing bottom of thread position
{bottom} = thread.nodes.root.getBoundingClientRect()
ExpandThread.toggle thread
window.scrollBy 0, (thread.nodes.root.getBoundingClientRect().bottom - bottom)
toggle: (thread) ->
return if not (thread.nodes.root and (a = $ '.summary', thread.nodes.root))
if thread.ID of ExpandThread.statuses
ExpandThread.contract thread, a, thread.nodes.root
else
ExpandThread.expand thread, a
expand: (thread, a) ->
ExpandThread.statuses[thread] = status = {}
a.textContent = Build.summaryText '...', a.textContent.match(/\d+/g)...
status.req = $.cache "#{location.protocol}//a.4cdn.org/#{thread.board}/thread/#{thread}.json", ->
delete status.req
ExpandThread.parse @, thread, a
contract: (thread, a, threadRoot) ->
status = ExpandThread.statuses[thread]
delete ExpandThread.statuses[thread]
if status.req
status.req.abort()
a.textContent = Build.summaryText '+', a.textContent.match(/\d+/g)... if a
return
replies = $$ '.thread > .replyContainer', threadRoot
if !Conf['JSON Index'] or Conf['Show Replies']
num = if thread.isSticky
1
else switch g.BOARD.ID
# XXX boards config
when 'b', 'vg', 'bant' then 3
when 't' then 1
else 5
replies = replies[...-num]
postsCount = 0
filesCount = 0
for reply in replies
# rm clones
inlined.click() while inlined = $ '.inlined', reply if Conf['Quote Inlining']
postsCount++
filesCount++ if 'file' of Get.postFromRoot reply
$.rm reply
if Index.enabled # otherwise handled by Main.addPosts
$.event 'PostsRemoved', null, a.parentNode
a.textContent = Build.summaryText '+', postsCount, filesCount
$.rm $('.summary-bottom', threadRoot)
parse: (req, thread, a) ->
if req.status not in [200, 304]
a.textContent = "Error #{req.statusText} (#{req.status})"
return
Build.spoilerRange[thread.board] = req.response.posts[0].custom_spoiler
posts = []
postsRoot = []
filesCount = 0
for postData in req.response.posts
continue if postData.no is thread.ID
if (post = thread.posts[postData.no]) and not post.isFetchedQuote
filesCount++ if 'file' of post
{root} = post.nodes
postsRoot.push root
continue
root = Build.postFromObject postData, thread.board.ID
post = new Post root, thread, thread.board
filesCount++ if 'file' of post
posts.push post
postsRoot.push root
Main.callbackNodes 'Post', posts
$.after a, postsRoot
$.event 'PostsInserted', null, a.parentNode
postsCount = postsRoot.length
a.textContent = Build.summaryText '-', postsCount, filesCount
if root
a2 = a.cloneNode true
a2.classList.add 'summary-bottom'
$.on a2, 'click', ExpandThread.cbToggleBottom
$.after root, a2