Skip to content

Commit

Permalink
feat: store into a specific list
Browse files Browse the repository at this point in the history
 - feat: allow store tabs into a specific list by clicking the items in context menu or a button in the simple list
 - feat: right clicking an item in the list will show a menu allows moving the tab to another list
  • Loading branch information
cnwangjie committed Oct 2, 2018
1 parent 94b23ea commit 9df3fcd
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 55 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### v1.3.10 10/3/2018

- feat: allow store tabs into a specific list by clicking the items in context menu or a button in the simple list
- feat: right clicking an item in the list will show a menu allows moving the tab to another list

### v1.3.9 9/29/2018

- feat: add an option to allow open tabs at the ending
Expand Down
12 changes: 12 additions & 0 deletions src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
"menu_STORE_TWOSIDE_TABS": {
"message": "store unselected tabs"
},
"menu_STORE": {
"message": "store"
},
"menu_STORE_TO_TITLED_LIST": {
"message": "store into a titled list"
},
"cmd_store_selected_tabs": {
"message": "Store selected tabs"
},
Expand Down Expand Up @@ -355,5 +361,11 @@
},
"ui_click_view_changelog": {
"message": "click to view detail changelog"
},
"ui_move_to": {
"message": "Move to"
},
"ui_a_new_list": {
"message": "(a new list)"
}
}
12 changes: 12 additions & 0 deletions src/_locales/zh_CN/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
"menu_STORE_TWOSIDE_TABS": {
"message": "储存未选中的标签"
},
"menu_STORE": {
"message": "储存"
},
"menu_STORE_TO_TITLED_LIST": {
"message": "储存至"
},
"cmd_store_selected_tabs": {
"message": "储存选中的标签"
},
Expand Down Expand Up @@ -346,5 +352,11 @@
},
"ui_click_view_changelog": {
"message": "点击查看详细更新日志"
},
"ui_move_to": {
"message": "移动至"
},
"ui_a_new_list": {
"message": "(一个新列表)"
}
}
151 changes: 115 additions & 36 deletions src/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,65 +59,137 @@ const updateBrowserAction = (action, tmp = false) => {
}
}

