-
Notifications
You must be signed in to change notification settings - Fork 138
/
Copy pathDataBoard.coffee
149 lines (131 loc) · 4.4 KB
/
DataBoard.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
class DataBoard
@keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads', 'customTitles']
constructor: (@key, sync, dontClean) ->
@initData Conf[@key]
$.sync @key, @onSync
@clean() unless dontClean
return unless sync
# Chrome also fires the onChanged callback on the current tab,
# so we only start syncing when we're ready.
init = =>
$.off d, '4chanXInitFinished', init
@sync = sync
$.on d, '4chanXInitFinished', init
initData: (@allData) ->
if Site.hostname is '4chan.org' and @allData.boards
@data = @allData
else
@data = (@allData[Site.hostname] or= boards: {})
changes: []
save: (change, cb) ->
change()
@changes.push change
$.get @key, {boards: {}}, (items) =>
return unless @changes.length
needSync = ((items[@key].version or 0) > (@allData.version or 0))
if needSync
@initData items[@key]
change() for change in @changes
@changes = []
@allData.version = (@allData.version or 0) + 1
$.set @key, @allData, =>
@sync?() if needSync
cb?()
forceSync: (cb) ->
$.get @key, {boards: {}}, (items) =>
if (items[@key].version or 0) > (@allData.version or 0)
@initData items[@key]
change() for change in @changes
@sync?()
cb?()
delete: ({boardID, threadID, postID}) ->
@save =>
if postID
return unless @data.boards[boardID]?[threadID]
delete @data.boards[boardID][threadID][postID]
@deleteIfEmpty {boardID, threadID}
else if threadID
return unless @data.boards[boardID]
delete @data.boards[boardID][threadID]
@deleteIfEmpty {boardID}
else
delete @data.boards[boardID]
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: (data, cb) ->
@save =>
@setUnsafe data
, cb
setUnsafe: ({boardID, threadID, postID, val}) ->
if postID isnt undefined
((@data.boards[boardID] or= {})[threadID] or= {})[postID] = val
else if threadID isnt undefined
(@data.boards[boardID] or= {})[threadID] = val
else
@data.boards[boardID] = val
extend: ({boardID, threadID, postID, val, rm}, cb) ->
@save =>
oldVal = @get {boardID, threadID, postID, val: {}}
delete oldVal[key] for key in rm or []
$.extend oldVal, val
@setUnsafe {boardID, threadID, postID, val: oldVal}
, cb
setLastChecked: ->
@save =>
@data.lastChecked = Date.now()
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: ->
# XXX not yet multisite ready
return unless Site.software is 'yotsuba'
for boardID, val of @data.boards
@deleteIfEmpty {boardID}
now = Date.now()
unless now - 2 * $.HOUR < (@data.lastChecked or 0) <= now
@data.lastChecked = now
for boardID of @data.boards
@ajaxClean boardID
return
ajaxClean: (boardID) ->
$.cache "#{location.protocol}//a.4cdn.org/#{boardID}/threads.json", (e1) =>
return unless e1.target.status is 200
$.cache "#{location.protocol}//a.4cdn.org/#{boardID}/archive.json", (e2) =>
return unless e2.target.status is 200 or boardID in ['b', 'f', 'trash', 'bant']
@ajaxCleanParse boardID, e1.target.response, e2.target.response
ajaxCleanParse: (boardID, response1, response2) ->
return if not (board = @data.boards[boardID])
threads = {}
if response1
for page in response1
for thread in page.threads
ID = thread.no
threads[ID] = board[ID] if ID of board
if response2
for ID in response2
threads[ID] = board[ID] if ID of board
@data.boards[boardID] = threads
@deleteIfEmpty {boardID}
$.set @key, @allData
onSync: (data) =>
return unless (data.version or 0) > (@allData.version or 0)
@initData data
@sync?()