Skip to content

Commit

Permalink
Splits sites object in the app state
Browse files Browse the repository at this point in the history
Resolves brave#1856
Resolves brave#2771
Resolves brave#3646
Resolves brave#3694
Resolves brave#4224
Resolves brave#4260
Resolves brave#4833
Resolves brave#4868
Resolves brave#4929
Resolves brave#5699
Resolves brave#6104
Resolves brave#6108
Resolves brave#6585
Resolves brave#8022
Resolves brave#9301
Resolves brave#9326
Resolves brave#9978
Resolves brave#10026

Auditors:

Test Plan:
  • Loading branch information
NejcZdovc committed Jul 22, 2017
1 parent fdd4c09 commit 0802623
Show file tree
Hide file tree
Showing 88 changed files with 3,201 additions and 2,109 deletions.
89 changes: 21 additions & 68 deletions app/browser/api/topSites.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,33 @@
const Immutable = require('immutable')
const appActions = require('../../../js/actions/appActions')
const debounce = require('../../../js/lib/debounce')
const siteUtil = require('../../../js/state/siteUtil')
const historyState = require('../../common/state/historyState')
const {isSourceAboutUrl} = require('../../../js/lib/appUrlUtil')
const aboutNewTabMaxEntries = 100
const aboutNewTabMaxEntries = 18
let appStore

let minCountOfTopSites
let minAccessOfTopSites

const compareSites = (site1, site2) => {
if (!site1 || !site2) return false
return site1.get('location') === site2.get('location') &&
site1.get('partitionNumber') === site2.get('partitionNumber')
}

const pinnedTopSites = (state) => {
return (state.getIn(['about', 'newtab', 'pinnedTopSites']) || Immutable.List()).setSize(18)
return state.getIn(['about', 'newtab', 'pinnedTopSites'], Immutable.List())
}

const ignoredTopSites = (state) => {
return state.getIn(['about', 'newtab', 'ignoredTopSites']) || Immutable.List()
return state.getIn(['about', 'newtab', 'ignoredTopSites'], Immutable.List())
}

