Support refreshing 4chan threads in Thread Watcher from other sites.

This commit is contained in:
ccd0 2018-12-06 18:20:21 -08:00
parent ad16e13b61
commit 4c139b3b0f
6 changed files with 47 additions and 32 deletions

View File

@ -24,8 +24,6 @@ ThreadWatcher =
$.on @refreshButton, 'click', @buttonFetchAll
$.on @closeButton, 'click', @toggleWatcher
@refreshButton.hidden = true unless Site.software is 'yotsuba'
@menu.addHeaderMenuEntry()
$.onExists doc, 'body', @addDialog
@ -184,13 +182,12 @@ ThreadWatcher =
ThreadWatcher.clearRequests()
fetchAuto: ->
return unless Site.software is 'yotsuba'
clearTimeout ThreadWatcher.timeout
return unless Conf['Auto Update Thread Watcher']
{db} = ThreadWatcher
interval = if ThreadWatcher.unreadEnabled and Conf['Show Unread Count'] then 5 * $.MINUTE else 2 * $.HOUR
now = Date.now()
unless now - interval < (db.data[Site.hostname].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()
db.setLastChecked()
ThreadWatcher.timeout = setTimeout ThreadWatcher.fetchAuto, interval
@ -202,7 +199,6 @@ ThreadWatcher =
ThreadWatcher.fetchAllStatus()
fetchAllStatus: ->
return unless Site.software is 'yotsuba'
dbs = [ThreadWatcher.db, ThreadWatcher.unreaddb, QuoteYou.db].filter((x) -> x)
n = 0
for db in dbs
@ -215,18 +211,26 @@ ThreadWatcher =
fetchStatus: (thread, force) ->
{siteID, boardID, threadID, data} = thread
return unless Site.software is 'yotsuba' and siteID is Site.hostname
return unless Conf['siteProperties'][siteID]?.software is 'yotsuba'
return if data.isDead and not force
if ThreadWatcher.requests.length is 0
ThreadWatcher.status.textContent = '...'
$.addClass ThreadWatcher.refreshButton, 'fa-spin'
req = $.ajax "#{location.protocol}//a.4cdn.org/#{boardID}/thread/#{threadID}.json",
onloadend: ->
url = "#{location.protocol}//a.4cdn.org/#{boardID}/thread/#{threadID}.json"
if Site.hasCORS?(url) or url.split('/')[...3].join('/') is location.origin
req = $.ajax url,
onloadend: ->
ThreadWatcher.parseStatus.call @, thread
timeout: $.MINUTE
else
req = {abort: () -> req.aborted = true}
CrossOrigin.json url, ->
return if req.aborted
ThreadWatcher.parseStatus.call @, thread
timeout: $.MINUTE
, true, $.MINUTE
ThreadWatcher.requests.push req
parseStatus: ({boardID, threadID, data}) ->
parseStatus: ({siteID, boardID, threadID, data}) ->
ThreadWatcher.fetched++
if ThreadWatcher.fetched is ThreadWatcher.requests.length
ThreadWatcher.clearRequests()
@ -237,24 +241,20 @@ ThreadWatcher =
last = @response.posts[@response.posts.length-1].no
isDead = !!@response.posts[0].archived
if isDead and Conf['Auto Prune']
ThreadWatcher.db.delete {boardID, threadID}
ThreadWatcher.db.delete {siteID, boardID, threadID}
ThreadWatcher.refresh()
return
return if last is data.last and isDead is data.isDead
lastReadPost = ThreadWatcher.unreaddb.get
boardID: boardID
threadID: threadID
defaultValue: 0
lastReadPost = ThreadWatcher.unreaddb.get {siteID, boardID, threadID, defaultValue: 0}
unread = 0
quotingYou = false
youOP = !!QuoteYou.db?.get {boardID, threadID, postID: threadID}
youOP = !!QuoteYou.db?.get {siteID, boardID, threadID, postID: threadID}
for postObj in @response.posts
continue unless postObj.no > lastReadPost
continue if QuoteYou.db?.get {boardID, threadID, postID: postObj.no}
continue if QuoteYou.db?.get {siteID, boardID, threadID, postID: postObj.no}
unread++
@ -268,6 +268,7 @@ ThreadWatcher =
regexp = /<a [^>]*\bhref="(?:(?:\/\/boards\.4chan(?:nel)?\.org)?\/([^\/]+)\/thread\/)?(\d+)?(?:#p(\d+))?"/g
while match = regexp.exec postObj.com
if QuoteYou.db.get {
siteID
boardID: match[1] or boardID
threadID: match[2] or threadID
postID: match[3] or match[2] or threadID
@ -278,14 +279,14 @@ ThreadWatcher =
quotingYou = true
updated = (isDead isnt data.isDead or unread isnt data.unread or quotingYou isnt data.quotingYou)
ThreadWatcher.db.extend {boardID, threadID, val: {last, isDead, unread, quotingYou}}
ThreadWatcher.db.extend {siteID, boardID, threadID, val: {last, isDead, unread, quotingYou}}
ThreadWatcher.refresh() if updated
else if @status is 404
if Conf['Auto Prune']
ThreadWatcher.db.delete {boardID, threadID}
ThreadWatcher.db.delete {siteID, boardID, threadID}
else
ThreadWatcher.db.extend {boardID, threadID, val: {isDead: true}, rm: ['unread', 'quotingYou']}
ThreadWatcher.db.extend {siteID, boardID, threadID, val: {isDead: true}, rm: ['unread', 'quotingYou']}
ThreadWatcher.refresh()

View File

@ -90,9 +90,9 @@ class DataBoard
@setUnsafe {siteID, boardID, threadID, postID, val: oldVal}
, cb
setLastChecked: (siteID=Site.hostname) ->
setLastChecked: ->
@save =>
@data[siteID].lastChecked = Date.now()
@data.lastChecked = Date.now()
get: ({siteID, boardID, threadID, postID, defaultValue}) ->
siteID or= Site.hostname

View File

@ -1174,6 +1174,9 @@ span.hide-announcement {
-webkit-flex: 0 1 auto;
flex: 0 1 auto;
}
.replies-quoting-you > a, #watcher-link.replies-quoting-you {
color: #F00;
}
#thread-watcher a {
text-decoration: none;
}

