Show what pages watched threads are on. #1030
This commit is contained in:
parent
ccf3692944
commit
574d1ad0d3
@ -160,7 +160,7 @@ ThreadWatcher =
|
|||||||
else if ThreadWatcher.unreadEnabled and Conf['Show Unread Count']
|
else if ThreadWatcher.unreadEnabled and Conf['Show Unread Count']
|
||||||
ThreadWatcher.fetchStatus {siteID, boardID, threadID, data}
|
ThreadWatcher.fetchStatus {siteID, boardID, threadID, data}
|
||||||
else
|
else
|
||||||
db.extend {boardID, threadID, val: {isDead: true}}
|
db.extend {boardID, threadID, val: {isDead: true, page: undefined, lastPage: undefined, unread: undefined, quotingYou: undefined}}
|
||||||
nKilled++
|
nKilled++
|
||||||
ThreadWatcher.refresh() if nKilled
|
ThreadWatcher.refresh() if nKilled
|
||||||
onThreadRefresh: (e) ->
|
onThreadRefresh: (e) ->
|
||||||
@ -224,7 +224,7 @@ ThreadWatcher =
|
|||||||
clearTimeout ThreadWatcher.timeout
|
clearTimeout ThreadWatcher.timeout
|
||||||
return unless Conf['Auto Update Thread Watcher']
|
return unless Conf['Auto Update Thread Watcher']
|
||||||
{db} = ThreadWatcher
|
{db} = ThreadWatcher
|
||||||
interval = if ThreadWatcher.unreadEnabled and Conf['Show Unread Count'] then 5 * $.MINUTE else 2 * $.HOUR
|
interval = if Conf['Show Page'] or (ThreadWatcher.unreadEnabled and Conf['Show Unread Count']) then 5 * $.MINUTE else 2 * $.HOUR
|
||||||
now = Date.now()
|
now = Date.now()
|
||||||
unless now - interval < (db.data.lastChecked or 0) <= now or d.hidden or not d.hasFocus()
|
unless now - interval < (db.data.lastChecked or 0) <= now or d.hidden or not d.hasFocus()
|
||||||
ThreadWatcher.fetchAllStatus()
|
ThreadWatcher.fetchAllStatus()
|
||||||
@ -254,40 +254,65 @@ ThreadWatcher =
|
|||||||
deep = !(now - 2 * $.HOUR < (db.data.lastChecked2 or 0) <= now)
|
deep = !(now - 2 * $.HOUR < (db.data.lastChecked2 or 0) <= now)
|
||||||
boards = ThreadWatcher.getAll(true)
|
boards = ThreadWatcher.getAll(true)
|
||||||
for board in boards
|
for board in boards
|
||||||
ThreadWatcher.fetchBoard board, deep
|
ThreadWatcher.fetchBoard board, false, deep
|
||||||
db.setLastChecked()
|
db.setLastChecked()
|
||||||
db.setLastChecked('lastChecked2') if deep
|
db.setLastChecked('lastChecked2') if deep
|
||||||
if ThreadWatcher.fetched is ThreadWatcher.requests.length
|
if ThreadWatcher.fetched is ThreadWatcher.requests.length
|
||||||
ThreadWatcher.clearRequests()
|
ThreadWatcher.clearRequests()
|
||||||
|
|
||||||
fetchBoard: (board, deep) ->
|
fetchBoard: (board, force, deep) ->
|
||||||
return unless board.some (thread) -> !thread.data.isDead
|
return unless board.some (thread) -> !thread.data.isDead
|
||||||
{siteID, boardID} = board[0]
|
{siteID, boardID} = board[0]
|
||||||
software = Conf['siteProperties'][siteID]?.software
|
software = Conf['siteProperties'][siteID]?.software
|
||||||
urlF = if deep and software is 'tinyboard' then 'catalogJSON' else 'threadsListJSON'
|
urlF = if deep and software is 'tinyboard' then 'catalogJSON' else 'threadsListJSON'
|
||||||
url = SW[software]?.urls[urlF]?({siteID, boardID})
|
url = SW[software]?.urls[urlF]?({siteID, boardID})
|
||||||
return unless url
|
return unless url
|
||||||
ThreadWatcher.fetch url, {siteID}, [board, url], ThreadWatcher.parseBoard
|
ThreadWatcher.fetch url, {siteID, force}, [board, url], ThreadWatcher.parseBoard
|
||||||
|
|
||||||
parseBoard: (board, url) ->
|
parseBoard: (board, url) ->
|
||||||
return unless @status is 200
|
return unless @status is 200
|
||||||
{siteID, boardID} = board[0]
|
{siteID, boardID} = board[0]
|
||||||
|
software = Conf['siteProperties'][siteID]?.software
|
||||||
lmDate = @getResponseHeader('Last-Modified')
|
lmDate = @getResponseHeader('Last-Modified')
|
||||||
ThreadWatcher.dbLM.extend {siteID, boardID, val: $.item(url, lmDate)}
|
ThreadWatcher.dbLM.extend {siteID, boardID, val: $.item(url, lmDate)}
|
||||||
modified = {}
|
threads = {}
|
||||||
replies = {}
|
pageLength = 0
|
||||||
|
nThreads = 0
|
||||||
|
oldest = null
|
||||||
try
|
try
|
||||||
for page in @response
|
pageLength = @response[0]?.threads.length or 0
|
||||||
|
for page, i in @response
|
||||||
for item in page.threads
|
for item in page.threads
|
||||||
modified[item.no] = item.last_modified
|
threads[item.no] =
|
||||||
replies[item.no] = item.replies
|
page: i + 1
|
||||||
|
index: nThreads
|
||||||
|
modified: item.last_modified
|
||||||
|
replies: item.replies
|
||||||
|
nThreads++
|
||||||
|
if !oldest? or item.no < oldest
|
||||||
|
oldest = item.no
|
||||||
|
catch
|
||||||
|
for thread in board
|
||||||
|
ThreadWatcher.fetchStatus thread
|
||||||
for thread in board
|
for thread in board
|
||||||
{threadID, data} = thread
|
{threadID, data} = thread
|
||||||
if modified[threadID]
|
if threads[threadID]
|
||||||
if modified[threadID] is data.modified and (!replies[threadID]? or replies[threadID] is data.replies)
|
{page, index, modified, replies} = threads[threadID]
|
||||||
continue
|
if Conf['Show Page']
|
||||||
ThreadWatcher.db.extend {siteID, boardID, threadID, val: {modified: modified[threadID]}}
|
lastPage = if SW[software]?.isPrunedByAge?({siteID, boardID})
|
||||||
ThreadWatcher.fetchStatus thread
|
threadID is oldest
|
||||||
|
else
|
||||||
|
index >= nThreads - pageLength
|
||||||
|
ThreadWatcher.update siteID, boardID, threadID, {page, lastPage}
|
||||||
|
if ThreadWatcher.unreadEnabled and Conf['Show Unread Count']
|
||||||
|
if modified isnt data.modified or (replies? and replies isnt data.replies)
|
||||||
|
ThreadWatcher.db.extend {siteID, boardID, threadID, val: {modified}}
|
||||||
|
ThreadWatcher.fetchStatus thread
|
||||||
|
else
|
||||||
|
if ThreadWatcher.unreadEnabled and Conf['Show Unread Count']
|
||||||
|
ThreadWatcher.fetchStatus thread
|
||||||
|
else
|
||||||
|
ThreadWatcher.update siteID, boardID, threadID, {isDead: true}
|
||||||
return
|
return
|
||||||
|
|
||||||
fetchStatus: (thread, force) ->
|
fetchStatus: (thread, force) ->
|
||||||
@ -348,9 +373,9 @@ ThreadWatcher =
|
|||||||
|
|
||||||
else if @status is 404
|
else if @status is 404
|
||||||
if SW[software].mayLackJSON and !data.last?
|
if SW[software].mayLackJSON and !data.last?
|
||||||
ThreadWatcher.update siteID, boardID, threadID, {last: -1, unread: undefined, quotingYou: undefined}
|
ThreadWatcher.update siteID, boardID, threadID, {last: -1}
|
||||||
else
|
else
|
||||||
ThreadWatcher.update siteID, boardID, threadID, {isDead: true, unread: undefined, quotingYou: undefined}
|
ThreadWatcher.update siteID, boardID, threadID, {isDead: true}
|
||||||
|
|
||||||
getAll: (groupByBoard) ->
|
getAll: (groupByBoard) ->
|
||||||
all = []
|
all = []
|
||||||
@ -381,6 +406,12 @@ ThreadWatcher =
|
|||||||
title: excerpt
|
title: excerpt
|
||||||
className: 'watcher-link'
|
className: 'watcher-link'
|
||||||
|
|
||||||
|
if Conf['Show Page'] and data.page?
|
||||||
|
page = $.el 'span',
|
||||||
|
textContent: "[#{data.page}]"
|
||||||
|
className: 'watcher-page'
|
||||||
|
$.add link, page
|
||||||
|
|
||||||
if ThreadWatcher.unreadEnabled and Conf['Show Unread Count'] and data.unread?
|
if ThreadWatcher.unreadEnabled and Conf['Show Unread Count'] and data.unread?
|
||||||
count = $.el 'span',
|
count = $.el 'span',
|
||||||
textContent: "(#{data.unread})"
|
textContent: "(#{data.unread})"
|
||||||
@ -398,6 +429,9 @@ ThreadWatcher =
|
|||||||
div.dataset.siteID = siteID
|
div.dataset.siteID = siteID
|
||||||
$.addClass div, 'current' if g.VIEW is 'thread' and fullID is "#{g.BOARD}.#{g.THREADID}"
|
$.addClass div, 'current' if g.VIEW is 'thread' and fullID is "#{g.BOARD}.#{g.THREADID}"
|
||||||
$.addClass div, 'dead-thread' if data.isDead
|
$.addClass div, 'dead-thread' if data.isDead
|
||||||
|
if Conf['Show Page']
|
||||||
|
$.addClass div, 'last-page' if data.lastPage
|
||||||
|
div.dataset.page = data.page if data.page?
|
||||||
if ThreadWatcher.unreadEnabled and Conf['Show Unread Count']
|
if ThreadWatcher.unreadEnabled and Conf['Show Unread Count']
|
||||||
$.addClass div, 'replies-read' if data.unread is 0
|
$.addClass div, 'replies-read' if data.unread is 0
|
||||||
$.addClass div, 'replies-unread' if data.unread
|
$.addClass div, 'replies-unread' if data.unread
|
||||||
@ -467,6 +501,9 @@ ThreadWatcher =
|
|||||||
if newData.isDead and Conf['Auto Prune']
|
if newData.isDead and Conf['Auto Prune']
|
||||||
ThreadWatcher.rm siteID, boardID, threadID
|
ThreadWatcher.rm siteID, boardID, threadID
|
||||||
return
|
return
|
||||||
|
if newData.isDead or newData.last is -1
|
||||||
|
for key in ['page', 'lastPage', 'unread', 'quotingyou'] when key not of newData
|
||||||
|
newData[key] = undefined
|
||||||
n = 0
|
n = 0
|
||||||
n++ for key, val of newData when data[key] isnt val
|
n++ for key, val of newData when data[key] isnt val
|
||||||
return unless n
|
return unless n
|
||||||
@ -483,8 +520,8 @@ ThreadWatcher =
|
|||||||
if Conf['Auto Prune']
|
if Conf['Auto Prune']
|
||||||
ThreadWatcher.db.delete {boardID, threadID}
|
ThreadWatcher.db.delete {boardID, threadID}
|
||||||
return cb()
|
return cb()
|
||||||
return cb() if data.isDead and not (data.unread? or data.quotingYou?)
|
return cb() if data.isDead and not (data.page? or data.lastPage? or data.unread? or data.quotingYou?)
|
||||||
ThreadWatcher.db.extend {boardID, threadID, val: {isDead: true, unread: undefined, quotingYou: undefined}}, cb
|
ThreadWatcher.db.extend {boardID, threadID, val: {isDead: true, page: undefined, lastPage: undefined, unread: undefined, quotingYou: undefined}}, cb
|
||||||
|
|
||||||
toggle: (thread) ->
|
toggle: (thread) ->
|
||||||
siteID = Site.hostname
|
siteID = Site.hostname
|
||||||
@ -511,8 +548,11 @@ ThreadWatcher =
|
|||||||
addRaw: (boardID, threadID, data) ->
|
addRaw: (boardID, threadID, data) ->
|
||||||
ThreadWatcher.db.set {boardID, threadID, val: data}
|
ThreadWatcher.db.set {boardID, threadID, val: data}
|
||||||
ThreadWatcher.refresh()
|
ThreadWatcher.refresh()
|
||||||
if ThreadWatcher.unreadEnabled and Conf['Show Unread Count']
|
thread = {siteID: Site.hostname, boardID, threadID, data}
|
||||||
ThreadWatcher.fetchStatus {siteID: Site.hostname, boardID, threadID, data}, true
|
if Conf['Show Page'] and !data.isDead
|
||||||
|
ThreadWatcher.fetchBoard [thread], true
|
||||||
|
else if ThreadWatcher.unreadEnabled and Conf['Show Unread Count']
|
||||||
|
ThreadWatcher.fetchStatus thread, true
|
||||||
|
|
||||||
rm: (siteID, boardID, threadID) ->
|
rm: (siteID, boardID, threadID) ->
|
||||||
ThreadWatcher.db.delete {siteID, boardID, threadID}
|
ThreadWatcher.db.delete {siteID, boardID, threadID}
|
||||||
@ -589,6 +629,6 @@ ThreadWatcher =
|
|||||||
$.addClass entry.el, 'disabled'
|
$.addClass entry.el, 'disabled'
|
||||||
entry.el.title += '\n[Remember Last Read Post is disabled.]'
|
entry.el.title += '\n[Remember Last Read Post is disabled.]'
|
||||||
$.on input, 'change', $.cb.checked
|
$.on input, 'change', $.cb.checked
|
||||||
$.on input, 'change', ThreadWatcher.refresh if name in ['Current Board', 'Show Unread Count', 'Show Site Prefix']
|
$.on input, 'change', ThreadWatcher.refresh if name in ['Current Board', 'Show Page', 'Show Unread Count', 'Show Site Prefix']
|
||||||
$.on input, 'change', ThreadWatcher.fetchAuto if name in ['Show Unread Count', 'Auto Update Thread Watcher']
|
$.on input, 'change', ThreadWatcher.fetchAuto if name in ['Show Page', 'Show Unread Count', 'Auto Update Thread Watcher']
|
||||||
@menu.addEntry entry
|
@menu.addEntry entry
|
||||||
|
|||||||
@ -676,6 +676,10 @@ Config =
|
|||||||
false
|
false
|
||||||
'Automatically remove dead threads.'
|
'Automatically remove dead threads.'
|
||||||
]
|
]
|
||||||
|
'Show Page': [
|
||||||
|
true
|
||||||
|
'Show what page watched threads are on.'
|
||||||
|
]
|
||||||
'Show Unread Count': [
|
'Show Unread Count': [
|
||||||
true
|
true
|
||||||
'Show number of unread posts in watched threads.'
|
'Show number of unread posts in watched threads.'
|
||||||
|
|||||||
@ -93,7 +93,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Thread Watcher */
|
/* Thread Watcher */
|
||||||
:root.burichan .replies-quoting-you > a, :root.burichan #watcher-link.replies-quoting-you {
|
:root.burichan .replies-quoting-you > a, :root.burichan #watcher-link.replies-quoting-you, :root.burichan .last-page > a > .watcher-page {
|
||||||
color: #F00;
|
color: #F00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -93,7 +93,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Thread Watcher */
|
/* Thread Watcher */
|
||||||
:root.futaba .replies-quoting-you > a, :root.futaba #watcher-link.replies-quoting-you {
|
:root.futaba .replies-quoting-you > a, :root.futaba #watcher-link.replies-quoting-you, :root.futaba .last-page > a > .watcher-page {
|
||||||
color: #F00;
|
color: #F00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -91,7 +91,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Thread Watcher */
|
/* Thread Watcher */
|
||||||
:root.photon .replies-quoting-you > a, :root.photon #watcher-link.replies-quoting-you {
|
:root.photon .replies-quoting-you > a, :root.photon #watcher-link.replies-quoting-you, :root.photon .last-page > a > .watcher-page {
|
||||||
color: #00F !important;
|
color: #00F !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -157,7 +157,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Thread Watcher */
|
/* Thread Watcher */
|
||||||
:root.spooky .replies-quoting-you > a, :root.spooky #watcher-link.replies-quoting-you {
|
:root.spooky .replies-quoting-you > a, :root.spooky #watcher-link.replies-quoting-you, :root.spooky .last-page > a > .watcher-page {
|
||||||
color: #F00 !important;
|
color: #F00 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1168,10 +1168,12 @@ span.hide-announcement {
|
|||||||
-webkit-flex-direction: row;
|
-webkit-flex-direction: row;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
#watched-threads .watcher-page,
|
||||||
#watched-threads .watcher-unread {
|
#watched-threads .watcher-unread {
|
||||||
-webkit-flex: 0 0 auto;
|
-webkit-flex: 0 0 auto;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
#watched-threads .watcher-page::after,
|
||||||
#watched-threads .watcher-unread::after {
|
#watched-threads .watcher-unread::after {
|
||||||
content: "\00a0";
|
content: "\00a0";
|
||||||
}
|
}
|
||||||
@ -1181,7 +1183,7 @@ span.hide-announcement {
|
|||||||
-webkit-flex: 0 1 auto;
|
-webkit-flex: 0 1 auto;
|
||||||
flex: 0 1 auto;
|
flex: 0 1 auto;
|
||||||
}
|
}
|
||||||
.replies-quoting-you > a, #watcher-link.replies-quoting-you {
|
.replies-quoting-you > a, #watcher-link.replies-quoting-you, .last-page > a > .watcher-page {
|
||||||
color: #F00;
|
color: #F00;
|
||||||
}
|
}
|
||||||
#thread-watcher a {
|
#thread-watcher a {
|
||||||
|
|||||||
@ -162,7 +162,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Thread Watcher */
|
/* Thread Watcher */
|
||||||
:root.tomorrow .replies-quoting-you > a, :root.tomorrow #watcher-link.replies-quoting-you {
|
:root.tomorrow .replies-quoting-you > a, :root.tomorrow #watcher-link.replies-quoting-you, :root.tomorrow .last-page > a > .watcher-page {
|
||||||
color: #F00 !important;
|
color: #F00 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -88,7 +88,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Thread Watcher */
|
/* Thread Watcher */
|
||||||
:root.yotsuba .replies-quoting-you > a, :root.yotsuba #watcher-link.replies-quoting-you {
|
:root.yotsuba .replies-quoting-you > a, :root.yotsuba #watcher-link.replies-quoting-you, :root.yotsuba .last-page > a > .watcher-page {
|
||||||
color: #F00;
|
color: #F00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,8 @@ SW.yotsuba =
|
|||||||
archiveListJSON: ({boardID}) -> if BoardConfig.isArchived(boardID) then "#{location.protocol}//a.4cdn.org/#{boardID}/archive.json" else ''
|
archiveListJSON: ({boardID}) -> if BoardConfig.isArchived(boardID) then "#{location.protocol}//a.4cdn.org/#{boardID}/archive.json" else ''
|
||||||
catalogJSON: ({boardID}) -> "#{location.protocol}//a.4cdn.org/#{boardID}/catalog.json"
|
catalogJSON: ({boardID}) -> "#{location.protocol}//a.4cdn.org/#{boardID}/catalog.json"
|
||||||
|
|
||||||
|
isPrunedByAge: ({boardID}) -> boardID is 'f'
|
||||||
|
|
||||||
selectors:
|
selectors:
|
||||||
board: '.board'
|
board: '.board'
|
||||||
thread: '.thread'
|
thread: '.thread'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user