diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 910959084..82c444fe9 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -713,6 +713,7 @@ 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) diff --git a/src/Monitoring/ThreadWatcher.coffee b/src/Monitoring/ThreadWatcher.coffee index 10a407c4a..87feb0800 100644 --- a/src/Monitoring/ThreadWatcher.coffee +++ b/src/Monitoring/ThreadWatcher.coffee @@ -16,7 +16,7 @@ ThreadWatcher = @list = @dialog.lastElementChild @refreshButton = $ '.refresh', @dialog @closeButton = $('.move > .close', @dialog) - @unreaddb = Unread.db or new DataBoard 'lastReadPosts' + @unreaddb = Unread.db or UnreadIndex.db or new DataBoard 'lastReadPosts' @unreadEnabled = Conf['Remember Last Read Post'] and Site.software is 'yotsuba' $.on d, 'QRPostSuccessful', @cb.post diff --git a/src/Monitoring/UnreadIndex.coffee b/src/Monitoring/UnreadIndex.coffee new file mode 100644 index 000000000..2f77921b3 --- /dev/null +++ b/src/Monitoring/UnreadIndex.coffee @@ -0,0 +1,69 @@ +UnreadIndex = + hasUnread: {} + markReadLink: {} + + init: -> + return unless g.VIEW is 'index' and Conf['Remember Last Read Post'] and Conf['Mark Read from 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.Post.push + name: 'Mark Read from Index' + cb: @addPost + + onIndexRefresh: -> + g.threads.forEach (thread) -> + UnreadIndex.addMarkReadLink thread + UnreadIndex.update thread + + node: -> + UnreadIndex.addMarkReadLink @ + UnreadIndex.update @ + + addPost: -> + if @ID is @thread.lastPost + UnreadIndex.update @thread + + sync: -> + g.threads.forEach UnreadIndex.update + + addMarkReadLink: (thread) -> + return unless thread.nodes.root + link = UnreadIndex.markReadLink[thread.fullID] + unless 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 + $.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 @ + UnreadIndex.db.set + boardID: thread.board.ID + threadID: thread.ID + val: thread.lastPost + UnreadIndex.update thread + ThreadWatcher.update thread.board.ID, thread.ID, + unread: 0 + quotingYou: false diff --git a/src/classes/Post.coffee b/src/classes/Post.coffee index 74fbe703f..3bfa57212 100644 --- a/src/classes/Post.coffee +++ b/src/classes/Post.coffee @@ -61,6 +61,7 @@ class Post @board.posts.push @ID, @ @thread.posts.push @ID, @ + @thread.lastPost = @ID if @ID > @thread.lastPost g.posts.push @fullID, @ parseNodes: (root) -> diff --git a/src/classes/Thread.coffee b/src/classes/Thread.coffee index d5e05d691..941dce8ae 100644 --- a/src/classes/Thread.coffee +++ b/src/classes/Thread.coffee @@ -13,12 +13,14 @@ class Thread @fileLimit = false @ipCount = undefined @json = null + @lastPost = 0 @OP = null @catalogView = null @nodes = - root: null + root: null + summary: null @board.threads.push @ID, @ g.threads.push @fullID, @ diff --git a/src/config/Config.coffee b/src/config/Config.coffee index 83da402ed..0178367fa 100644 --- a/src/config/Config.coffee +++ b/src/config/Config.coffee @@ -383,6 +383,11 @@ Config = 'Scroll back to the last read post when reopening a thread.' 1 ] + 'Mark Read from Index': [ + false + 'Add links in the index for marking threads read.' + 1 + ] 'Remove Thread Excerpt': [ false 'Replace the excerpt of the thread in the tab title with the board title.' diff --git a/src/css/style.css b/src/css/style.css index 564811ccc..cfef612fd 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -1063,6 +1063,18 @@ span.hide-announcement { margin: 0; border-color: rgb(255,0,0); } +.unread-mark-read { + float: right; + clear: both; + height: 0; + width: 100%; + position: relative; + top: -1em; + text-align: right; +} +:not(.unread-thread) > .unread-mark-read { + visibility: hidden; +} /* Thread Updater */ #updater { diff --git a/src/main/Main.coffee b/src/main/Main.coffee index 7ec67988b..4d1a61e25 100644 --- a/src/main/Main.coffee +++ b/src/main/Main.coffee @@ -510,6 +510,7 @@ Main = ['Thread Expansion', ExpandThread] ['Favicon', Favicon] ['Unread', Unread] + ['Mark Read from Index', UnreadIndex] ['Quote Threading', QuoteThreading] ['Thread Stats', ThreadStats] ['Thread Updater', ThreadUpdater]