Add callback to $.set and use it.

We can now:

- Update status of 404'd threads in watcher before redirecting.
- Wait until imported settings are saved before prompting to reload.

Also $.clear now passes errors to the callback rather than simply failing.
This commit is contained in:
ccd0 2015-02-14 16:05:16 -08:00
parent 5ad84a700e
commit 6dd2a4103c
5 changed files with 56 additions and 31 deletions

View File

@ -129,12 +129,14 @@ Main =
initReady: ->
if d.title in ['4chan - Temporarily Offline', '4chan - 404 Not Found']
if Conf['404 Redirect'] and g.VIEW is 'thread'
href = Redirect.to 'thread',
boardID: g.BOARD.ID
threadID: g.THREADID
postID: +location.hash.match /\d+/ # post number or 0
Redirect.navigate href, "/#{g.BOARD}/"
if g.VIEW is 'thread'
ThreadWatcher.set404 g.BOARD.ID, g.THREADID, ->
if Conf['404 Redirect']
href = Redirect.to 'thread',
boardID: g.BOARD.ID
threadID: g.THREADID
postID: +location.hash.match /\d+/ # post number or 0
Redirect.navigate href, "/#{g.BOARD}/"
return
# 4chan Pass Link

View File

@ -175,15 +175,17 @@ Settings =
reader = new FileReader()
reader.onload = (e) ->
try
Settings.loadSettings JSON.parse e.target.result
if confirm 'Import successful. Reload now?'
window.location.reload()
Settings.loadSettings JSON.parse(e.target.result), (err) ->
if err
output.textContent = 'Import failed due to an error.'
else if confirm 'Import successful. Reload now?'
window.location.reload()
catch err
output.textContent = 'Import failed due to an error.'
c.error err.stack
reader.readAsText file
loadSettings: (data) ->
loadSettings: (data, cb) ->
version = data.version.split '.'
if version[0] is '2'
convertSettings = (data, map) ->
@ -265,11 +267,17 @@ Settings =
if data.Conf['WatchedThreads']
data.Conf['watchedThreads'] = boards: ThreadWatcher.convert data.Conf['WatchedThreads']
delete data.Conf['WatchedThreads']
$.clear -> $.set data.Conf
$.clear (err) ->
return cb err if err
$.set data.Conf, cb
reset: ->
if confirm 'Your current settings will be entirely wiped, are you sure?'
$.clear -> window.location.reload() if confirm 'Reset successful. Reload now?'
$.clear (err) ->
if err
$('.imp-exp-result').textContent = 'Import failed due to an error.'
else if confirm 'Reset successful. Reload now?'
window.location.reload()
filter: (section) ->
$.extend section, <%= importHTML('Settings/Filter-select') %>

View File

@ -361,16 +361,16 @@ do ->
chrome.storage.sync.remove keys
timeout = {}
setArea = (area) ->
setArea = (area, cb) ->
data = {}
$.extend data, items[area]
return if !Object.keys(data).length or timeout[area] > Date.now()
chrome.storage[area].set data, ->
if chrome.runtime.lastError
c.error chrome.runtime.lastError.message
if err = chrome.runtime.lastError
c.error err.message
setTimeout setArea, $.MINUTE, area
timeout[area] = Date.now() + $.MINUTE
return
return cb? err
delete timeout[area]
delete items[area][key] for key of data when items[area][key] is data[key]
@ -382,29 +382,32 @@ do ->
delete $.localKeys[key]
key
chrome.storage.local.remove oldLocal
cb?()
setSync = $.debounce $.SECOND, ->
setArea 'sync'
$.set = (key, val) ->
data = if typeof key is 'string'
$.item key, val
$.set = (key, val, cb) ->
if typeof key is 'string'
data = $.item key, val
else
key
data = key
cb = val
$.extend items.local, data
$.localKeys[key] = true for key of data
setArea 'local'
setArea 'local', cb
$.clear = (cb) ->
items.local = {}
items.sync = {}
$.localKeys = {}
count = 2
err = null
done = ->
if chrome.runtime.lastError
c.error chrome.runtime.lastError.message
return
cb?() unless --count
err ?= chrome.runtime.lastError
cb? err unless --count
chrome.storage.local.clear done
chrome.storage.sync.clear done
<% } else { %>
@ -470,13 +473,14 @@ $.set = do ->
# for `storage` events
localStorage.setItem key, val
(keys, val) ->
(keys, val, cb) ->
if typeof keys is 'string'
set keys, val
return
for key, val of keys
set key, val
return
else
set key, value for key, value of keys
cb = val
cb?()
$.clear = (cb) ->
try
$.delete GM_listValues().map (key) -> key.replace g.NAMESPACE, ''

View File

@ -13,7 +13,7 @@ class DataBoard
@sync = sync
$.on d, '4chanXInitFinished', init
save: -> $.set @key, @data
save: (cb) -> $.set @key, @data, cb
delete: ({boardID, threadID, postID}) ->
$.forceSync @key
@ -38,7 +38,7 @@ class DataBoard
else unless Object.keys(@data.boards[boardID]).length
delete @data.boards[boardID]
set: ({boardID, threadID, postID, val}) ->
set: ({boardID, threadID, postID, val}, cb) ->
$.forceSync @key
if postID isnt undefined
((@data.boards[boardID] or= {})[threadID] or= {})[postID] = val
@ -46,7 +46,7 @@ class DataBoard
(@data.boards[boardID] or= {})[threadID] = val
else
@data.boards[boardID] = val
@save()
@save cb
get: ({boardID, threadID, postID, defaultValue}) ->
if board = @data.boards[boardID]

View File

@ -335,6 +335,17 @@ ThreadWatcher =
else
ThreadWatcher.refresh()
set404: (boardID, threadID, cb) ->
return cb() unless data = ThreadWatcher.db?.get {boardID, threadID}
if Conf['Auto Prune']
ThreadWatcher.db.delete {boardID, threadID}
return cb()
return cb() if data.isDead and not (data.unread? or data.quotingYou?)
data.isDead = true
delete data.unread
delete data.quotingYou
ThreadWatcher.db.set {boardID, threadID, val: data}, cb
toggle: (thread) ->
boardID = thread.board.ID
threadID = thread.ID