mirror of
https://github.com/penxio/penx.git
synced 2026-04-19 03:03:06 -04:00
242 lines
6.1 KiB
TypeScript
242 lines
6.1 KiB
TypeScript
import { storage } from '@/lib/storage'
|
|
import { format } from 'date-fns'
|
|
import { defaultEditorContent } from '@penx/constants'
|
|
import { Creation, Struct } from '@penx/domain'
|
|
import { localDB } from '@penx/local-db'
|
|
import {
|
|
BrowserTabProps,
|
|
IAreaNode,
|
|
ICreationNode,
|
|
IStructNode,
|
|
NodeType,
|
|
} from '@penx/model-type'
|
|
import {
|
|
ColumnType,
|
|
CreationStatus,
|
|
GateType,
|
|
SessionData,
|
|
StructType,
|
|
} from '@penx/types'
|
|
import { uniqueId } from '@penx/unique-id'
|
|
import { getSpaceInfo } from './getSpaceInfo'
|
|
import { sendMessage } from './message'
|
|
|
|
interface Tab {
|
|
status?: string | undefined
|
|
index: number
|
|
openerTabId?: number | undefined
|
|
title?: string | undefined
|
|
url?: string | undefined
|
|
pendingUrl?: string | undefined
|
|
pinned: boolean
|
|
highlighted: boolean
|
|
windowId: number
|
|
active: boolean
|
|
favIconUrl?: string | undefined
|
|
frozen: boolean
|
|
id?: number | undefined
|
|
incognito: boolean
|
|
selected: boolean
|
|
audible?: boolean | undefined
|
|
discarded: boolean
|
|
autoDiscardable: boolean
|
|
mutedInfo?: {
|
|
muted: boolean
|
|
}
|
|
width?: number | undefined
|
|
height?: number | undefined
|
|
sessionId?: string | undefined
|
|
groupId: number
|
|
lastAccessed?: number | undefined
|
|
}
|
|
|
|
export async function syncTabs() {
|
|
const session = await storage.getSession()
|
|
|
|
if (session) {
|
|
syncInitialTabs(session)
|
|
}
|
|
|
|
browser.tabs.onCreated.addListener((tab) => {
|
|
console.log('Tab created:', tab)
|
|
})
|
|
|
|
browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
|
|
// console.log('Tab updated:', tabId, changeInfo, tab)
|
|
|
|
if (changeInfo.status === 'complete') {
|
|
// console.log('>>>>>>Tab ' + tabId + ' finished loading:', tab.url, tab)
|
|
|
|
const { tabNodes, tabStruct, area } = await getSpaceInfo()
|
|
|
|
const existed = tabNodes.find((t) => {
|
|
const creation = new Creation(t)
|
|
const fields = creation.getCells<BrowserTabProps>(new Struct(tabStruct))
|
|
return fields.id === tab.id
|
|
})
|
|
|
|
// console.log('======existed:', existed)
|
|
if (existed) {
|
|
const creation = new Creation(existed)
|
|
const fields = creation.getCells<BrowserTabProps>(new Struct(tabStruct))
|
|
if (fields.url !== tab.url) {
|
|
const cells = getCells(tab, tabStruct)
|
|
await localDB.updateCreationProps(existed.id, {
|
|
...existed.props,
|
|
title: tab.title,
|
|
cells,
|
|
})
|
|
|
|
sendMessage('updateBrowserTab', {})
|
|
}
|
|
} else {
|
|
await createTabCreation(tab, area, tabStruct)
|
|
sendMessage('updateBrowserTab', {})
|
|
}
|
|
}
|
|
|
|
if (changeInfo.url) {
|
|
// console.log(
|
|
// '>>>>>>>>Tab ' + tabId + ' url changed to:',
|
|
// changeInfo.url,
|
|
// tab,
|
|
// )
|
|
}
|
|
})
|
|
|
|
browser.tabs.onRemoved.addListener(async (tabId, removeInfo) => {
|
|
console.log('Tab removed:', tabId, removeInfo)
|
|
|
|
const { tabNodes, tabStruct } = await getSpaceInfo()
|
|
|
|
const existed = tabNodes.find((t) => {
|
|
const creation = new Creation(t)
|
|
const fields = creation.getCells<BrowserTabProps>(new Struct(tabStruct))
|
|
return fields.id === tabId
|
|
})
|
|
|
|
if (existed) {
|
|
await localDB.node.delete(existed.id)
|
|
sendMessage('updateBrowserTab', {})
|
|
}
|
|
})
|
|
|
|
browser.tabs.onActivated.addListener(function (activeInfo) {
|
|
console.log('Tab activated:', activeInfo)
|
|
})
|
|
|
|
browser.tabs.onAttached.addListener((tabId, attachInfo) => {
|
|
console.log(
|
|
'tab ' +
|
|
tabId +
|
|
' attached to window ' +
|
|
attachInfo.newWindowId +
|
|
' at position ' +
|
|
attachInfo.newPosition,
|
|
)
|
|
})
|
|
|
|
browser.tabs.onDetached.addListener((tabId, detachInfo) => {
|
|
console.log(
|
|
'tab ' +
|
|
tabId +
|
|
' detached from window ' +
|
|
detachInfo.oldWindowId +
|
|
' at position ' +
|
|
detachInfo.oldPosition,
|
|
)
|
|
})
|
|
|
|
browser.tabs.onReplaced.addListener((addedTabId, removedTabId) => {
|
|
console.log(
|
|
'tab ' + removedTabId + ' has been replaced by tab ' + addedTabId,
|
|
)
|
|
})
|
|
}
|
|
|
|
async function syncInitialTabs(session: SessionData) {
|
|
let tabs = await browser.tabs.query({})
|
|
|
|
// console.log('==========tabs:', tabs)
|
|
|
|
const { tabNodes, tabStruct, area } = await getSpaceInfo()
|
|
// console.log('=======>>>>>>>>>tabNodes:', tabNodes)
|
|
|
|
if (tabNodes.length) return
|
|
|
|
for (const tab of tabs) {
|
|
createTabCreation(tab, area, tabStruct)
|
|
}
|
|
}
|
|
|
|
function getCells(tab: Tab, tabStruct: IStructNode) {
|
|
const cells = tabStruct.props.columns.reduce(
|
|
(acc, column) => {
|
|
let value: any = ''
|
|
if (column.slug === 'id') value = tab.id
|
|
if (column.slug === 'windowId') value = tab.windowId
|
|
if (column.slug === 'url') value = tab.url
|
|
if (column.slug === 'favIconUrl') value = tab.favIconUrl
|
|
if (column.slug === 'active') value = tab.active
|
|
if (column.slug === 'muted') value = tab.mutedInfo?.muted
|
|
if (column.slug === 'pinned') value = tab.pinned
|
|
if (column.slug === 'lastAccessed') value = tab.lastAccessed
|
|
if (column.slug === 'index') value = tab.index
|
|
|
|
return { ...acc, [column.id]: value }
|
|
},
|
|
{} as Record<string, any>,
|
|
)
|
|
return cells
|
|
}
|
|
|
|
async function createTabCreation(
|
|
tab: Tab,
|
|
area: IAreaNode,
|
|
tabStruct: IStructNode,
|
|
) {
|
|
const cells = getCells(tab, tabStruct)
|
|
|
|
const props: ICreationNode['props'] = {
|
|
slug: uniqueId(),
|
|
title: tab.title || '',
|
|
description: '',
|
|
content: defaultEditorContent,
|
|
data: {},
|
|
icon: '',
|
|
image: '',
|
|
type: tabStruct.type,
|
|
cells,
|
|
podcast: {},
|
|
i18n: {},
|
|
gateType: GateType.FREE,
|
|
status: CreationStatus.DRAFT,
|
|
commentStatus: 'OPEN',
|
|
featured: false,
|
|
collectible: false,
|
|
structId: tabStruct.id,
|
|
isJournal: false,
|
|
isPopular: false,
|
|
checked: false,
|
|
delivered: false,
|
|
commentCount: 0,
|
|
cid: '',
|
|
openedAt: new Date(),
|
|
date: format(new Date(), 'yyyy-MM-dd'),
|
|
}
|
|
|
|
const newCreation: ICreationNode = {
|
|
id: uniqueId(),
|
|
spaceId: area.spaceId,
|
|
type: NodeType.CREATION,
|
|
areaId: area.id,
|
|
props,
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
userId: area.userId,
|
|
}
|
|
|
|
// console.log('=====cells:', cells, 'newCreation:', newCreation)
|
|
await localDB.addCreation(newCreation)
|
|
}
|