View File

@ -26,6 +26,7 @@ ajax = (request, sender, sendResponse) ->
xhr = new XMLHttpRequest()
xhr.open 'GET', request.url, true
xhr.responseType = request.responseType
xhr.timeout = request.timeout
xhr.addEventListener 'load', ->
{status, statusText, response} = @
if @readyState is @DONE && xhr.status is 200
@ -43,4 +44,7 @@ ajax = (request, sender, sendResponse) ->
xhr.addEventListener 'abort', ->
chrome.tabs.sendMessage sender.tab.id, {id, error: true}
, false
xhr.addEventListener 'timeout', ->
chrome.tabs.sendMessage sender.tab.id, {id, error: true}
, false
xhr.send()

View File

@ -4,8 +4,8 @@ eventPageRequest = do ->
chrome.runtime.onMessage.addListener (data) ->
callbacks[data.id] data
delete callbacks[data.id]
(url, responseType, cb) ->
chrome.runtime.sendMessage {url, responseType}, (id) ->
(url, responseType, cb, timeout) ->
chrome.runtime.sendMessage {url, responseType, timeout}, (id) ->
callbacks[id] = cb
<% } %>
@ -85,7 +85,7 @@ CrossOrigin =
$.queueTask -> cb.call {}
delete callbacks[url]
(url, cb, bypassCache) ->
(url, cb, bypassCache, timeout) ->
<% if (type === 'userscript') { %>
unless GM?.xmlHttpRequest? or GM_xmlhttpRequest?
if bypassCache
@ -99,18 +99,20 @@ CrossOrigin =
if bypassCache
delete results[url]
if results[url]
cb.call results[url]
return
if callbacks[url]
callbacks[url].push cb
return
else
if results[url]
cb.call results[url]
return
if callbacks[url]
callbacks[url].push cb
return
callbacks[url] = [cb]
<% if (type === 'userscript') { %>
(GM?.xmlHttpRequest or GM_xmlhttpRequest)
method: "GET"
url: url+''
timeout: timeout
onload: (xhr) ->
{status, statusText} = xhr
try
@ -120,6 +122,7 @@ CrossOrigin =
failure url
onerror: -> failure(url)
onabort: -> failure(url)
ontimeout: -> failure(url)
<% } %>
<% if (type === 'crx') { %>
eventPageRequest url, 'json', (result) ->
@ -127,4 +130,5 @@ CrossOrigin =
success url, result
else
failure url
, timeout
<% } %>

View File

@ -140,3 +140,6 @@ SW.yotsuba =
for node in $$ '.prettyprint', bq
$.replace node, [$.tn('[code]'), node.childNodes..., $.tn '[/code]']
return
hasCORS: (url) ->
url.split('/')[...3].join('/') is location.protocol + '//a.4cdn.org'