Add Unread Line in Index option, combined with previous work on Mark Read button. #625
Also fix various bugs with the old implementation.
This commit is contained in:
parent
96cae8339a
commit
481a775a80
@ -691,6 +691,10 @@ Index =
|
||||
isHiddenReply: (threadID, replyData) ->
|
||||
PostHiding.isHidden(g.BOARD.ID, threadID, replyData.no) or Filter.isHidden(Build.parseJSON replyData, g.BOARD.ID)
|
||||
|
||||
lastPost: (threadID) ->
|
||||
threadData = Index.liveThreadDict[threadID]
|
||||
if threadData?.last_replies then threadData.last_replies[threadData.last_replies.length - 1].no else threadID
|
||||
|
||||
buildThreads: (threadIDs, isCatalog, withReplies) ->
|
||||
threads = []
|
||||
newThreads = []
|
||||
@ -713,7 +717,6 @@ Index =
|
||||
thread = new Thread ID, g.BOARD
|
||||
newThreads.push thread
|
||||
thread.json = threadData
|
||||
thread.lastPost = if threadData.last_replies then threadData.last_replies[threadData.last_replies.length - 1].no else ID
|
||||
threads.push thread
|
||||
|
||||
if ((OP = thread.OP) and not OP.isFetchedQuote)
|
||||
@ -741,7 +744,7 @@ Index =
|
||||
Main.callbackNodes 'Thread', newThreads
|
||||
Main.callbackNodes 'Post', newPosts
|
||||
Index.updateHideLabel()
|
||||
$.event 'IndexRefreshInternal'
|
||||
$.event 'IndexRefreshInternal', {threadIDs: (t.fullID for t in threads), isCatalog}
|
||||
|
||||
threads
|
||||
|
||||
|
||||
@ -68,6 +68,8 @@ ExpandThread =
|
||||
postsCount = 0
|
||||
filesCount = 0
|
||||
for reply in replies
|
||||
# rm elements above post such as unread line
|
||||
$.rm node while (node = a.nextSibling) and node isnt reply
|
||||
# rm clones
|
||||
inlined.click() while inlined = $ '.inlined', reply if Conf['Quote Inlining']
|
||||
postsCount++
|
||||
|
||||
@ -15,6 +15,7 @@ Unread =
|
||||
|
||||
@hr = $.el 'hr',
|
||||
id: 'unread-line'
|
||||
className: 'unread-line'
|
||||
@posts = new Set()
|
||||
@postsQuotingYou = new Set()
|
||||
@order = new RandomAccessList()
|
||||
|
||||
@ -1,69 +1,109 @@
|
||||
UnreadIndex =
|
||||
hasUnread: {}
|
||||
lastReadPost: {}
|
||||
hr: {}
|
||||
markReadLink: {}
|
||||
|
||||
init: ->
|
||||
return unless g.VIEW is 'index' and Conf['Remember Last Read Post'] and Conf['Mark Read from Index']
|
||||
return unless g.VIEW is 'index' and Conf['Remember Last Read Post'] and Conf['Unread Line in Index']
|
||||
|
||||
@db = new DataBoard 'lastReadPosts', @sync
|
||||
|
||||
if Index.enabled
|
||||
$.on d, 'IndexRefreshInternal',
|
||||
@onIndexRefresh
|
||||
else
|
||||
Callbacks.Thread.push
|
||||
name: 'Mark Read from Index'
|
||||
cb: @node
|
||||
Callbacks.Thread.push
|
||||
name: 'Unread Line in Index'
|
||||
cb: @node
|
||||
|
||||
Callbacks.Post.push
|
||||
name: 'Mark Read from Index'
|
||||
cb: @addPost
|
||||
|
||||
onIndexRefresh: ->
|
||||
g.threads.forEach (thread) ->
|
||||
UnreadIndex.addMarkReadLink thread
|
||||
UnreadIndex.update thread
|
||||
$.on d, 'IndexRefreshInternal', @onIndexRefresh
|
||||
$.on d, 'PostsInserted', @onPostsInserted
|
||||
|
||||
node: ->
|
||||
UnreadIndex.addMarkReadLink @
|
||||
UnreadIndex.update @
|
||||
UnreadIndex.lastReadPost[@fullID] = UnreadIndex.db.get(
|
||||
boardID: @board.ID
|
||||
threadID: @ID
|
||||
) or 0
|
||||
if !Index.enabled # let onIndexRefresh handle JSON Index
|
||||
UnreadIndex.update @
|
||||
|
||||
addPost: ->
|
||||
if @ID is @thread.lastPost
|
||||
UnreadIndex.update @thread
|
||||
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
|
||||
UnreadIndex.update thread
|
||||
|
||||
sync: ->
|
||||
g.threads.forEach UnreadIndex.update
|
||||
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)
|
||||
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
|
||||
|
||||
addMarkReadLink: (thread) ->
|
||||
return unless thread.nodes.root
|
||||
link = UnreadIndex.markReadLink[thread.fullID]
|
||||
unless link
|
||||
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 link.parentNode isnt thread.nodes.root
|
||||
if (divider = $ Site.selectors.threadDivider, thread.nodes.root) # divider inside thread as in Tinyboard
|
||||
$.before divider, link
|
||||
else
|
||||
$.add thread.nodes.root, link
|
||||
|
||||
update: (thread) ->
|
||||
return unless thread.nodes.root
|
||||
lastReadPost = UnreadIndex.db.get(
|
||||
boardID: thread.board.ID
|
||||
threadID: thread.ID
|
||||
) or 0
|
||||
hasUnread = (lastReadPost < thread.lastPost)
|
||||
if hasUnread isnt UnreadIndex.hasUnread[thread.fullID]
|
||||
thread.nodes.root.classList.toggle 'unread-thread', hasUnread
|
||||
|
||||
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: thread.lastPost
|
||||
UnreadIndex.update thread
|
||||
val: lastPost
|
||||
$.rm UnreadIndex.hr[thread.fullID]
|
||||
$.rm UnreadIndex.markReadLink[thread.fullID]
|
||||
ThreadWatcher.update thread.board.ID, thread.ID,
|
||||
unread: 0
|
||||
quotingYou: false
|
||||
|
||||
@ -61,7 +61,6 @@ class Post
|
||||
|
||||
@board.posts.push @ID, @
|
||||
@thread.posts.push @ID, @
|
||||
@thread.lastPost = @ID if @ID > @thread.lastPost
|
||||
g.posts.push @fullID, @
|
||||
|
||||
parseNodes: (root) ->
|
||||
|
||||
@ -13,14 +13,12 @@ class Thread
|
||||
@fileLimit = false
|
||||
@ipCount = undefined
|
||||
@json = null
|
||||
@lastPost = 0
|
||||
|
||||
@OP = null
|
||||
@catalogView = null
|
||||
|
||||
@nodes =
|
||||
root: null
|
||||
summary: null
|
||||
root: null
|
||||
|
||||
@board.threads.push @ID, @
|
||||
g.threads.push @fullID, @
|
||||
|
||||
@ -383,9 +383,9 @@ Config =
|
||||
'Scroll back to the last read post when reopening a thread.'
|
||||
1
|
||||
]
|
||||
'Mark Read from Index': [
|
||||
'Unread Line in Index': [
|
||||
false
|
||||
'Add links in the index for marking threads read.'
|
||||
'Show a line between read and unread posts in threads in the index.'
|
||||
1
|
||||
]
|
||||
'Remove Thread Excerpt': [
|
||||
|
||||
@ -147,7 +147,7 @@
|
||||
}
|
||||
|
||||
/* Unread */
|
||||
:root.spooky #unread-line {
|
||||
:root.spooky .unread-line {
|
||||
border-color: rgb(197, 200, 198);
|
||||
}
|
||||
|
||||
|
||||
@ -1059,7 +1059,7 @@ span.hide-announcement {
|
||||
}
|
||||
|
||||
/* Unread */
|
||||
#unread-line {
|
||||
.unread-line {
|
||||
margin: 0;
|
||||
border-color: rgb(255,0,0);
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@
|
||||
}
|
||||
|
||||
/* Unread */
|
||||
:root.tomorrow #unread-line {
|
||||
:root.tomorrow .unread-line {
|
||||
border-color: rgb(197, 200, 198);
|
||||
}
|
||||
|
||||
|
||||
@ -510,7 +510,7 @@ Main =
|
||||
['Thread Expansion', ExpandThread]
|
||||
['Favicon', Favicon]
|
||||
['Unread', Unread]
|
||||
['Mark Read from Index', UnreadIndex]
|
||||
['Unread Line in Index', UnreadIndex]
|
||||
['Quote Threading', QuoteThreading]
|
||||
['Thread Stats', ThreadStats]
|
||||
['Thread Updater', ThreadUpdater]
|
||||
|
||||
@ -53,6 +53,7 @@ SW.tinyboard =
|
||||
selectors:
|
||||
board: 'form[name="postcontrols"]'
|
||||
thread: 'div[id^="thread_"]'
|
||||
threadDivider: 'div[id^="thread_"] > hr:last-of-type'
|
||||
postContainer: '.reply' # postContainer is thread for OP
|
||||
infoRoot: '.intro'
|
||||
info:
|
||||
|
||||
@ -7,6 +7,7 @@ SW.yotsuba =
|
||||
selectors:
|
||||
board: '.board'
|
||||
thread: '.thread'
|
||||
threadDivider: '.board > hr'
|
||||
postContainer: '.postContainer'
|
||||
sideArrows: '.sideArrows'
|
||||
post: '.post'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user