const isPinned = (state, siteProps) => {
return pinnedTopSites(state).filter((site) => compareSites(site, siteProps)).size > 0
const isPinned = (state, siteKey) => {
return pinnedTopSites(state).find(site => site.get('key') === siteKey)
}

const isIgnored = (state, siteProps) => {
return ignoredTopSites(state).filter((site) => compareSites(site, siteProps)).size > 0
const isIgnored = (state, siteKey) => {
return ignoredTopSites(state).includes(siteKey)
}

const sortCountDescending = (left, right) => {
const leftCount = left.get('count') || 0
const rightCount = right.get('count') || 0
const leftCount = left.get('count', 0)
const rightCount = right.get('count', 0)
if (leftCount < rightCount) {
return 1
}
Expand All @@ -55,25 +49,6 @@ const sortCountDescending = (left, right) => {
return 0
}

const removeDuplicateDomains = (list) => {
const siteDomains = new Set()
return list.filter((site) => {
if (!site.get('location')) {
return false
}
try {
const hostname = require('../../common/urlParse')(site.get('location')).hostname
if (!siteDomains.has(hostname)) {
siteDomains.add(hostname)
return true
}
} catch (e) {
console.log('Error parsing hostname: ', e)
}
return false
})
}

const calculateTopSites = (clearCache) => {
if (clearCache) {
clearTopSiteCacheData()
Expand All @@ -91,18 +66,21 @@ const startCalculatingTopSiteData = debounce(() => {
}
const state = appStore.getState()
// remove folders; sort by visit count; enforce a max limit
const sites = (state.get('sites') ? state.get('sites').toList() : new Immutable.List())
.filter((site) => !siteUtil.isFolder(site) &&
!siteUtil.isImportedBookmark(site) &&
!isSourceAboutUrl(site.get('location')) &&
const sites = historyState.getSites(state)
.filter((site, key) => !isSourceAboutUrl(site.get('location')) &&
!isPinned(state, key) &&
!isIgnored(state, key) &&
(minCountOfTopSites === undefined || (site.get('count') || 0) >= minCountOfTopSites) &&
(minAccessOfTopSites === undefined || (site.get('lastAccessedTime') || 0) >= minAccessOfTopSites))
(minAccessOfTopSites === undefined || (site.get('lastAccessedTime') || 0) >= minAccessOfTopSites)
)
.sort(sortCountDescending)
.slice(0, aboutNewTabMaxEntries)
.map((site, key) => site.set('key', key))
.toList()

for (let i = 0; i < sites.size; i++) {
const count = sites.getIn([i, 'count']) || 0
const access = sites.getIn([i, 'lastAccessedTime']) || 0
const count = sites.getIn([i, 'count'], 0)
const access = sites.getIn([i, 'lastAccessedTime'], 0)
if (minCountOfTopSites === undefined || count < minCountOfTopSites) {
minCountOfTopSites = count
}
Expand All @@ -111,32 +89,7 @@ const startCalculatingTopSiteData = debounce(() => {
}
}

// Filter out pinned and ignored sites
let unpinnedSites = sites.filter((site) => !(isPinned(state, site) || isIgnored(state, site)))
unpinnedSites = removeDuplicateDomains(unpinnedSites)

// Merge the pinned and unpinned lists together
// Pinned items have priority because the position is important
let gridSites = pinnedTopSites(state).map((pinnedSite) => {
// Fetch latest siteDetail objects from appState.sites using location/partition
if (pinnedSite) {
const matches = sites.filter((site) => compareSites(site, pinnedSite))
if (matches.size > 0) return matches.first()
}
// Default to unpinned items
const firstSite = unpinnedSites.first()
unpinnedSites = unpinnedSites.shift()
return firstSite
})

// Include up to [aboutNewTabMaxEntries] entries so that folks
// can ignore sites and have new items fill those empty spaces
if (unpinnedSites.size > 0) {
gridSites = gridSites.concat(unpinnedSites)
}

const finalData = gridSites.filter((site) => site != null)
appActions.topSiteDataAvailable(finalData)
appActions.topSiteDataAvailable(sites)
}, 5 * 1000)

const clearTopSiteCacheData = () => {
Expand Down
47 changes: 25 additions & 22 deletions app/browser/bookmarksExporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,23 @@ const electron = require('electron')
const dialog = electron.dialog
const app = electron.app
const BrowserWindow = electron.BrowserWindow
const getSetting = require('../../js/settings').getSetting

// State
const bookmarksState = require('../common/state/bookmarksState')

// Constants
const settings = require('../../js/constants/settings')
const siteTags = require('../../js/constants/siteTags')
const siteUtil = require('../../js/state/siteUtil')
const isWindows = process.platform === 'win32'

// Utils
const {getSetting} = require('../../js/settings')
const platformUtil = require('../common/lib/platformUtil')
const bookmarkFoldersUtil = require('../common/lib/bookmarkFoldersUtil')
const bookmarkUtil = require('../common/lib/bookmarkUtil')

const indentLength = 2
const indentType = ' '

function showDialog (sites) {
const showDialog = (state) => {
const focusedWindow = BrowserWindow.getFocusedWindow()
const fileName = moment().format('DD_MM_YYYY') + '.html'
const defaultPath = path.join(getSetting(settings.DEFAULT_DOWNLOAD_SAVE_PATH) || app.getPath('downloads'), fileName)
Expand All @@ -34,34 +42,29 @@ function showDialog (sites) {
}]
}, (fileName) => {
if (fileName) {
personal = createBookmarkArray(sites)
other = createBookmarkArray(sites, -1, false)
personal = createBookmarkArray(state)
other = createBookmarkArray(state, -1, false)
fs.writeFileSync(fileName, createBookmarkHTML(personal, other))
}
})
}

function createBookmarkArray (sites, parentFolderId, first = true, depth = 1) {
const filteredBookmarks = parentFolderId
? sites.filter((site) => site.get('parentFolderId') === parentFolderId)
: sites.filter((site) => !site.get('parentFolderId'))
const createBookmarkArray = (state, parentFolderId = 0, first = true, depth = 1) => {
const bookmarks = bookmarksState.getBookmarksWithFolders(state, parentFolderId)
let payload = []
let title
let indentFirst = indentType.repeat(depth * indentLength)
let indentNext = (!first) ? indentFirst : indentType.repeat((depth + 1) * indentLength)

if (first) payload.push(`${indentFirst}<DL><p>`)

filteredBookmarks.forEach((site) => {
if (site.get('tags').includes(siteTags.BOOKMARK) && site.get('location')) {
title = site.get('customTitle') || site.get('title') || site.get('location')
bookmarks.forEach((site) => {
if (bookmarkUtil.isBookmark(site) && site.get('location')) {
title = site.get('title', site.get('location'))
payload.push(`${indentNext}<DT><A HREF="${site.get('location')}">${title}</A>`)
} else if (siteUtil.isFolder(site)) {
const folderId = site.get('folderId')

title = site.get('customTitle') || site.get('title')
payload.push(`${indentNext}<DT><H3>${title}</H3>`)
payload = payload.concat(createBookmarkArray(sites, folderId, true, (depth + 1)))
} else if (bookmarkFoldersUtil.isFolder(site)) {
payload.push(`${indentNext}<DT><H3>${site.get('title')}</H3>`)
payload = payload.concat(createBookmarkArray(state, site.get('folderId'), true, (depth + 1)))
}
})

Expand All @@ -70,8 +73,8 @@ function createBookmarkArray (sites, parentFolderId, first = true, depth = 1) {
return payload
}

function createBookmarkHTML (personal, other) {
const breakTag = (isWindows) ? '\r\n' : '\n'
const createBookmarkHTML = (personal, other) => {
const breakTag = (platformUtil.isWindows()) ? '\r\n' : '\n'
const title = 'Bookmarks'

return `<!DOCTYPE NETSCAPE-Bookmark-file-1>
Expand Down
43 changes: 9 additions & 34 deletions app/browser/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const appConstants = require('../../js/constants/appConstants')
const windowConstants = require('../../js/constants/windowConstants')
const messages = require('../../js/constants/messages')
const settings = require('../../js/constants/settings')
const siteTags = require('../../js/constants/siteTags')

// State
const {getByTabId} = require('../common/state/tabState')
Expand All @@ -35,8 +34,8 @@ const frameStateUtil = require('../../js/state/frameStateUtil')
const menuUtil = require('../common/lib/menuUtil')
const {getSetting} = require('../../js/settings')
const locale = require('../locale')
const {isLocationBookmarked} = require('../../js/state/siteUtil')
const platformUtil = require('../common/lib/platformUtil')
const bookmarkUtil = require('../common/lib/bookmarkUtil')
const isDarwin = platformUtil.isDarwin()
const isLinux = platformUtil.isLinux()
const isWindows = platformUtil.isWindows()
Expand Down Expand Up @@ -376,7 +375,7 @@ const updateRecentlyClosedMenuItems = (state) => {
}

const isCurrentLocationBookmarked = (state) => {
return isLocationBookmarked(state, currentLocation)
return bookmarkUtil.isLocationBookmarked(state, currentLocation)
}

const createBookmarksSubmenu = (state) => {
Expand Down Expand Up @@ -406,7 +405,7 @@ const createBookmarksSubmenu = (state) => {
CommonMenu.exportBookmarksMenuItem()
]

const bookmarks = menuUtil.createBookmarkTemplateItems(state.get('sites'))
const bookmarks = menuUtil.createBookmarkTemplateItems(state)
if (bookmarks.length > 0) {
submenu.push(CommonMenu.separatorMenuItem)
submenu = submenu.concat(bookmarks)
Expand Down Expand Up @@ -693,38 +692,14 @@ const doAction = (state, action) => {
}
break
}
case appConstants.APP_APPLY_SITE_RECORDS:
if (action.records && action.records.find((record) => record.objectData === 'bookmark')) {
createMenu(state)
}
break
case appConstants.APP_ADD_SITE:
case appConstants.APP_ADD_BOOKMARK:
case appConstants.APP_EDIT_BOOKMARK:
{
if (action.tag === siteTags.BOOKMARK || action.tag === siteTags.BOOKMARK_FOLDER) {
createMenu(state)
} else if (action.siteDetail && action.siteDetail.constructor === Immutable.List && action.tag === undefined) {
let shouldRebuild = false
action.siteDetail.forEach((site) => {
const tag = site.getIn(['tags', 0])
if (tag === siteTags.BOOKMARK || tag === siteTags.BOOKMARK_FOLDER) {
shouldRebuild = true
}
})
if (shouldRebuild) {
createMenu(state)
}
}
break
}
case appConstants.APP_REMOVE_SITE:
{
if (action.tag === siteTags.BOOKMARK || action.tag === siteTags.BOOKMARK_FOLDER) {
createMenu(state)
}
break
}
case appConstants.APP_REMOVE_BOOKMARK:
case appConstants.APP_ADD_BOOKMARK_FOLDER:
case appConstants.APP_EDIT_BOOKMARK_FOLDER:
case appConstants.APP_REMOVE_BOOKMARK_FOLDER:
createMenu(state)
break
case appConstants.APP_ON_CLEAR_BROWSING_DATA:
{
const defaults = state.get('clearBrowsingDataDefaults')
Expand Down
88 changes: 88 additions & 0 deletions app/browser/reducers/bookmarkFoldersReducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

const Immutable = require('immutable')

// State
const bookmarkFoldersState = require('../../common/state/bookmarkFoldersState')

// Constants
const appConstants = require('../../../js/constants/appConstants')

// Utils
const {makeImmutable} = require('../../common/state/immutableUtil')
const syncUtil = require('../../../js/state/syncUtil')

const bookmarkFoldersReducer = (state, action, immutableAction) => {
action = immutableAction || makeImmutable(action)
switch (action.get('actionType')) {
case appConstants.APP_ADD_BOOKMARK_FOLDER:
{
const closestKey = action.get('closestKey')
let folder = action.get('folderDetails')

if (folder == null) {
break
}

if (Immutable.List.isList(folder)) {
action.get('folderDetails', Immutable.List()).forEach((folder) => {
state = bookmarkFoldersState.addFolder(state, folder, closestKey)

if (syncUtil.syncEnabled()) {
state = syncUtil.updateSiteCache(state, folder)
}
})
} else {
state = bookmarkFoldersState.addFolder(state, folder, closestKey)

if (syncUtil.syncEnabled()) {
state = syncUtil.updateSiteCache(state, folder)
}
}
break
}
case appConstants.APP_EDIT_BOOKMARK_FOLDER:
{
let folder = action.get('folderDetails')

if (folder == null) {
break
}

state = bookmarkFoldersState.editFolder(state, folder, action.get('editKey'))

if (syncUtil.syncEnabled()) {
state = syncUtil.updateSiteCache(state, folder)
}

break
}
case appConstants.APP_MOVE_BOOKMARK_FOLDER:
{
state = bookmarkFoldersState.moveFolder(
state,
action.get('folderKey'),
action.get('destinationKey'),
action.get('append'),
action.get('moveIntoParent')
)

if (syncUtil.syncEnabled()) {
const destinationDetail = state.getIn(['sites', action.get('destinationKey')])
state = syncUtil.updateSiteCache(state, destinationDetail)
}
break
}
case appConstants.APP_REMOVE_BOOKMARK_FOLDER:
{
state = bookmarkFoldersState.removeFolder(state, action.get('folderKey'))
break
}
}

return state
}

module.exports = bookmarkFoldersReducer
Loading

0 comments on commit 0802623

Please sign in to comment.