const setupContextMenus = async ({pageContext, allContext}) => {
const dynamicDisableMenu = async () => {
const groupedTabs = await tabs.groupTabsInCurrentWindow()
const windows = await browser.windows.getAll()
browser.contextMenus.update('STORE.STORE_LEFT_TABS', {
enabled: groupedTabs.left.length !== 0,
title: __('menu_STORE_LEFT_TABS') + ` (${groupedTabs.left.length})`,
})
browser.contextMenus.update('STORE.STORE_RIGHT_TABS', {
enabled: groupedTabs.right.length !== 0,
title: __('menu_STORE_RIGHT_TABS') + ` (${groupedTabs.right.length})`,
})
browser.contextMenus.update('STORE.STORE_TWOSIDE_TABS', {
enabled: groupedTabs.twoSide.length !== 0,
title: __('menu_STORE_TWOSIDE_TABS') + ` (${groupedTabs.twoSide.length})`,
})
browser.contextMenus.update('STORE.STORE_ALL_TABS_IN_ALL_WINDOWS', {
enabled: windows.length > 1,
title: __('menu_STORE_ALL_TABS_IN_ALL_WINDOWS') + ` (${groupedTabs.all.length})`,
})
browser.contextMenus.update('STORE.STORE_ALL_TABS_IN_CURRENT_WINDOW', {
title: __('menu_STORE_ALL_TABS_IN_CURRENT_WINDOW') + ` (${groupedTabs.all.length})`,
})
browser.contextMenus.update('STORE_SELECTED_TABS', {
title: __('menu_STORE_SELECTED_TABS') + ` (${groupedTabs.inter.length})`,
})
const lists = await storage.getLists()
for (let i = 0; i < lists.length; i += 1) {
if (!lists[i].title) continue
browser.contextMenus.update('STORE_TO_TITLED_LIST.STORE_LEFT_TABS|' + i, {
enabled: groupedTabs.left.length !== 0,
title: __('menu_STORE_LEFT_TABS') + ` (${groupedTabs.left.length})`,
})
browser.contextMenus.update('STORE_TO_TITLED_LIST.STORE_RIGHT_TABS|' + i, {
enabled: groupedTabs.right.length !== 0,
title: __('menu_STORE_RIGHT_TABS') + ` (${groupedTabs.right.length})`,
})
browser.contextMenus.update('STORE_TO_TITLED_LIST.STORE_TWOSIDE_TABS|' + i, {
enabled: groupedTabs.twoSide.length !== 0,
title: __('menu_STORE_TWOSIDE_TABS') + ` (${groupedTabs.twoSide.length})`,
})
browser.contextMenus.update('STORE_TO_TITLED_LIST.STORE_ALL_TABS_IN_CURRENT_WINDOW|' + i, {
title: __('menu_STORE_ALL_TABS_IN_CURRENT_WINDOW') + ` (${groupedTabs.all.length})`,
})
browser.contextMenus.update('STORE_TO_TITLED_LIST.STORE_SELECTED_TABS|' + i, {
title: __('menu_STORE_SELECTED_TABS') + ` (${groupedTabs.inter.length})`,
})
}
}

const setupContextMenus = _.debounce(async ({pageContext, allContext}) => {
await browser.contextMenus.removeAll()
const contexts = [browser.contextMenus.ContextType.BROWSER_ACTION]
if (pageContext) {
contexts.push(browser.contextMenus.ContextType.PAGE)
if (allContext) contexts.push(browser.contextMenus.ContextType.ALL)
}
const menus = {
STORE_SELECTED_TABS: tabs.storeSelectedTabs,
STORE_ALL_TABS_IN_CURRENT_WINDOW: tabs.storeAllTabs,
SHOW_TAB_LIST: tabs.openTabLists,
STORE_ALL_TABS_IN_ALL_WINDOWS: tabs.storeAllTabInAllWindows,
EXTRA: {
STORE_SELECTED_TABS: tabs.storeSelectedTabs,
STORE: {
STORE_ALL_TABS_IN_CURRENT_WINDOW: tabs.storeAllTabs,
STORE_ALL_TABS_IN_ALL_WINDOWS: tabs.storeAllTabInAllWindows,
STORE_LEFT_TABS: tabs.storeLeftTabs,
STORE_RIGHT_TABS: tabs.storeRightTabs,
STORE_TWOSIDE_TABS: tabs.storeTwoSideTabs,
},
STORE_TO_TITLED_LIST: {
STORE_SELECTED_TABS: tabs.storeSelectedTabs,
STORE_ALL_TABS_IN_CURRENT_WINDOW: tabs.storeAllTabs,
STORE_LEFT_TABS: tabs.storeLeftTabs,
STORE_RIGHT_TABS: tabs.storeRightTabs,
STORE_TWOSIDE_TABS: tabs.storeTwoSideTabs,
}
}
const lists = await storage.getLists()
const createMenus = async (obj, parent) => {
for (const key of Object.keys(obj)) {
const prop = {
id: key,
title: __('menu_' + key),
contexts,
if (obj === menus.STORE_TO_TITLED_LIST) {
for (let listIndex = 0; listIndex < lists.length; listIndex += 1) {
if (!lists[listIndex].title) continue
const prop = {
id: 'STORE_TO_TITLED_LIST|' + listIndex,
title: lists[listIndex].title,
contexts,
parentId: 'STORE_TO_TITLED_LIST',
}
const id = await browser.contextMenus.create(prop)
console.log('context menu created: ' + id)
for (const key in obj) {
const prop = {
id: 'STORE_TO_TITLED_LIST.' + key + '|' + listIndex,
title: __('menu_' + key),
contexts,
parentId: id,
}
const childId = await browser.contextMenus.create(prop)
console.log('context menu created: ' + childId)
}
}
if (parent) {
prop.id = parent + '.' + key
prop.parentId = parent
} else {
for (const key of Object.keys(obj)) {
const prop = {
id: key,
title: __('menu_' + key),
contexts,
}
if (parent) {
prop.id = parent + '.' + key
prop.parentId = parent
}
const id = await browser.contextMenus.create(prop)
console.log('context menu created: ' + id)
if (_.isObject(obj[key])) await createMenus(obj[key], key)
}
const id = await browser.contextMenus.create(prop)
console.log('context menu created: ' + id)
if (_.isObject(obj[key])) await createMenus(obj[key], key)
}
}
window.contextMenusClickedHandler = info => {
console.log('context menu clicked', info.menuItemId)
_.get(menus, info.menuItemId)()
if (PRODUCTION) ga('send', 'event', 'Menu clicked', info.menuItemId)
if (info.menuItemId.startsWith('STORE_TO_TITLED_LIST')) {
const [key, listIndex] = info.menuItemId.split('|')
_.get(menus, key)(+listIndex)
if (PRODUCTION) ga('send', 'event', 'Menu clicked', key)
} else {
_.get(menus, info.menuItemId)()
if (PRODUCTION) ga('send', 'event', 'Menu clicked', info.menuItemId)
}
}
console.groupCollapsed('create context menu', contexts)
await createMenus(menus)
console.groupEnd('create context menu')
}

const dynamicDisableMenu = async () => {
const groupedTabs = await tabs.groupTabsInCurrentWindow()
browser.contextMenus.update('EXTRA.STORE_LEFT_TABS', {
enabled: groupedTabs.left.length !== 0,
title: __('menu_STORE_LEFT_TABS') + ` (${groupedTabs.left.length})`,
})
browser.contextMenus.update('EXTRA.STORE_RIGHT_TABS', {
enabled: groupedTabs.right.length !== 0,
title: __('menu_STORE_RIGHT_TABS') + ` (${groupedTabs.right.length})`,
})
browser.contextMenus.update('EXTRA.STORE_TWOSIDE_TABS', {
enabled: groupedTabs.twoSide.length !== 0,
title: __('menu_STORE_TWOSIDE_TABS') + ` (${groupedTabs.twoSide.length})`,
})
}
dynamicDisableMenu()
}, 250)

const commandHandler = async command => {
console.log('received command', command)
Expand Down Expand Up @@ -184,13 +256,17 @@ const init = async () => {
if (msg.forceDownload) {
boss.forceDownloadRemoteImmediate()
}
if (msg.storeInto) {
tabs.storeSelectedTabs(msg.storeInto.index)
}
})
browser.runtime.onMessageExternal.addListener(commandHandler)
browser.commands.onCommand.addListener(commandHandler)
browser.runtime.onUpdateAvailable.addListener(detail => {
window.update = detail.version
})
browser.runtime.onInstalled.addListener(detail => {
if (DEBUG) return
if (detail.reason === chrome.runtime.OnInstalledReason.UPDATE) {
const updatedNotificationId = 'updated'
browser.notifications.onClicked.addListener(id => {
Expand All @@ -215,11 +291,14 @@ const init = async () => {
window.coverBrowserAction(activeInfo)
dynamicDisableMenu(activeInfo)
}, 200))
browser.storage.onChanged.addListener(changes => {
browser.storage.onChanged.addListener(async changes => {
console.log(changes)
if (changes.boss_token) {
window.boss_token = changes.boss_token
}
if (changes.lists) {
setupContextMenus(await storage.getOptions())
}
})
await boss.forceDownloadRemoteImmediate()
setInterval(() => boss.forceDownloadRemoteImmediate(), 60 * 1000)
Expand Down
29 changes: 17 additions & 12 deletions src/common/tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ const getAllTabsInCurrentWindow = async () => {

const groupTabsInCurrentWindow = async () => {
const tabs = await getAllTabsInCurrentWindow()
const result = { left: [], right: [] }
const result = { left: [], right: [], inter: [], all: tabs }
let currentIsRight = false
for (const tab of tabs) {
if (tab.highlighted) {
currentIsRight = true
result.inter.push(tab)
} else if (currentIsRight) result.right.push(tab)
else result.left.push(tab)
}
Expand All @@ -63,7 +64,7 @@ const isLegalURL = url => [
'about:', 'chrome:', 'file:', 'wss:'
].every(prefix => !url.startsWith(prefix))

const storeTabs = async tabs => {
const storeTabs = async (tabs, listIndex) => {
const appUrl = browser.runtime.getURL('')
tabs = tabs.filter(i => !i.url.startsWith(appUrl))
const opts = await storage.getOptions()
Expand All @@ -72,9 +73,13 @@ const storeTabs = async tabs => {
if (tabs.length === 0) return
browser.tabs.remove(tabs.map(i => i.id))
const lists = await storage.getLists()
const newList = list.createNewTabList({tabs: pickTabs(tabs)})
if (opts.pinNewList) newList.pinned = true
lists.unshift(newList)
if (listIndex == null) {
const newList = list.createNewTabList({tabs: pickTabs(tabs)})
if (opts.pinNewList) newList.pinned = true
lists.unshift(newList)
} else {
tabs.forEach(tab => lists[listIndex].tabs.push(tab))
}
await storage.setLists(lists)
if (opts.addHistory) {
for (let i = 0; i < tabs.length; i += 1) {
Expand All @@ -88,21 +93,21 @@ const storeTabs = async tabs => {
}
}

const storeLeftTabs = async () => storeTabs((await groupTabsInCurrentWindow()).left)
const storeRightTabs = async () => storeTabs((await groupTabsInCurrentWindow()).right)
const storeTwoSideTabs = async () => storeTabs((await groupTabsInCurrentWindow()).twoSide)
const storeLeftTabs = async listIndex => storeTabs((await groupTabsInCurrentWindow()).left, listIndex)
const storeRightTabs = async listIndex => storeTabs((await groupTabsInCurrentWindow()).right, listIndex)
const storeTwoSideTabs = async listIndex => storeTabs((await groupTabsInCurrentWindow()).twoSide, listIndex)

const storeSelectedTabs = async () => {
const storeSelectedTabs = async listIndex => {
const tabs = await getSelectedTabs()
const allTabs = await getAllTabsInCurrentWindow()
if (tabs.length === allTabs.length) await openTabLists()
return storeTabs(tabs)
return storeTabs(tabs, listIndex)
}

const storeAllTabs = async () => {
const storeAllTabs = async listIndex => {
const tabs = await getAllTabsInCurrentWindow()
await openTabLists()
return storeTabs(tabs)
return storeTabs(tabs, listIndex)
}

const storeAllTabInAllWindows = async () => {
Expand Down
2 changes: 1 addition & 1 deletion src/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "__MSG_ext_name__",
"version": "1.3.9",
"version": "1.3.10",
"default_locale": "en",
"description": "__MSG_ext_desc__",
"author": "WangJie <[email protected]>",
Expand Down
Loading

0 comments on commit 9df3fcd

Please sign in to comment.