Skip to content

Commit

Permalink
feat: get list service
Browse files Browse the repository at this point in the history
  • Loading branch information
cnwangjie committed Nov 13, 2021
1 parent a5612e0 commit 5d3fb97
Show file tree
Hide file tree
Showing 25 changed files with 312 additions and 105 deletions.
File renamed without changes.
6 changes: 4 additions & 2 deletions packages/ext/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,30 @@
"author": "cnwangjie",
"license": "MIT",
"scripts": {
"dev": "cross-env NODE_ENV=development webpack --watch --config webpack.common.js"
"dev": "cross-env TAILWIND_MODE=watch NODE_ENV=development webpack --watch --config webpack.common.js"
},
"dependencies": {
"@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0",
"@iconify/react": "^3.0.1",
"@mui/material": "^5.0.4",
"dayjs": "^1.10.7",
"lodash": "^4.17.21",
"pouchdb-adapter-idb": "^7.2.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.3.0",
"rxdb": "^10.2.1",
"rxjs": "^7.4.0",
"webextension-polyfill-ts": "^0.26.0"
"swr": "^1.0.1"
},
"devDependencies": {
"@types/history": "^4.7.9",
"@types/lodash": "^4.14.176",
"@types/react": "^17.0.31",
"@types/react-dom": "^17.0.10",
"@types/react-router-dom": "^5.3.1",
"@types/webextension-polyfill": "^0.8.1",
"autoprefixer": "^10.3.7",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^9.0.1",
Expand Down
47 changes: 30 additions & 17 deletions packages/ext/src/app/layout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
Typography,
} from '@mui/material'
import React, { FC, useState } from 'react'
import { Link } from 'react-router-dom'

const drawerWidth = 240

Expand Down Expand Up @@ -112,7 +113,19 @@ const StyledListItemButton = styled(ListItemButton, {
}),
}))

