diff --git a/js/state/syncUtil.js b/js/state/syncUtil.js index b44895d9742..19c678cc1a6 100644 --- a/js/state/syncUtil.js +++ b/js/state/syncUtil.js @@ -61,8 +61,9 @@ let folderIdMap = new Immutable.Map() * Converts sync records into a form that can be consumed by AppStore. * @param {Object} record * @param {Immutable.Map} appState + * @param {Immutable.List=} records - batch of records possibly not yet applied */ -module.exports.getSiteDataFromRecord = (record, appState) => { +module.exports.getSiteDataFromRecord = (record, appState, records) => { const objectId = new Immutable.List(record.objectId) const category = CATEGORY_MAP[record.objectData].categoryName let existingObjectData @@ -96,7 +97,7 @@ module.exports.getSiteDataFromRecord = (record, appState) => { const parentFolderObjectId = siteProps.parentFolderObjectId if (parentFolderObjectId && parentFolderObjectId.length > 0) { siteProps.parentFolderId = - getFolderIdByObjectId(new Immutable.List(parentFolderObjectId), appState) + getFolderIdByObjectId(new Immutable.List(parentFolderObjectId), appState, records) } } const siteDetail = new Immutable.Map(pickFields(siteProps, SITE_FIELDS)) @@ -341,16 +342,30 @@ module.exports.getObjectById = (objectId, category, appState) => { * Given an bookmark folder objectId, find the folder and return its folderId. * @param {Immutable.List} objectId * @param {Immutable.Map=} appState + * @param {Immutable.List=} records * @returns {number|undefined} */ -const getFolderIdByObjectId = (objectId, appState) => { +const getFolderIdByObjectId = (objectId, appState, records) => { if (folderIdMap.has(objectId)) { return folderIdMap.get(objectId) } + let folderId const entry = module.exports.getObjectById(objectId, 'BOOKMARKS', appState) - if (!entry) { return undefined } - const folderId = entry[1].get('folderId') - folderIdMap = folderIdMap.set(objectId, folderId) + if (entry) { + folderId = entry[1].get('folderId') + } else if (records) { + // Look for a folder record with a matching object ID in this record batch + const matchingFolder = records.find((record) => { + record = Immutable.fromJS(record) + return record && objectId.equals(record.get('objectId')) && typeof record.getIn(['bookmark', 'site', 'folderId']) === 'number' + }) + if (matchingFolder) { + folderId = matchingFolder.bookmark.site.folderId + } + } + if (folderId) { + folderIdMap = folderIdMap.set(objectId, folderId) + } return folderId } diff --git a/js/stores/appStore.js b/js/stores/appStore.js index dd5fdbd7004..3b2c21a5510 100644 --- a/js/stores/appStore.js +++ b/js/stores/appStore.js @@ -9,7 +9,6 @@ const ExtensionConstants = require('../../app/common/constants/extensionConstant const AppDispatcher = require('../dispatcher/appDispatcher') const appConfig = require('../constants/appConfig') const settings = require('../constants/settings') -const siteTags = require('../constants/siteTags') const writeActions = require('../constants/sync/proto').actions const siteUtil = require('../state/siteUtil') const syncUtil = require('../state/syncUtil') @@ -438,16 +437,23 @@ const handleAppAction = (action) => { nativeImage.copyDataURL(action.dataURL, action.html, action.text) break case appConstants.APP_APPLY_SITE_RECORDS: + let nextFolderId = siteUtil.getNextFolderId(appState.get('sites')) + // Ensure that all folders are assigned folderIds + action.records.forEach((record, i) => { + if (record.action !== writeActions.DELETE && + record.bookmark && record.bookmark.isFolder && + record.bookmark.site && + typeof record.bookmark.site.folderId !== 'number') { + record.bookmark.site.folderId = nextFolderId + action.records.set(i, record) + nextFolderId = nextFolderId + 1 + } + }) action.records.forEach((record) => { - const siteData = syncUtil.getSiteDataFromRecord(record, appState) + const siteData = syncUtil.getSiteDataFromRecord(record, appState, action.records) const tag = siteData.tag let siteDetail = siteData.siteDetail const sites = appState.get('sites') - if (record.action !== writeActions.DELETE && - tag === siteTags.BOOKMARK_FOLDER && - !siteDetail.get('folderId')) { - siteDetail = siteDetail.set('folderId', siteUtil.getNextFolderId(sites)) - } switch (record.action) { case writeActions.CREATE: appState = appState.set('sites',