@@ -26,7 +26,8 @@ const CATEGORY_MAP = syncUtil.CATEGORY_MAP
26
26
const CATEGORY_NAMES = Object . keys ( categories )
27
27
const SYNC_ACTIONS = Object . values ( syncConstants )
28
28
29
- let dispatcherCallback = null
29
+ // The sync background script message sender
30
+ let backgroundSender = null
30
31
31
32
const log = ( message ) => {
32
33
if ( ! config . debug ) { return }
@@ -43,6 +44,65 @@ let pollIntervalId = null
43
44
let deviceIdSent = false
44
45
let bookmarksToolbarShown = false
45
46
47
+ // Determines what to sync
48
+ const appStoreChangeCallback = function ( diffs ) {
49
+ if ( ! backgroundSender ) {
50
+ return
51
+ }
52
+
53
+ // Fields that should trigger a sync SEND when changed
54
+ const syncFields = {
55
+ sites : [ 'location' , 'tags' , 'customTitle' , 'folderId' , 'parentFolderId' ] ,
56
+ siteSettings : Object . keys ( syncUtil . siteSettingDefaults )
57
+ }
58
+ diffs . forEach ( ( diff ) => {
59
+ if ( ! diff || ! diff . path ) {
60
+ return
61
+ }
62
+ const path = diff . path . split ( '/' )
63
+ if ( path . length < 3 ) {
64
+ // We are looking for paths like ['', 'sites', 'https://brave.com/', 'title']
65
+ return
66
+ }
67
+ const type = path [ 1 ]
68
+ const fieldsToPick = syncFields [ type ]
69
+ if ( ! fieldsToPick ) {
70
+ return
71
+ }
72
+
73
+ const isInsert = diff . op === 'add' && path . length === 3
74
+ const isUpdate = fieldsToPick . includes ( path [ 3 ] ) // Ignore insignicant updates
75
+
76
+ // DELETES are handled in appState because the old object is no longer
77
+ // available by the time emitChanges is received
78
+ // const isDelete = diff.op === 'remove' && path.length === 3
79
+ if ( isInsert || isUpdate ) {
80
+ // This item should be synced
81
+ const statePath = path . slice ( 1 , 3 ) . map ( ( item ) => item . replace ( / ~ 1 / g, '/' ) )
82
+ const entry = AppStore . getState ( ) . getIn ( statePath )
83
+ if ( ! entry || ! entry . toJS ) {
84
+ return
85
+ }
86
+ // Set the object ID if there is not already one
87
+ const entryJS = entry . toJS ( )
88
+ entryJS . objectId = entryJS . objectId || syncUtil . newObjectId ( statePath )
89
+
90
+ let action = null
91
+
92
+ if ( isInsert && ! entry . get ( 'skipSync' ) ) {
93
+ action = writeActions . CREATE
94
+ } else if ( isUpdate ) {
95
+ action = writeActions . UPDATE
96
+ }
97
+
98
+ if ( action !== null ) {
99
+ sendSyncRecords ( backgroundSender , action ,
100
+ [ type === 'sites' ? syncUtil . createSiteData ( entryJS ) : syncUtil . createSiteSettingsData ( statePath [ 1 ] , entryJS ) ] )
101
+ }
102
+ }
103
+ } )
104
+ }
105
+
46
106
/**
47
107
* Sends sync records of the same category to the sync server.
48
108
* @param {event.sender } sender
@@ -81,8 +141,7 @@ const sendSyncRecords = (sender, action, data) => {
81
141
const validateAction = ( action ) => {
82
142
const SYNC_ACTIONS_WITHOUT_ITEMS = [
83
143
syncConstants . SYNC_CLEAR_HISTORY ,
84
- syncConstants . SYNC_CLEAR_SITE_SETTINGS ,
85
- syncConstants . SYNC_DELETE_USER
144
+ syncConstants . SYNC_CLEAR_SITE_SETTINGS
86
145
]
87
146
if ( SYNC_ACTIONS . includes ( action . actionType ) !== true ) {
88
147
return false
@@ -103,53 +162,30 @@ const validateAction = (action) => {
103
162
return true
104
163
}
105
164
106
- const doAction = ( sender , action ) => {
165
+ const dispatcherCallback = ( action ) => {
166
+ if ( ! backgroundSender ) {
167
+ return
168
+ }
169
+
107
170
if ( action . key === settings . SYNC_ENABLED ) {
108
171
if ( action . value === false ) {
109
172
module . exports . stop ( )
110
173
}
111
174
}
112
175
// If sync is not enabled, the following actions should be ignored.
113
- if ( ! syncEnabled ( ) || validateAction ( action ) !== true || sender . isDestroyed ( ) ) {
176
+ if ( ! syncEnabled ( ) || validateAction ( action ) !== true || backgroundSender . isDestroyed ( ) ) {
114
177
return
115
178
}
116
179
switch ( action . actionType ) {
117
- case syncConstants . SYNC_ADD_SITE :
118
- sendSyncRecords ( sender , writeActions . CREATE ,
119
- [ syncUtil . createSiteData ( action . item . toJS ( ) ) ] )
120
- break
121
- case syncConstants . SYNC_UPDATE_SITE :
122
- sendSyncRecords ( sender , writeActions . UPDATE ,
123
- [ syncUtil . createSiteData ( action . item . toJS ( ) ) ] )
124
- break
125
180
case syncConstants . SYNC_REMOVE_SITE :
126
- sendSyncRecords ( sender , writeActions . DELETE ,
181
+ sendSyncRecords ( backgroundSender , writeActions . DELETE ,
127
182
[ syncUtil . createSiteData ( action . item . toJS ( ) ) ] )
128
183
break
129
184
case syncConstants . SYNC_CLEAR_HISTORY :
130
- sender . send ( messages . DELETE_SYNC_CATEGORY , CATEGORY_MAP . historySite . categoryName )
131
- break
132
- case syncConstants . SYNC_ADD_SITE_SETTING :
133
- if ( syncUtil . isSyncable ( 'siteSetting' , action . item ) ) {
134
- sendSyncRecords ( sender , writeActions . CREATE ,
135
- [ syncUtil . createSiteSettingsData ( action . hostPattern , action . item . toJS ( ) ) ] )
136
- }
137
- break
138
- case syncConstants . SYNC_UPDATE_SITE_SETTING :
139
- if ( syncUtil . isSyncable ( 'siteSetting' , action . item ) ) {
140
- sendSyncRecords ( sender , writeActions . UPDATE ,
141
- [ syncUtil . createSiteSettingsData ( action . hostPattern , action . item . toJS ( ) ) ] )
142
- }
143
- break
144
- case syncConstants . SYNC_REMOVE_SITE_SETTING :
145
- sendSyncRecords ( sender , writeActions . DELETE ,
146
- [ syncUtil . createSiteSettingsData ( action . hostPattern , action . item . toJS ( ) ) ] )
185
+ backgroundSender . send ( messages . DELETE_SYNC_CATEGORY , CATEGORY_MAP . historySite . categoryName )
147
186
break
148
187
case syncConstants . SYNC_CLEAR_SITE_SETTINGS :
149
- sender . send ( messages . DELETE_SYNC_SITE_SETTINGS )
150
- break
151
- case syncConstants . SYNC_DELETE_USER :
152
- sender . send ( messages . DELETE_SYNC_USER )
188
+ backgroundSender . send ( messages . DELETE_SYNC_SITE_SETTINGS )
153
189
break
154
190
default :
155
191
}
@@ -165,6 +201,8 @@ module.exports.onSyncReady = (isFirstRun, e) => {
165
201
if ( ! syncEnabled ( ) ) {
166
202
return
167
203
}
204
+ AppStore . addChangeListener ( appStoreChangeCallback )
205
+
168
206
if ( ! deviceIdSent && isFirstRun ) {
169
207
// Sync the device id for this device
170
208
sendSyncRecords ( e . sender , writeActions . CREATE , [ {
@@ -283,9 +321,9 @@ module.exports.init = function (appState) {
283
321
} )
284
322
// sent by about:preferences when resetting sync
285
323
ipcMain . on ( RESET_SYNC , ( e ) => {
286
- if ( dispatcherCallback ) {
324
+ if ( backgroundSender ) {
287
325
// send DELETE_SYNC_USER to sync client. it replies with DELETED_SYNC_USER
288
- dispatcherCallback ( { actionType : syncConstants . SYNC_DELETE_USER } )
326
+ backgroundSender . send ( messages . DELETE_SYNC_USER )
289
327
} else {
290
328
reset ( )
291
329
}
@@ -295,14 +333,15 @@ module.exports.init = function (appState) {
295
333
} )
296
334
// GET_INIT_DATA is the first message sent by the sync-client when it starts
297
335
ipcMain . on ( messages . GET_INIT_DATA , ( e ) => {
336
+ // Set the message sender
337
+ backgroundSender = e . sender
298
338
// Clear any old errors
299
339
appActions . setSyncSetupError ( null )
300
340
// Unregister the previous dispatcher cb
301
341
if ( dispatcherCallback ) {
302
342
appDispatcher . unregister ( dispatcherCallback )
303
343
}
304
344
// Register the dispatcher callback now that we have a valid sender
305
- dispatcherCallback = doAction . bind ( null , e . sender )
306
345
appDispatcher . register ( dispatcherCallback )
307
346
// Send the initial data
308
347
if ( syncEnabled ( ) ) {
@@ -413,4 +452,5 @@ module.exports.stop = function () {
413
452
clearInterval ( pollIntervalId )
414
453
}
415
454
appActions . setSyncSetupError ( null )
455
+ AppStore . removeChangeListener ( appStoreChangeCallback )
416
456
}
0 commit comments