4chan-x/src/Monitoring/UnreadIndex.coffee

114 lines
3.7 KiB
CoffeeScript

UnreadIndex =
lastReadPost: {}
hr: {}
markReadLink: {}
init: ->
return unless g.VIEW is 'index' and Conf['Remember Last Read Post'] and Conf['Unread Line in Index']
@enabled = true
@db = new DataBoard 'lastReadPosts', @sync
Callbacks.Thread.push
name: 'Unread Line in Index'
cb: @node
$.on d, 'IndexRefreshInternal', @onIndexRefresh
$.on d, 'PostsInserted', @onPostsInserted
node: ->
UnreadIndex.lastReadPost[@fullID] = UnreadIndex.db.get(
boardID: @board.ID
threadID: @ID
) or 0
if !Index.enabled # let onIndexRefresh handle JSON Index
UnreadIndex.update @
onIndexRefresh: (e) ->
return if e.detail.isCatalog
for threadID in e.detail.threadIDs
thread = g.threads[threadID]
UnreadIndex.update thread
onPostsInserted: (e) ->
return if e.target is Index.root # onIndexRefresh handles this case
thread = Get.threadFromNode e.target
return if !thread or thread.nodes.root isnt e.target
wasVisible = !!UnreadIndex.hr[thread.fullID]?.parentNode
UnreadIndex.update thread
if Conf['Scroll to Last Read Post'] and !wasVisible and !!UnreadIndex.hr[thread.fullID]?.parentNode
Header.scrollToIfNeeded UnreadIndex.hr[thread.fullID], true
sync: ->
g.threads.forEach (thread) ->
lastReadPost = UnreadIndex.db.get(
boardID: thread.board.ID
threadID: thread.ID
) or 0
if lastReadPost isnt UnreadIndex.lastReadPost[thread.fullID]
UnreadIndex.lastReadPost[thread.fullID] = lastReadPost
if thread.nodes.root?.parentNode
UnreadIndex.update thread
update: (thread) ->
lastReadPost = UnreadIndex.lastReadPost[thread.fullID]
repliesShown = 0
repliesRead = 0
firstUnread = null
thread.posts.forEach (post) ->
if post.isReply and post.nodes.root.parentNode is thread.nodes.root
repliesShown++
if post.ID <= lastReadPost
repliesRead++
else if (!firstUnread or post.ID < firstUnread.ID) and !post.isHidden and !QuoteYou.isYou(post)
firstUnread = post
hr = UnreadIndex.hr[thread.fullID]
if firstUnread and (repliesRead or (lastReadPost is thread.OP.ID and (!$(Site.selectors.summary, thread.nodes.root) or thread.ID of ExpandThread.statuses)))
if !hr
hr = UnreadIndex.hr[thread.fullID] = $.el 'hr',
className: 'unread-line'
$.before firstUnread.nodes.root, hr
else
$.rm hr
hasUnread = if repliesShown
firstUnread or !repliesRead
else if Index.enabled
Index.lastPost(thread.ID) > lastReadPost
else
thread.OP.ID > lastReadPost
thread.nodes.root.classList.toggle 'unread-thread', hasUnread
link = UnreadIndex.markReadLink[thread.fullID]
if !link
link = UnreadIndex.markReadLink[thread.fullID] = $.el 'a',
className: 'unread-mark-read brackets-wrap'
href: 'javascript:;'
textContent: 'Mark Read'
$.on link, 'click', UnreadIndex.markRead
if (divider = $ Site.selectors.threadDivider, thread.nodes.root) # divider inside thread as in Tinyboard
$.before divider, link
else
$.add thread.nodes.root, link
markRead: ->
thread = Get.threadFromNode @
if Index.enabled
lastPost = Index.lastPost(thread.ID)
else
lastPost = 0
thread.posts.forEach (post) ->
if post.ID > lastPost and !post.isFetchedQuote
lastPost = post.ID
UnreadIndex.lastReadPost[thread.fullID] = lastPost
UnreadIndex.db.set
boardID: thread.board.ID
threadID: thread.ID
val: lastPost
$.rm UnreadIndex.hr[thread.fullID]
thread.nodes.root.classList.remove 'unread-thread'
ThreadWatcher.update thread.board.ID, thread.ID,
unread: 0
quotingYou: false