-
Notifications
You must be signed in to change notification settings - Fork 973
Change sites from List to Map #5531
Changes from 1 commit
20034b2
d8d2b66
aa16552
9143a70
f42afbf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,7 +34,8 @@ AppStore | |
} | ||
} | ||
}, | ||
sites: [{ | ||
sites: { | ||
[siteKey]: { // Calculated by siteUtil.getSiteKey() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you just put the format of the key? like folder specifies folderId, URLs use location/partition/folderId? |
||
location: string, | ||
title: string, | ||
customTitle: string, // User provided title for bookmark; overrides title | ||
|
@@ -46,7 +47,7 @@ AppStore | |
partitionNumber: number, // Optionally specifies a specific session | ||
folderId: number, // Set for bookmark folders only | ||
parentFolderId: number // Set for bookmarks and bookmark folders only | ||
}], | ||
}}, | ||
downloads: [{ | ||
[downloadId]: { | ||
startTime: number, // datetime.getTime() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,22 +25,20 @@ const isBookmarkFolder = (tags) => { | |
tags && typeof tags !== 'string' && tags.includes(siteTags.BOOKMARK_FOLDER) | ||
} | ||
|
||
/** | ||
* Obtains the index of the location in sites | ||
* | ||
* @param sites The application state's Immutable sites list | ||
* @param siteDetail The siteDetails entry to get the index of | ||
* @param tags Tag for siteDetail (ex: bookmark). Folders are searched differently than other entries | ||
* @return index of the siteDetail or -1 if not found. | ||
*/ | ||
module.exports.getSiteIndex = function (sites, siteDetail, tags) { | ||
if (!sites || !siteDetail) { | ||
return -1 | ||
module.exports.getSiteKey = function (siteDetail, tags) { | ||
if (!siteDetail) { | ||
return null | ||
} | ||
if (isBookmarkFolder(tags)) { | ||
return sites.findIndex((site) => isBookmarkFolder(site.get('tags')) && site.get('folderId') === siteDetail.get('folderId')) | ||
const folderId = siteDetail.get('folderId') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. with this refactor, the tags field really isn't needed (which is nice). Because you can determine if it's a folder or not by the |
||
const location = siteDetail.get('location') | ||
if (isBookmarkFolder(tags) && folderId) { | ||
return folderId.toString() | ||
} else if (location) { | ||
return location + | ||
(siteDetail.get('partitionNumber') || 0) + | ||
(siteDetail.get('parentFolderId') || 0) | ||
} | ||
return sites.findIndex((site) => site.get('location') === siteDetail.get('location') && (site.get('partitionNumber') || 0) === (siteDetail.get('partitionNumber') || 0)) | ||
return null | ||
} | ||
|
||
/** | ||
|
@@ -51,11 +49,14 @@ module.exports.getSiteIndex = function (sites, siteDetail, tags) { | |
* @return true if the location is already bookmarked | ||
*/ | ||
module.exports.isSiteBookmarked = function (sites, siteDetail) { | ||
const index = module.exports.getSiteIndex(sites, siteDetail, siteTags.BOOKMARK) | ||
if (index === -1) { | ||
if (!sites) { | ||
return false | ||
} | ||
const key = module.exports.getSiteKey(siteDetail, siteTags.BOOKMARK) | ||
if (key === null) { | ||
return false | ||
} | ||
return isBookmark(sites.get(index).get('tags')) | ||
return isBookmark(sites.getIn([key, 'tags'])) | ||
} | ||
|
||
const getNextFolderIdItem = (sites) => | ||
|
@@ -85,7 +86,7 @@ module.exports.getNextFolderId = (sites) => { | |
|
||
// Some details can be copied from the existing siteDetail if null | ||
// ex: parentFolderId, partitionNumber, and favicon | ||
const mergeSiteDetails = (oldSiteDetail, newSiteDetail, tag, folderId) => { | ||
const mergeSiteDetails = (oldSiteDetail, newSiteDetail, tag, folderId, order) => { | ||
let tags = oldSiteDetail && oldSiteDetail.get('tags') || new Immutable.List() | ||
if (tag) { | ||
tags = tags.toSet().add(tag).toList() | ||
|
@@ -105,9 +106,14 @@ const mergeSiteDetails = (oldSiteDetail, newSiteDetail, tag, folderId) => { | |
let site = Immutable.fromJS({ | ||
lastAccessedTime: lastAccessedTime, | ||
tags, | ||
title: newSiteDetail.get('title') | ||
title: newSiteDetail.get('title'), | ||
order | ||
}) | ||
|
||
if (oldSiteDetail && oldSiteDetail.get('order') !== undefined) { | ||
site = site.set('order', oldSiteDetail.get('order')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At some point (doesn't have to be now, something for all of us to keep in mind 😄), I think it might be worth creating util methods to help with type conversion / default values. Something like this:
|
||
} | ||
|
||
if (newSiteDetail.get('location')) { | ||
site = site.set('location', newSiteDetail.get('location')) | ||
} | ||
|
@@ -162,8 +168,13 @@ module.exports.addSite = function (sites, siteDetail, tag, originalSiteDetail) { | |
tag = siteDetail.getIn(['tags', 0]) | ||
} | ||
|
||
const index = module.exports.getSiteIndex(sites, originalSiteDetail || siteDetail, tag) | ||
const oldSite = index !== -1 ? sites.getIn([index]) : null | ||
let originalSiteKey | ||
if (originalSiteDetail) { | ||
originalSiteKey = module.exports.getSiteKey(originalSiteDetail, originalSiteDetail.get('tags')) | ||
} | ||
|
||
const oldKey = originalSiteKey || module.exports.getSiteKey(siteDetail, tag) | ||
const oldSite = oldKey !== null ? sites.get(oldKey) : null | ||
let folderId = siteDetail.get('folderId') | ||
|
||
if (tag === siteTags.BOOKMARK_FOLDER) { | ||
|
@@ -173,21 +184,21 @@ module.exports.addSite = function (sites, siteDetail, tag, originalSiteDetail) { | |
site.get('parentFolderId') === siteDetail.get('parentFolderId') && | ||
site.get('customTitle') === siteDetail.get('customTitle')) | ||
if (dupFolder) { | ||
sites = module.exports.removeSite(sites, dupFolder, siteTags.BOOKMARK_FOLDER) | ||
sites = module.exports.removeSite(sites, dupFolder, siteTags.BOOKMARK_FOLDER, true) | ||
} | ||
} else if (!folderId) { | ||
// Assign an id if this is a new folder | ||
folderId = module.exports.getNextFolderId(sites) | ||
} | ||
} | ||
|
||
let site = mergeSiteDetails(oldSite, siteDetail, tag, folderId) | ||
if (index === -1) { | ||
// Insert new entry | ||
return sites.push(site) | ||
let site = mergeSiteDetails(oldSite, siteDetail, tag, folderId, sites.size) | ||
|
||
const key = originalSiteKey || module.exports.getSiteKey(site, tag) | ||
if (key === null) { | ||
return sites | ||
} | ||
// Update existing entry | ||
return sites.setIn([index], site) | ||
return sites.set(key, site) | ||
} | ||
|
||
/** | ||
|
@@ -197,36 +208,32 @@ module.exports.addSite = function (sites, siteDetail, tag, originalSiteDetail) { | |
* @param siteDetail The siteDetail to remove a tag from | ||
* @return The new sites Immutable object | ||
*/ | ||
module.exports.removeSite = function (sites, siteDetail, tag) { | ||
const index = module.exports.getSiteIndex(sites, siteDetail, tag) | ||
if (index === -1) { | ||
return sites | ||
} | ||
module.exports.removeSite = function (sites, siteDetail, tag, reorder) { | ||
const key = module.exports.getSiteKey(siteDetail, tag) | ||
|
||
const tags = sites.getIn([index, 'tags']) | ||
const tags = sites.getIn([key, 'tags']) | ||
if (isBookmarkFolder(tags)) { | ||
const folderId = sites.getIn([index, 'folderId']) | ||
const folderId = sites.getIn([key, 'folderId']) | ||
const childSites = sites.filter((site) => site.get('parentFolderId') === folderId) | ||
childSites.forEach((site) => { | ||
const tags = site.get('tags') | ||
tags.forEach((tag) => { | ||
sites = module.exports.removeSite(sites, site, tag) | ||
sites = module.exports.removeSite(sites, site, tag, false) | ||
}) | ||
}) | ||
} | ||
if (tags.size === 0 && !tag) { | ||
// If called without tags and entry has no tags, remove the entry | ||
return sites.splice(index, 1) | ||
} else if (tags.size > 0 && !tag) { | ||
// If called without tags BUT entry has tags, null out lastAccessedTime. | ||
// This is a bookmark entry that we want to clear history for (but NOT delete/untag bookmark) | ||
return sites.setIn([index, 'lastAccessedTime'], null) | ||
} | ||
// Else, remove the specified tag | ||
return sites | ||
.setIn([index, 'parentFolderId'], 0) | ||
.deleteIn([index, 'customTitle']) | ||
.setIn([index, 'tags'], tags.toSet().remove(tag).toList()) | ||
if (reorder) { | ||
const order = sites.getIn([key, 'order']) | ||
sites = sites.map((site) => { | ||
const siteOrder = site.get('order') | ||
if (siteOrder > order) { | ||
return site.set('order', siteOrder - 1) | ||
} | ||
return site | ||
}) | ||
} | ||
|
||
return sites.delete(key) | ||
} | ||
|
||
/** | ||
|
@@ -277,28 +284,40 @@ module.exports.isMoveAllowed = (sites, sourceDetail, destinationDetail) => { | |
* @param disallowReparent If set to true, parent folder will not be set | ||
* @return The new sites Immutable object | ||
*/ | ||
module.exports.moveSite = function (sites, sourceDetail, destinationDetail, prepend, destinationIsParent, disallowReparent) { | ||
module.exports.moveSite = function (sites, sourceDetail, destinationDetail, prepend, | ||
destinationIsParent, disallowReparent) { | ||
if (!module.exports.isMoveAllowed(sites, sourceDetail, destinationDetail)) { | ||
return sites | ||
} | ||
|
||
const sourceSiteIndex = module.exports.getSiteIndex(sites, sourceDetail, sourceDetail.get('tags')) | ||
let sourceKey = module.exports.getSiteKey(sourceDetail, sourceDetail.get('tags')) | ||
let destinationKey = module.exports.getSiteKey(destinationDetail, destinationDetail.get('tags')) | ||
|
||
const sourceSiteIndex = sites.getIn([sourceKey, 'order']) | ||
let destinationSiteIndex | ||
if (destinationIsParent) { | ||
// When the destination is the parent we want to put it at the end | ||
destinationSiteIndex = sites.size - 1 | ||
prepend = false | ||
} else { | ||
destinationSiteIndex = module.exports.getSiteIndex(sites, destinationDetail, destinationDetail.get('tags')) | ||
destinationSiteIndex = sites.getIn([destinationKey, 'order']) | ||
} | ||
|
||
let newIndex = destinationSiteIndex + (prepend ? 0 : 1) | ||
let sourceSite = sites.get(sourceSiteIndex) | ||
let destinationSite = sites.get(destinationSiteIndex) | ||
sites = sites.splice(sourceSiteIndex, 1) | ||
let sourceSite = sites.get(sourceKey) | ||
let destinationSite = sites.get(destinationKey) | ||
sites = sites.delete(sourceKey) | ||
sites = sites.map((site) => { | ||
const siteOrder = site.get('order') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to pull this re-ordering out to a common method? |
||
if (siteOrder > sourceSiteIndex) { | ||
return site.set('order', siteOrder - 1) | ||
} | ||
return site | ||
}) | ||
if (newIndex > sourceSiteIndex) { | ||
newIndex-- | ||
} | ||
sourceSite = sourceSite.set('order', newIndex) | ||
|
||
if (!disallowReparent) { | ||
if (destinationIsParent && destinationDetail.get('folderId') !== sourceSite.get('folderId')) { | ||
|
@@ -309,7 +328,8 @@ module.exports.moveSite = function (sites, sourceDetail, destinationDetail, prep | |
sourceSite = sourceSite.set('parentFolderId', destinationSite.get('parentFolderId')) | ||
} | ||
} | ||
return sites.splice(newIndex, 0, sourceSite) | ||
sourceKey = module.exports.getSiteKey(sourceSite, sourceSite.get('tags')) | ||
return sites.set(sourceKey, sourceSite) | ||
} | ||
|
||
module.exports.getDetailFromFrame = function (frame, tag) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -439,10 +439,15 @@ const handleAppAction = (action) => { | |
appState = appState.set('sites', siteUtil.addSite(appState.get('sites'), s, action.tag)) | ||
}) | ||
} else { | ||
appState = appState.set('sites', siteUtil.addSite(appState.get('sites'), action.siteDetail, action.tag, action.originalSiteDetail)) | ||
let sites = appState.get('sites') | ||
if (!action.siteDetail.get('folderId')) { | ||
action.siteDetail = action.siteDetail.set('folderId', siteUtil.getNextFolderId(sites)) | ||
} | ||
appState = appState.set('sites', siteUtil.addSite(sites, action.siteDetail, action.tag)) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Much cleaner + easier to read 😄 |
||
if (action.destinationDetail) { | ||
appState = appState.set('sites', siteUtil.moveSite(appState.get('sites'), action.siteDetail, action.destinationDetail, false, false, true)) | ||
appState = appState.set('sites', siteUtil.moveSite(appState.get('sites'), | ||
action.siteDetail, action.destinationDetail, false, false, true)) | ||
} | ||
// If there was an item added then clear out the old history entries | ||
if (oldSiteSize !== appState.get('sites').size) { | ||
|
@@ -451,12 +456,18 @@ const handleAppAction = (action) => { | |
appState = aboutNewTabState.addSite(appState, action) | ||
break | ||
case AppConstants.APP_REMOVE_SITE: | ||
appState = appState.set('sites', siteUtil.removeSite(appState.get('sites'), action.siteDetail, action.tag)) | ||
appState = aboutNewTabState.removeSite(appState, action) | ||
break | ||
{ | ||
appState = appState.set('sites', siteUtil.removeSite(appState.get('sites'), action.siteDetail, action.tag, true)) | ||
appState = aboutNewTabState.removeSite(appState, action) | ||
break | ||
} | ||
case AppConstants.APP_MOVE_SITE: | ||
appState = appState.set('sites', siteUtil.moveSite(appState.get('sites'), action.sourceDetail, action.destinationDetail, action.prepend, action.destinationIsParent, false)) | ||
break | ||
{ | ||
appState = appState.set('sites', siteUtil.moveSite(appState.get('sites'), | ||
action.sourceDetail, action.destinationDetail, action.prepend, | ||
action.destinationIsParent, false)) | ||
break | ||
} | ||
case AppConstants.APP_MERGE_DOWNLOAD_DETAIL: | ||
if (action.downloadDetail) { | ||
appState = appState.mergeIn(['downloads', action.downloadId], action.downloadDetail) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job with the above 😄 It's super important to have migrations for the session data