const AppLayout: FC = ({ children }) => {
interface Tab {
key: string
icon: string
label: string
to: string
}

interface AppLayoutProps {
tabs: Tab[]
activeTab: string
}

const AppLayout: FC<AppLayoutProps> = ({ tabs, activeTab, children }) => {
const [open, setOpen] = useState(false)

// TODO: hide shadow scroll Y is 0
Expand All @@ -137,27 +150,27 @@ const AppLayout: FC = ({ children }) => {
<DrawerHeader />

<List>
<StyledListItemButton open={open} selected>
<ListItemIcon>
<Icon icon="mdi:view-list" fontSize={24} />
</ListItemIcon>
<ListItemText primary="Tab lists" />
</StyledListItemButton>

<StyledListItemButton open={open}>
<ListItemIcon>
<Icon icon="mdi:pin-outline" fontSize={24} />
</ListItemIcon>
<ListItemText primary="Pinned" />
</StyledListItemButton>
{tabs.map(tab => {
return (
<Link to={tab.to} key={tab.key}>
<StyledListItemButton
open={open}
selected={tab.key === activeTab}
>
<ListItemIcon>
<Icon icon={tab.icon} fontSize={24} />
</ListItemIcon>
<ListItemText primary={tab.label} />
</StyledListItemButton>
</Link>
)
})}
</List>
<Divider />
</StyledDrawer>

<div className="flex-1 mt-[64px] p-8">
<Container>
{children}
</Container>
<Container>{children}</Container>
</div>
</div>
)
Expand Down
44 changes: 38 additions & 6 deletions packages/ext/src/app/pages/Main/DetailList/ListGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,46 @@
import { Accordion, AccordionDetails, AccordionSummary } from '@mui/material'
import React from 'react'
import {
Accordion,
AccordionDetails,
AccordionSummary,
Chip,
IconButton,
} from '@mui/material'
import React, { FC } from 'react'
import __ from 'src/common/util/i18n'
import { useListTabs } from 'src/app/service'
import { formatTime } from 'src/common/util/formatDate'
import { Icon } from '@iconify/react'

const ListGroup: FC<{ list: any }> = ({ list }) => {
const { data: tabs } = useListTabs(list.id)

const ListGroup = () => {
return (
<Accordion>
<Accordion className="group">
<AccordionSummary>
1
<div className="flex items-center gap-4 w-full h-7">
<Chip size="small" label={`${tabs?.length || 0} ${__('ui_tab')}`} />
{__('ui_created')} {formatTime(list.createdAt)}
<div className="flex-1" />
<div
className="hidden gap-1 group-hover:flex"
onClick={e => e.stopPropagation()}
>
<IconButton size="small">
<Icon icon="mdi:arrow-up" />
</IconButton>
<IconButton size="small">
<Icon icon="mdi:arrow-down" />
</IconButton>
<IconButton size="small">
<Icon icon="mdi:pin" />
</IconButton>
</div>
</div>
</AccordionSummary>
<AccordionDetails>
2
{tabs?.map((tab, index) => {
return <div key={index}>{tab.url}</div>
})}
</AccordionDetails>
</Accordion>
)
Expand Down
10 changes: 5 additions & 5 deletions packages/ext/src/app/pages/Main/DetailList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React from 'react'
import ListGroup from './ListGroup'
import { useLists } from '../../../service'

const DetailList = () => {
const [lists, setLists] = React.useState([
1,2,3,4
])
const { data } = useLists()

return (
<div>
{
lists.map(list => {
return <ListGroup key={list} />
data?.result.map(list => {
console.log(list)
return <ListGroup key={list.id} list={list} />
})
}
</div>
Expand Down
51 changes: 48 additions & 3 deletions packages/ext/src/app/pages/Main/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,57 @@
import React from 'react'
import { Route, Switch } from 'react-router-dom'
import React, { useMemo } from 'react'
import { matchPath, Route, Switch, useRouteMatch } from 'react-router-dom'
import AppLayout from '../../layout/AppLayout'
import DetailList from './DetailList'
import { history } from '../../App'

const routes = [
{
key: 'Tab lists',
label: 'Tab lists',
icon: 'mdi:view-list',
path: '/app/list',
exact: true,
},
{
key: 'Pinned',
label: 'Pinned',
icon: 'mdi:pin-outline',
path: '/app/list/pinned',
},
]

const Main = () => {
const tabs = useMemo(() => {
return routes.map(({ key, label, icon, path }) => {
return {
key,
label,
icon,
to: path,
}
})
}, [])

useRouteMatch()

const activeTab = useMemo(() => {
return (
routes.find(({ path, exact }) => {
const match = matchPath(history.location.pathname, {
path,
exact,
})
return match
}) || routes[0]
)
}, [history.location.pathname])

return (
<AppLayout>
<AppLayout tabs={tabs} activeTab={activeTab.key}>
<Switch>
<Route path="/app">
<DetailList />
</Route>
<Route path="/app/list">
<DetailList />
</Route>
Expand Down
23 changes: 23 additions & 0 deletions packages/ext/src/app/service/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import storage from 'src/common/storage'
import useSWR from 'swr'

type ThenArg<T> = T extends PromiseLike<infer U> ? U : never

const createSWR = <
F extends (...args: any[]) => Promise<T>,
T = ThenArg<ReturnType<F>>
>(
prefix: string,
fn: F,
requireArgs = false,
) => (...args: any[]) => {
const key = requireArgs && args.every(i => !i) ? null : [prefix, ...args]

return useSWR<T>(key, (_, ...args: any) => {
return fn(...args)
})
}

export const useLists = createSWR('lists', storage.lists.listList)

export const useListTabs = createSWR('listTab', storage.tabs.getSortedTabsByList, true)
2 changes: 1 addition & 1 deletion packages/ext/src/background/autoReload.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { browser } from 'webextension-polyfill-ts'
import browser from 'webextension-polyfill'

const filesInDirectory = (dir: any) =>
new Promise(resolve => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ext/src/background/browserAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { noop } from 'lodash'
import { BrowserAction, NewTabs } from 'src/common/constants'
import { browserActionConfigItems, optionsList } from 'src/common/options/list'
import { tabsManager } from 'src/common/tabsManager'
import { browser } from 'webextension-polyfill-ts'
import browser from 'webextension-polyfill'

const actions = {
[BrowserAction.StoreSelected]: tabsManager.storeSelectedTabs,
Expand Down
2 changes: 1 addition & 1 deletion packages/ext/src/background/contextMenus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Options } from 'src/common/options/types'
import storage from 'src/common/storage'
import { tabsManager } from 'src/common/tabsManager'
import { __ } from 'src/common/util/i18n'
import { browser, Menus } from 'webextension-polyfill-ts'
import browser, { Menus } from 'webextension-polyfill'

const SHOW_TAB_LIST = 'SHOW_TAB_LIST'
const STORE_SELECTED_TABS = 'STORE_SELECTED_TABS'
Expand Down
2 changes: 1 addition & 1 deletion packages/ext/src/background/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import storage from 'src/common/storage'
import { tabsManager } from 'src/common/tabsManager'
import { browser } from 'webextension-polyfill-ts'
import browser from 'webextension-polyfill'
import init from './init'

if (DEBUG) {
Expand Down
19 changes: 14 additions & 5 deletions packages/ext/src/background/init.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { debounce } from 'lodash'
import { getOptions } from 'src/common/options'
import storage from 'src/common/storage'
import { registerIpcHandlerDeeply, registerIpcListener } from 'src/common/util/ipc'
import { browser, Tabs } from 'webextension-polyfill-ts'
import { composeListeners } from 'src/common/util/composeListener'
import { createIpcListener, registerIpcHandlerDeeply } from 'src/common/util/ipc'
import browser, { Tabs } from 'webextension-polyfill'
import { updateBrowserAction } from './browserAction'
import commandHandler from './commandHandler'
import { dynamicDisableMenu, setupContextMenus } from './contextMenus'
Expand All @@ -14,9 +15,17 @@ const tabsChangedHandler = (activeInfo: Tabs.OnActivatedActiveInfoType) => {
dynamicDisableMenu()
}

const registerRuntimeMessageListener = async () => {
const ipcListener = await createIpcListener()
const listener = composeListeners(
ipcListener,
messageHandler,
)
await browser.runtime.onMessage.addListener(listener)
}

const init = async () => {
registerIpcHandlerDeeply(storage)
registerIpcListener()
registerIpcHandlerDeeply({ storage })

const opts = window.opts = await getOptions()
console.log(opts)
Expand All @@ -25,7 +34,7 @@ const init = async () => {
await Promise.all([
browser.commands.onCommand.addListener(commandHandler),
browser.runtime.onMessageExternal.addListener(commandHandler),
browser.runtime.onMessage.addListener(messageHandler),
registerRuntimeMessageListener(),
browser.runtime.onUpdateAvailable.addListener(detail => { window.update = detail.version }),
browser.contextMenus.onClicked.addListener(info => window.contextMenusClickedHandler(info)),
browser.tabs.onActivated.addListener(debounce(tabsChangedHandler, 200)),
Expand Down
8 changes: 5 additions & 3 deletions packages/ext/src/common/storage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { tabsStorage } from './tabs'
export const lists = listStorage
export const tabs = tabsStorage

export const storage = wrapBackgroundCommunicationDeeply({
lists,
tabs,
export const { storage } = wrapBackgroundCommunicationDeeply({
storage: {
lists,
tabs,
},
})

export default storage
2 changes: 1 addition & 1 deletion packages/ext/src/common/storage/lists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const getLatestList = async () => {

const listList = async (opt?: PaginateOpt) => {
const db = await getDB()
return paginate(db.lists)(opt)
return paginate<List>(db.lists)(opt)
}

export const listStorage = {
Expand Down
6 changes: 3 additions & 3 deletions packages/ext/src/common/storage/tabs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { sortBy } from "lodash";
import { RxDocument } from "rxdb";
import type * as Browser from "webextension-polyfill-ts";
import type { Tabs } from "webextension-polyfill";
import { genId } from "../util";
import { getDB } from "./db";

Expand Down Expand Up @@ -30,7 +30,7 @@ const initTabs = (tabs: any[], listId: string): Tab[] => {
})
}

const createTabs = async (tabs: Browser.Tabs.Tab[], listId: string) => {
const createTabs = async (tabs: Tabs.Tab[], listId: string) => {
const db = await getDB()
const tabsDocs = initTabs(tabs, listId)
const result = await db.tabs.bulkInsert(tabsDocs)
Expand All @@ -39,7 +39,7 @@ const createTabs = async (tabs: Browser.Tabs.Tab[], listId: string) => {
}
}

const getTabsByList = async (listId: string) => {
const getTabsByList = async (listId: string): Promise<Tab[]> => {
const db = await getDB()
const tabs = await db.tabs.find({ selector: { listId } }).exec()
return tabs
Expand Down
Loading

0 comments on commit 5d3fb97

Please sign in to comment.