diff --git a/Gruntfile.js b/Gruntfile.js index 1739cd574..8dabe7cd4 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -17,6 +17,7 @@ module.exports = function(grunt) { 'src/features.coffee', 'src/qr.coffee', 'src/report.coffee', + 'src/databoard.coffee', 'src/main.coffee' ], dest: 'tmp/script.coffee' diff --git a/src/databoard.coffee b/src/databoard.coffee new file mode 100644 index 000000000..09cbb9f31 --- /dev/null +++ b/src/databoard.coffee @@ -0,0 +1,80 @@ +DataBoards = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts'] + +class DataBoard + constructor: (@key, sync) -> + @data = Conf[key] + $.sync key, @onSync.bind @ + @clean() + return unless sync + # Chrome also fires the onChanged callback on the current tab, + # so we only start syncing when we're ready. + $.on d, '4chanXInitFinished', => @sync = sync + + delete: ({boardID, threadID, postID}) -> + if postID + delete @data.boards[boardID][threadID][postID] + @deleteIfEmpty {boardID, threadID} + else if threadID + delete @data.boards[boardID][threadID] + @deleteIfEmpty {boardID} + else + delete @data.boards[boardID] + $.set @key, @data + deleteIfEmpty: ({boardID, threadID}) -> + if threadID + unless Object.keys(@data.boards[boardID][threadID]).length + delete @data.boards[boardID][threadID] + @deleteIfEmpty {boardID} + else unless Object.keys(@data.boards[boardID]).length + delete @data.boards[boardID] + set: ({boardID, threadID, postID, val}) -> + if postID + ((@data.boards[boardID] or= {})[threadID] or= {})[postID] = val + else if threadID + (@data.boards[boardID] or= {})[threadID] = val + else + @data.boards[boardID] = val + $.set @key, @data + get: ({boardID, threadID, postID, defaultValue}) -> + if board = @data.boards[boardID] + unless threadID + if postID + for ID, thread in board + if postID of thread + val = thread[postID] + break + else + val = board + else if thread = board[threadID] + val = if postID + thread[postID] + else + thread + val or defaultValue + + clean: -> + for boardID of @data.boards + @deleteIfEmpty {boardID} + + now = Date.now() + if @data.lastChecked < now - 12 * $.HOUR + @data.lastChecked = now + for boardID of @data.boards + @ajaxClean boardID + + $.set @key, @data + ajaxClean: (boardID) -> + $.ajax "//api.4chan.org/#{boardID}/threads.json", onload: (e) => + board = @data.boards[boardID] + threads = {} + for page in JSON.parse e.target.response + for thread in page.threads + if thread.no of board + threads[thread.no] = board[thread.no] + @data.boards[boardID] = threads + @deleteIfEmpty {boardID} + $.set @key, @data + + onSync: (data) -> + @data = data + @sync?() diff --git a/src/features.coffee b/src/features.coffee index dce1a2abd..666d3cef1 100644 --- a/src/features.coffee +++ b/src/features.coffee @@ -347,18 +347,20 @@ Settings = innerHTML: ": Clear manually hidden threads and posts on /#{g.BOARD}/." button = $ 'button', div hiddenNum = 0 - ThreadHiding.getHiddenThreads (hiddenThreads) -> - for ID, thread of hiddenThreads.threads - hiddenNum++ - button.textContent = "Hidden: #{hiddenNum}" - ReplyHiding.getHiddenPosts (hiddenPosts) -> - for ID, thread of hiddenPosts.threads - for ID, post of thread + $.get 'hiddenThreads', boards: {}, (item) -> + for ID, board of item.hiddenThreads.boards + for ID, thread of board hiddenNum++ button.textContent = "Hidden: #{hiddenNum}" + $.get 'hiddenPosts', boards: {}, (item) -> + for ID, board of item.hiddenPosts.boards + for ID, thread of board + for ID, post of thread + hiddenNum++ + button.textContent = "Hidden: #{hiddenNum}" $.on button, 'click', -> @textContent = 'Hidden: 0' - $.delete ["hiddenThreads.#{g.BOARD}", "hiddenPosts.#{g.BOARD}"] + $.delete ['hiddenThreads', 'hiddenPosts'] $.after $('input[name="Stubs"]', section).parentNode.parentNode, div export: (now, data) -> unless typeof now is 'number' @@ -367,9 +369,14 @@ Settings = version: g.VERSION date: now Conf: Conf - $.get 'WatchedThreads', {}, (item) -> - data.WatchedThreads = item.WatchedThreads + items = WatchedThreads: {} + for db in DataBoards + items[db] = boards: {} + $.get items (items) -> + for key, val in items + data[key] = val Settings.export now, data + return a = $.el 'a', className: 'warning' textContent: 'Save me!' @@ -472,6 +479,8 @@ Settings = "Shift+#{s[0...-1]}#{s[-1..].toLowerCase()}" for key, val of data.Conf $.set key, val + for db in DataBoards + $.set db, data[db] $.set 'WatchedThreads', data.WatchedThreads convertSettings: (data, map) -> for prevKey, newKey of map @@ -1060,43 +1069,38 @@ ThreadHiding = init: -> return if g.VIEW isnt 'index' or !Conf['Thread Hiding'] and !Conf['Thread Hiding Link'] - Misc.clearThreads "hiddenThreads.#{g.BOARD}" + @db = new DataBoard 'hiddenThreads' @syncFromCatalog() Thread::callbacks.push name: 'Thread Hiding' cb: @node node: -> - if data = ThreadHiding.hiddenThreads.threads[@] + if data = ThreadHiding.db.get {boardID: @board.ID, threadID: @ID} ThreadHiding.hide @, data.makeStub return unless Conf['Thread Hiding'] $.prepend @OP.nodes.root, ThreadHiding.makeButton @, 'hide' - getHiddenThreads: (cb) -> - $.get "hiddenThreads.#{g.BOARD}", threads: {}, (item) -> - ThreadHiding.hiddenThreads = item["hiddenThreads.#{g.BOARD}"] - cb ThreadHiding.hiddenThreads if cb - syncFromCatalog: -> # Sync hidden threads from the catalog into the index. - ThreadHiding.getHiddenThreads (hiddenThreads) -> - {threads} = hiddenThreads - hiddenThreadsOnCatalog = JSON.parse(localStorage.getItem "4chan-hide-t-#{g.BOARD}") or {} + hiddenThreads = ThreadHiding.db.get + boardID: g.BOARD.ID + defaultValue: {} + hiddenThreadsOnCatalog = JSON.parse(localStorage.getItem "4chan-hide-t-#{g.BOARD}") or {} - # Add threads that were hidden in the catalog. - for threadID of hiddenThreadsOnCatalog - continue if threadID of threads - threads[threadID] = {} + # Add threads that were hidden in the catalog. + for threadID of hiddenThreadsOnCatalog + unless threadID of hiddenThreads + hiddenThreads[threadID] = {} - # Remove threads that were un-hidden in the catalog. - for threadID of threads - continue if threadID of threads - delete threads[threadID] + # Remove threads that were un-hidden in the catalog. + for threadID of hiddenThreads + unless threadID of hiddenThreadsOnCatalog + delete hiddenThreads[threadID] - if Object.keys(threads).length - $.set "hiddenThreads.#{g.BOARD}", ThreadHiding.hiddenThreads - else - $.delete "hiddenThreads.#{g.BOARD}" + ThreadHiding.db.set + boardID: g.BOARD.ID + val: hiddenThreads menu: init: -> @@ -1141,17 +1145,19 @@ ThreadHiding = a saveHiddenState: (thread, makeStub) -> - # Get fresh hidden threads. - ThreadHiding.getHiddenThreads (hiddenThreads) -> - hiddenThreadsCatalog = JSON.parse(localStorage.getItem "4chan-hide-t-#{g.BOARD}") or {} - if thread.isHidden - hiddenThreads.threads[thread] = {makeStub} - hiddenThreadsCatalog[thread] = true - else - delete hiddenThreads.threads[thread] - delete hiddenThreadsCatalog[thread] - $.set "hiddenThreads.#{g.BOARD}", hiddenThreads - localStorage.setItem "4chan-hide-t-#{g.BOARD}", JSON.stringify hiddenThreadsCatalog + hiddenThreadsOnCatalog = JSON.parse(localStorage.getItem "4chan-hide-t-#{g.BOARD}") or {} + if thread.isHidden + ThreadHiding.db.set + boardID: thread.board.ID + threadID: thread.ID + val: {makeStub} + hiddenThreadsOnCatalog[thread] = true + else + ThreadHiding.db.delete + boardID: thread.board.ID + threadID: thread.ID + delete hiddenThreadsOnCatalog[thread] + localStorage.setItem "4chan-hide-t-#{g.BOARD}", JSON.stringify hiddenThreadsOnCatalog toggle: (thread) -> unless thread instanceof Thread @@ -1204,29 +1210,22 @@ ReplyHiding = init: -> return if g.VIEW is 'catalog' or !Conf['Reply Hiding'] and !Conf['Reply Hiding Link'] - Misc.clearThreads "hiddenPosts.#{g.BOARD}" - @getHiddenPosts() + @db = new DataBoard 'hiddenPosts' Post::callbacks.push name: 'Reply Hiding' cb: @node node: -> return if !@isReply or @isClone - if thread = ReplyHiding.hiddenPosts.threads[@thread] - if data = thread[@] - if data.thisPost - ReplyHiding.hide @, data.makeStub, data.hideRecursively - else - Recursive.apply ReplyHiding.hide, @, data.makeStub, true - Recursive.add ReplyHiding.hide, @, data.makeStub, true + if data = ReplyHiding.db.get {boardID: @board.ID, threadID: @thread.ID, postID: @ID} + if data.thisPost + ReplyHiding.hide @, data.makeStub, data.hideRecursively + else + Recursive.apply ReplyHiding.hide, @, data.makeStub, true + Recursive.add ReplyHiding.hide, @, data.makeStub, true return unless Conf['Reply Hiding'] $.replace $('.sideArrows', @nodes.root), ReplyHiding.makeButton @, 'hide' - getHiddenPosts: (cb) -> - $.get "hiddenPosts.#{g.BOARD}", threads: {}, (item) -> - ReplyHiding.hiddenPosts = item["hiddenPosts.#{g.BOARD}"] - cb ReplyHiding.hiddenPosts if cb - menu: init: -> return if g.VIEW is 'catalog' or !Conf['Menu'] or !Conf['Reply Hiding Link'] @@ -1279,10 +1278,9 @@ ReplyHiding = el: div order: 20 open: (post) -> - if !post.isReply or post.isClone + if !post.isReply or post.isClone or !post.isHidden return false - thread = ReplyHiding.hiddenPosts.threads[post.thread] - unless post.isHidden or data = thread?[post] + unless data = ReplyHiding.db.get {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID} return false ReplyHiding.menu.post = post thisPost.firstChild.checked = post.isHidden @@ -1309,8 +1307,6 @@ ReplyHiding = thisPost = $('input[name=thisPost]', parent).checked replies = $('input[name=replies]', parent).checked {post} = ReplyHiding.menu - thread = ReplyHiding.hiddenPosts.threads[post.thread] - data = thread?[post] if thisPost ReplyHiding.show post, replies else if replies @@ -1318,7 +1314,7 @@ ReplyHiding = Recursive.rm ReplyHiding.hide, post, true else return - if data + if data = ReplyHiding.db.get {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID} ReplyHiding.saveHiddenState post, !(thisPost and replies), !thisPost, data.makeStub, !replies $.event 'CloseMenu' @@ -1331,21 +1327,18 @@ ReplyHiding = a saveHiddenState: (post, isHiding, thisPost, makeStub, hideRecursively) -> - # Get fresh hidden posts. - ReplyHiding.getHiddenPosts (hiddenPosts) -> - if isHiding - unless thread = hiddenPosts.threads[post.thread] - thread = hiddenPosts.threads[post.thread] = {} - thread[post] = - thisPost: thisPost isnt false # undefined -> true - makeStub: makeStub - hideRecursively: hideRecursively - else - thread = hiddenPosts.threads[post.thread] - delete thread[post] - unless Object.keys(thread).length - delete hiddenPosts.threads[post.thread] - $.set "hiddenPosts.#{g.BOARD}", hiddenPosts + data = + boardID: post.board.ID + threadID: post.thread.ID + postID: post.ID + if isHiding + data.val = + thisPost: thisPost isnt false # undefined -> true + makeStub: makeStub + hideRecursively: hideRecursively + ReplyHiding.db.set data + else + ReplyHiding.db.delete data toggle: -> post = Get.postFromNode @ @@ -1448,8 +1441,8 @@ QuoteStrikeThrough = node: -> return if @isClone for quotelink in @nodes.quotelinks - {board, postID} = Get.postDataFromLink quotelink - if g.posts["#{board}.#{postID}"]?.isHidden + {boardID, postID} = Get.postDataFromLink quotelink + if g.posts["#{boardID}.#{postID}"]?.isHidden $.addClass quotelink, 'filtered' return @@ -1597,7 +1590,7 @@ DeleteLink = cooldown: start: (post, node) -> - unless (thread = QR.yourPosts?.threads?[post.thread]) and post.ID in thread + unless QR.db?.get {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID} # Only start counting on our posts. delete DeleteLink.cooldown.counting return @@ -2304,15 +2297,15 @@ Get = postDataFromLink: (link) -> if link.hostname is 'boards.4chan.org' path = link.pathname.split '/' - board = path[1] + boardID = path[1] threadID = path[3] postID = link.hash[2..] else # resurrected quote - board = link.dataset.board + boardID = link.dataset.board threadID = link.dataset.threadid or 0 postID = link.dataset.postid return { - board: board + boardID: boardID threadID: +threadID postID: +postID } @@ -2340,8 +2333,8 @@ Get = # Third: # Filter out irrelevant quotelinks. quotelinks.filter (quotelink) -> - {board, postID} = Get.postDataFromLink quotelink - board is post.board.ID and postID is post.ID + {boardID, postID} = Get.postDataFromLink quotelink + boardID is post.board.ID and postID is post.ID postClone: (board, threadID, postID, root, context) -> if post = g.posts["#{board}.#{postID}"] Get.insert post, root, context @@ -2510,34 +2503,6 @@ Get = Main.callbackNodes Post, [post] Get.insert post, root, context -Misc = # super semantic - clearThreads: (key, data) -> - unless data - $.get key, null, (item) -> - data = item[key] - return unless data - Misc.clearThreads key, data - return - - unless Object.keys(data.threads).length - $.delete key - return - - return if data.lastChecked > Date.now() - 12 * $.HOUR - - $.ajax "//api.4chan.org/#{g.BOARD}/threads.json", onload: -> - threads = {} - for page in JSON.parse @response - for thread in page.threads - if thread.no of data.threads - threads[thread.no] = data.threads[thread.no] - unless Object.keys(threads).length - $.delete key - return - data.threads = threads - data.lastChecked = Date.now() - $.set key, data - Quotify = init: -> return if g.VIEW is 'catalog' or !Conf['Resurrect Quotes'] @@ -2623,13 +2588,13 @@ QuoteInline = toggle: (e) -> return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0 e.preventDefault() - {board, threadID, postID} = Get.postDataFromLink @ + {boardID, threadID, postID} = Get.postDataFromLink @ context = Get.contextFromLink @ if $.hasClass @, 'inlined' - QuoteInline.rm @, board, threadID, postID, context + QuoteInline.rm @, boardID, threadID, postID, context else return if $.x "ancestor::div[@id='p#{postID}']", @ - QuoteInline.add @, board, threadID, postID, context + QuoteInline.add @, boardID, threadID, postID, context @classList.toggle 'inlined' findRoot: (quotelink, isBacklink) -> @@ -2637,15 +2602,15 @@ QuoteInline = quotelink.parentNode.parentNode else $.x 'ancestor-or-self::*[parent::blockquote][1]', quotelink - add: (quotelink, board, threadID, postID, context) -> + add: (quotelink, boardID, threadID, postID, context) -> isBacklink = $.hasClass quotelink, 'backlink' inline = $.el 'div', id: "i#{postID}" className: 'inline' $.after QuoteInline.findRoot(quotelink, isBacklink), inline - Get.postClone board, threadID, postID, inline, context + Get.postClone boardID, threadID, postID, inline, context - return unless (post = g.posts["#{board}.#{postID}"]) and + return unless (post = g.posts["#{boardID}.#{postID}"]) and context.thread is post.thread # Hide forward post if it's a backlink of a post in this thread. @@ -2659,7 +2624,7 @@ QuoteInline = Unread.posts.splice i, 1 Unread.update() - rm: (quotelink, board, threadID, postID, context) -> + rm: (quotelink, boardID, threadID, postID, context) -> isBacklink = $.hasClass quotelink, 'backlink' # Select the corresponding inlined quote, and remove it. root = QuoteInline.findRoot quotelink, isBacklink @@ -2670,21 +2635,21 @@ QuoteInline = return unless el = root.firstElementChild # Dereference clone. - post = g.posts["#{board}.#{postID}"] + post = g.posts["#{boardID}.#{postID}"] post.rmClone el.dataset.clone # Decrease forward count and unhide. if Conf['Forward Hiding'] and isBacklink and - context.thread is g.threads["#{board}.#{threadID}"] and + context.thread is g.threads["#{boardID}.#{threadID}"] and not --post.forwarded delete post.forwarded $.rmClass post.nodes.root, 'forwarded' # Repeat. while inlined = $ '.inlined', el - {board, threadID, postID} = Get.postDataFromLink inlined - QuoteInline.rm inlined, board, threadID, postID, context + {boardID, threadID, postID} = Get.postDataFromLink inlined + QuoteInline.rm inlined, boardID, threadID, postID, context $.rmClass inlined, 'inlined' return @@ -2704,13 +2669,13 @@ QuotePreview = mouseover: (e) -> return if $.hasClass @, 'inlined' - {board, threadID, postID} = Get.postDataFromLink @ + {boardID, threadID, postID} = Get.postDataFromLink @ qp = $.el 'div', id: 'qp' className: 'dialog' $.add d.body, qp - Get.postClone board, threadID, postID, qp, Get.contextFromLink @ + Get.postClone boardID, threadID, postID, qp, Get.contextFromLink @ UI.hover root: @ @@ -2720,7 +2685,7 @@ QuotePreview = cb: QuotePreview.mouseout asapTest: -> qp.firstElementChild - return unless origin = g.posts["#{board}.#{postID}"] + return unless origin = g.posts["#{boardID}.#{postID}"] if Conf['Quote Highlighting'] posts = [origin].concat origin.clones @@ -2823,11 +2788,12 @@ QuoteYou = return if @isClone # Stop there if there's no quotes in that post. return unless (quotes = @quotes).length + {db} = QR + return unless db {quotelinks} = @nodes for quotelink in quotelinks - {threadID, postID} = Get.postDataFromLink quotelink - if (thread = QR.yourPosts.threads[threadID]) and postID in thread + if db.get Get.postDataFromLink quotelink $.add quotelink, $.tn QuoteYou.text return @@ -2856,8 +2822,8 @@ QuoteOP = # add (OP) to quotes quoting this context's OP. return unless op in quotes for quotelink in quotelinks - {board, postID} = Get.postDataFromLink quotelink - if "#{board}.#{postID}" is op + {boardID, postID} = Get.postDataFromLink quotelink + if "#{boardID}.#{postID}" is op $.add quotelink, $.tn QuoteOP.text return @@ -2879,11 +2845,11 @@ QuoteCT = {board, thread} = if @isClone then @context else @ for quotelink in quotelinks - data = Get.postDataFromLink quotelink - continue unless data.threadID # deadlink + {boardID, threadID} = Get.postDataFromLink quotelink + continue unless threadID # deadlink if @isClone quotelink.textContent = quotelink.textContent.replace QuoteCT.text, '' - if data.board is @board.ID and data.threadID isnt thread.ID + if boardID is @board.ID and threadID isnt thread.ID $.add quotelink, $.tn QuoteCT.text return @@ -3612,13 +3578,11 @@ Unread = init: -> return if g.VIEW isnt 'thread' or !Conf['Unread Count'] and !Conf['Unread Tab Icon'] - Unread.hr = $.el 'hr', + @db = new DataBoard 'lastReadPosts', @sync + @hr = $.el 'hr', id: 'unread-line' - Misc.clearThreads "lastReadPosts.#{g.BOARD}" - $.sync "lastReadPosts.#{g.BOARD}", @sync - - Unread.posts = [] - Unread.postsQuotingYou = [] + @posts = [] + @postsQuotingYou = [] Thread::callbacks.push name: 'Unread' @@ -3630,23 +3594,29 @@ Unread = posts = [] for ID, post of @posts posts.push post if post.isReply - $.get "lastReadPosts.#{@board}", threads: {}, (item) => - Unread.lastReadPost = item["lastReadPosts.#{@board}"].threads[@] or 0 - Unread.addPosts posts - if (hash = location.hash.match /\d+/) and post = @posts[hash[0]] - post.nodes.root.scrollIntoView() - else if Unread.posts.length - # Scroll to before the first unread post. - $.x('preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root).scrollIntoView false - else if posts.length - # Scroll to the last read post. - posts[posts.length - 1].nodes.root.scrollIntoView() + Unread.lastReadPost = Unread.db.get + boardID: @board.ID + threadID: @ID + defaultValue: 0 + Unread.addPosts posts + if (hash = location.hash.match /\d+/) and post = @posts[hash[0]] + post.nodes.root.scrollIntoView() + else if Unread.posts.length + # Scroll to before the first unread post. + $.x('preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root).scrollIntoView false + else if posts.length + # Scroll to the last read post. + posts[posts.length - 1].nodes.root.scrollIntoView() $.on d, 'ThreadUpdate', Unread.onUpdate $.on d, 'scroll visibilitychange', Unread.read $.on d, 'visibilitychange', Unread.setLine if Conf['Unread Line'] - sync: (lastReadPosts) -> - return unless (lastReadPost = lastReadPosts?.threads?[Unread.thread]) and Unread.lastReadPost < lastReadPost + sync: -> + lastReadPost = Unread.db.get + boardID: Unread.thread.board.ID + threadID: Unread.thread.ID + defaultValue: 0 + return unless Unread.lastReadPost < lastReadPost Unread.lastReadPost = lastReadPost Unread.readArray Unread.posts Unread.readArray Unread.postsQuotingYou @@ -3654,29 +3624,30 @@ Unread = Unread.update() addPosts: (newPosts) -> - if Conf['Quick Reply'] - {yourPosts} = QR - youInThisThread = yourPosts.threads[Unread.thread] for post in newPosts {ID} = post - if ID <= Unread.lastReadPost or post.isHidden or youInThisThread and ID in youInThisThread + if ID <= Unread.lastReadPost or post.isHidden continue + if QR.db + data = + boardID: post.board.ID + threadID: post.thread.ID + postID: post.ID + continue if QR.db.get data Unread.posts.push post - Unread.addPostQuotingYou post, yourPosts if yourPosts + Unread.addPostQuotingYou post if Conf['Unread Line'] # Force line on visible threads if there were no unread posts previously. Unread.setLine Unread.posts[0] in newPosts Unread.read() Unread.update() - addPostQuotingYou: (post, yourPosts) -> - for quote in post.quotes - [board, quoteID] = quote.split '.' - continue unless board is Unread.thread.board.ID - for thread, postIDs of yourPosts.threads - if +quoteID in postIDs - Unread.postsQuotingYou.push post - return + addPostQuotingYou: (post) -> + return unless QR.db + for quotelink in post.nodes.quotelinks + if QR.db.get Get.postDataFromLink quotelink + Unread.postsQuotingYou.push post + return onUpdate: (e) -> if e.detail[404] @@ -3704,10 +3675,10 @@ Unread = Unread.update() if e saveLastReadPost: $.debounce 2 * $.SECOND, -> - $.get "lastReadPosts.#{Unread.thread.board}", threads: {}, (item) -> - lastReadPosts = item["lastReadPosts.#{Unread.thread.board}"] - lastReadPosts.threads[Unread.thread] = Unread.lastReadPost - $.set "lastReadPosts.#{Unread.thread.board}", lastReadPosts + Unread.db.set + boardID: Unread.thread.board.ID + threadID: Unread.thread.ID + val: Unread.lastReadPost setLine: (force) -> return unless d.hidden or force is true diff --git a/src/main.coffee b/src/main.coffee index 40f16ac29..303232774 100644 --- a/src/main.coffee +++ b/src/main.coffee @@ -282,22 +282,25 @@ class Clone extends Post Main = init: (items) -> - unless items - # flatten Config into Conf - # and get saved or default values - flatten = (parent, obj) -> - if obj instanceof Array - Conf[parent] = obj[0] - else if typeof obj is 'object' - for key, val of obj - flatten key, val - else # string or number - Conf[parent] = obj - return - flatten null, Config - $.get Conf, Main.init + # flatten Config into Conf + # and get saved or default values + flatten = (parent, obj) -> + if obj instanceof Array + Conf[parent] = obj[0] + else if typeof obj is 'object' + for key, val of obj + flatten key, val + else # string or number + Conf[parent] = obj return + flatten null, Config + for db in DataBoards + Conf[db] = boards: {} + $.get Conf, Main.initFeatures + $.on d, '4chanMainInit', Main.initStyle + + initFeatures: (items) -> Conf = items pathname = location.pathname.split '/' @@ -385,10 +388,10 @@ Main = # c.timeEnd 'All initializations' $.on d, 'AddCallback', Main.addCallback - $.on d, '4chanMainInit', Main.initStyle $.ready Main.initReady initStyle: -> + $.off d, '4chanMainInit', Main.initStyle return unless Main.isThisPageLegit() # disable the mobile layout $('link[href*=mobile]', d.head)?.disabled = true diff --git a/src/qr.coffee b/src/qr.coffee index baa99c1cd..3d95f2495 100644 --- a/src/qr.coffee +++ b/src/qr.coffee @@ -2,8 +2,7 @@ QR = init: -> return if g.VIEW is 'catalog' or !Conf['Quick Reply'] - Misc.clearThreads "yourPosts.#{g.BOARD}" - @syncYourPosts() + @db = new DataBoard 'yourPosts' if Conf['Hide Original Post Form'] $.addClass doc, 'hide-original-post-form' @@ -88,14 +87,6 @@ QR = else QR.unhide() - syncYourPosts: (yourPosts) -> - if yourPosts - QR.yourPosts = yourPosts - return - $.get "yourPosts.#{g.BOARD}", threads: {}, (item) -> - QR.syncYourPosts item["yourPosts.#{g.BOARD}"] - $.sync "yourPosts.#{g.BOARD}", QR.syncYourPosts - error: (err) -> QR.open() if typeof err is 'string' @@ -984,8 +975,11 @@ QR = threadID = +threadID or postID isReply = threadID isnt postID - (QR.yourPosts.threads[threadID] or= []).push postID - $.set "yourPosts.#{g.BOARD}", QR.yourPosts + QR.db.set + boardID: g.BOARD.ID + threadID: threadID + postID: postID + val: true # Post/upload confirmed as successful. $.event 'QRPostSuccessful', {