diff --git a/src/General/Main.coffee b/src/General/Main.coffee index ee2fd9381..179e80484 100755 --- a/src/General/Main.coffee +++ b/src/General/Main.coffee @@ -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 diff --git a/src/General/Settings.coffee b/src/General/Settings.coffee index 0fbb11dd5..1518da3df 100755 --- a/src/General/Settings.coffee +++ b/src/General/Settings.coffee @@ -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') %> diff --git a/src/General/lib/$.coffee b/src/General/lib/$.coffee index 3df85540c..5250c132e 100755 --- a/src/General/lib/$.coffee +++ b/src/General/lib/$.coffee @@ -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, '' diff --git a/src/General/lib/databoard.class b/src/General/lib/databoard.class index 3b4eccbae..84b0db994 100755 --- a/src/General/lib/databoard.class +++ b/src/General/lib/databoard.class @@ -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] diff --git a/src/Monitoring/ThreadWatcher.coffee b/src/Monitoring/ThreadWatcher.coffee index 1cee9b1fb..c9a5df82a 100755 --- a/src/Monitoring/ThreadWatcher.coffee +++ b/src/Monitoring/ThreadWatcher.coffee @@ -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