This commit is contained in:
parent
5235a6ee87
commit
05ee49e7c4
14 changed files with 123 additions and 100 deletions
|
@ -65,7 +65,7 @@
|
|||
"@webext-core/proxy-service": "^1.2.0",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"danmaku": "^2.0.7",
|
||||
"danmu": "^0.12.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"framer-motion": "^11.11.1",
|
||||
"idb-keyval": "^6.2.1",
|
||||
|
|
|
@ -71,9 +71,9 @@ importers:
|
|||
clsx:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1
|
||||
danmaku:
|
||||
specifier: ^2.0.7
|
||||
version: 2.0.7
|
||||
danmu:
|
||||
specifier: ^0.12.0
|
||||
version: 0.12.0
|
||||
date-fns:
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0
|
||||
|
@ -136,7 +136,7 @@ importers:
|
|||
version: 2.5.3
|
||||
trystero:
|
||||
specifier: ^0.20.0
|
||||
version: 0.20.0(@libp2p/interface@2.1.2)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/message-hash@0.1.16)(@waku/proto@0.0.7)(@waku/relay@0.0.15(@libp2p/interface@2.1.2)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4))(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
version: 0.20.0(@libp2p/interface@1.7.0)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/message-hash@0.1.16)(@waku/proto@0.0.7)(@waku/relay@0.0.15(@libp2p/interface@1.7.0)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4))(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
type-fest:
|
||||
specifier: ^4.26.1
|
||||
version: 4.26.1
|
||||
|
@ -1132,9 +1132,6 @@ packages:
|
|||
'@libp2p/interface@1.7.0':
|
||||
resolution: {integrity: sha512-/zFyaIaIGW0aihhsH7/93vQdpWInUzFocxF11RO/029Y6h0SVjs24HHbils+DqaFDTqN+L7oNlBx2rM2MnmTjA==}
|
||||
|
||||
'@libp2p/interface@2.1.2':
|
||||
resolution: {integrity: sha512-uD4NapC+1qGX7RmgC1aehQm3pMs1MpO1DwuhUlAo1M6CyNxfs1Ha9jhg2T+G4u4CAJM6wffZTyPGnKnrR+M8Fw==}
|
||||
|
||||
'@libp2p/logger@4.0.20':
|
||||
resolution: {integrity: sha512-TTh2dhHsOTAlMPxSa9ncFPHa/0jTt+0AQxwHdlxg/OGLAgc9VRhnrhHUbJZp07Crcw4T/MOfS4KhjlxgqYgJRw==}
|
||||
|
||||
|
@ -2406,6 +2403,9 @@ packages:
|
|||
resolution: {integrity: sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
aidly@1.9.0:
|
||||
resolution: {integrity: sha512-OREY4n7SkhJZpxn94Exd4MeYni1MVPpHGe8dBxkuOSjqrlOTHchgjguaX8BNd0g3idoRNrkFBrmyJ+JWK+AROw==}
|
||||
|
||||
ajv@6.12.6:
|
||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||
|
||||
|
@ -2971,8 +2971,8 @@ packages:
|
|||
csstype@3.1.3:
|
||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||
|
||||
danmaku@2.0.7:
|
||||
resolution: {integrity: sha512-etJEa9tdfW6cp5pn5qLCr1oE9v+uSE7bZxeQUMFKjHNV0Z7JCIVO126NZ5KyKgeOZx3jXAXLkS4UH/CgIx4BPQ==}
|
||||
danmu@0.12.0:
|
||||
resolution: {integrity: sha512-29NnnQaVFJVWvfCNpt70nW9UV2ClLtryrkWvwz8Nrwe1qrd2M8LMEfEQCNdtXebn1enk6ropBfHq3S/uTiTj5A==}
|
||||
|
||||
dargs@8.1.0:
|
||||
resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==}
|
||||
|
@ -3834,6 +3834,9 @@ packages:
|
|||
hookable@5.5.3:
|
||||
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
|
||||
|
||||
hooks-plugin@1.3.0:
|
||||
resolution: {integrity: sha512-CuISP+7AhIca8ZoGRN4valoVwVPtOVkzA7MiVaLA2s9XNESADUI7WbLO67z17KU2onX/UA2n/ZRhMn9PdMzXVw==}
|
||||
|
||||
hosted-git-info@2.8.9:
|
||||
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
|
||||
|
||||
|
@ -5933,6 +5936,9 @@ packages:
|
|||
resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
small-queue@1.1.2:
|
||||
resolution: {integrity: sha512-K6zQPh7cRjkzv+upcwrOTbR4kU3neY3KZR2F1nc8Fuez8uJyh4BguOUs4KGKHcuzU1LJmK8yfCkMUZbconLe8Q==}
|
||||
|
||||
snake-case@3.0.4:
|
||||
resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
|
||||
|
||||
|
@ -7953,16 +7959,6 @@ snapshots:
|
|||
progress-events: 1.0.1
|
||||
uint8arraylist: 2.4.8
|
||||
|
||||
'@libp2p/interface@2.1.2':
|
||||
dependencies:
|
||||
'@multiformats/multiaddr': 12.3.1
|
||||
it-pushable: 3.2.3
|
||||
it-stream-types: 2.0.2
|
||||
multiformats: 13.3.0
|
||||
progress-events: 1.0.1
|
||||
uint8arraylist: 2.4.8
|
||||
optional: true
|
||||
|
||||
'@libp2p/logger@4.0.20':
|
||||
dependencies:
|
||||
'@libp2p/interface': 1.7.0
|
||||
|
@ -9273,7 +9269,7 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@waku/discovery@0.0.3(@libp2p/interface@2.1.2)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/proto@0.0.7)':
|
||||
'@waku/discovery@0.0.3(@libp2p/interface@1.7.0)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/proto@0.0.7)':
|
||||
dependencies:
|
||||
'@waku/enr': 0.0.26(@multiformats/multiaddr@12.3.1)
|
||||
'@waku/proto': 0.0.7
|
||||
|
@ -9282,11 +9278,11 @@ snapshots:
|
|||
hi-base32: 0.5.1
|
||||
uint8arrays: 5.1.0
|
||||
optionalDependencies:
|
||||
'@libp2p/interface': 2.1.2
|
||||
'@libp2p/interface': 1.7.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@waku/discovery@0.0.5(@libp2p/interface@2.1.2)(@multiformats/multiaddr@12.3.1)(libp2p@1.9.4)':
|
||||
'@waku/discovery@0.0.5(@libp2p/interface@1.7.0)(@multiformats/multiaddr@12.3.1)(libp2p@1.9.4)':
|
||||
dependencies:
|
||||
'@waku/core': 0.0.32(@multiformats/multiaddr@12.3.1)(libp2p@1.9.4)
|
||||
'@waku/enr': 0.0.26(@multiformats/multiaddr@12.3.1)
|
||||
|
@ -9298,7 +9294,7 @@ snapshots:
|
|||
hi-base32: 0.5.1
|
||||
uint8arrays: 5.1.0
|
||||
optionalDependencies:
|
||||
'@libp2p/interface': 2.1.2
|
||||
'@libp2p/interface': 1.7.0
|
||||
transitivePeerDependencies:
|
||||
- '@multiformats/multiaddr'
|
||||
- libp2p
|
||||
|
@ -9337,13 +9333,13 @@ snapshots:
|
|||
dependencies:
|
||||
protons-runtime: 5.5.0
|
||||
|
||||
'@waku/relay@0.0.15(@libp2p/interface@2.1.2)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4)':
|
||||
'@waku/relay@0.0.15(@libp2p/interface@1.7.0)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4)':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.5.0
|
||||
'@waku/core': 0.0.32(@multiformats/multiaddr@12.3.1)(libp2p@1.9.4)
|
||||
'@waku/interfaces': 0.0.27
|
||||
'@waku/proto': 0.0.8
|
||||
'@waku/sdk': 0.0.28(@libp2p/interface@2.1.2)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
'@waku/sdk': 0.0.28(@libp2p/interface@1.7.0)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
'@waku/utils': 0.0.20
|
||||
chai: 4.5.0
|
||||
debug: 4.3.7
|
||||
|
@ -9357,7 +9353,7 @@ snapshots:
|
|||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@waku/sdk@0.0.26(@libp2p/interface@2.1.2)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/message-hash@0.1.16)(@waku/relay@0.0.15(@libp2p/interface@2.1.2)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4))(bufferutil@4.0.8)(utf-8-validate@6.0.4)':
|
||||
'@waku/sdk@0.0.26(@libp2p/interface@1.7.0)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/message-hash@0.1.16)(@waku/relay@0.0.15(@libp2p/interface@1.7.0)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4))(bufferutil@4.0.8)(utf-8-validate@6.0.4)':
|
||||
dependencies:
|
||||
'@chainsafe/libp2p-noise': 14.1.0
|
||||
'@libp2p/identify': 1.0.21
|
||||
|
@ -9365,10 +9361,10 @@ snapshots:
|
|||
'@libp2p/ping': 1.1.6
|
||||
'@libp2p/websockets': 8.2.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
'@noble/hashes': 1.5.0
|
||||
'@waku/discovery': 0.0.3(@libp2p/interface@2.1.2)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/proto@0.0.7)
|
||||
'@waku/discovery': 0.0.3(@libp2p/interface@1.7.0)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/proto@0.0.7)
|
||||
'@waku/message-hash': 0.1.16
|
||||
'@waku/proto': 0.0.7
|
||||
'@waku/relay': 0.0.15(@libp2p/interface@2.1.2)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4)
|
||||
'@waku/relay': 0.0.15(@libp2p/interface@1.7.0)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4)
|
||||
libp2p: 1.9.4
|
||||
transitivePeerDependencies:
|
||||
- '@libp2p/interface'
|
||||
|
@ -9377,7 +9373,7 @@ snapshots:
|
|||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@waku/sdk@0.0.28(@libp2p/interface@2.1.2)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(utf-8-validate@6.0.4)':
|
||||
'@waku/sdk@0.0.28(@libp2p/interface@1.7.0)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(utf-8-validate@6.0.4)':
|
||||
dependencies:
|
||||
'@chainsafe/libp2p-noise': 15.1.2
|
||||
'@libp2p/identify': 2.1.5
|
||||
|
@ -9386,7 +9382,7 @@ snapshots:
|
|||
'@libp2p/websockets': 8.2.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
'@noble/hashes': 1.5.0
|
||||
'@waku/core': 0.0.32(@multiformats/multiaddr@12.3.1)(libp2p@1.9.4)
|
||||
'@waku/discovery': 0.0.5(@libp2p/interface@2.1.2)(@multiformats/multiaddr@12.3.1)(libp2p@1.9.4)
|
||||
'@waku/discovery': 0.0.5(@libp2p/interface@1.7.0)(@multiformats/multiaddr@12.3.1)(libp2p@1.9.4)
|
||||
'@waku/interfaces': 0.0.27
|
||||
'@waku/message-hash': 0.1.16
|
||||
'@waku/proto': 0.0.8
|
||||
|
@ -9465,6 +9461,10 @@ snapshots:
|
|||
clean-stack: 5.2.0
|
||||
indent-string: 5.0.0
|
||||
|
||||
aidly@1.9.0:
|
||||
dependencies:
|
||||
small-queue: 1.1.2
|
||||
|
||||
ajv@6.12.6:
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
|
@ -10062,7 +10062,10 @@ snapshots:
|
|||
|
||||
csstype@3.1.3: {}
|
||||
|
||||
danmaku@2.0.7: {}
|
||||
danmu@0.12.0:
|
||||
dependencies:
|
||||
aidly: 1.9.0
|
||||
hooks-plugin: 1.3.0
|
||||
|
||||
dargs@8.1.0: {}
|
||||
|
||||
|
@ -11181,6 +11184,10 @@ snapshots:
|
|||
|
||||
hookable@5.5.3: {}
|
||||
|
||||
hooks-plugin@1.3.0:
|
||||
dependencies:
|
||||
aidly: 1.9.0
|
||||
|
||||
hosted-git-info@2.8.9: {}
|
||||
|
||||
hosted-git-info@7.0.2:
|
||||
|
@ -13525,6 +13532,8 @@ snapshots:
|
|||
ansi-styles: 6.2.1
|
||||
is-fullwidth-code-point: 5.0.0
|
||||
|
||||
small-queue@1.1.2: {}
|
||||
|
||||
snake-case@3.0.4:
|
||||
dependencies:
|
||||
dot-case: 3.0.4
|
||||
|
@ -13892,13 +13901,13 @@ snapshots:
|
|||
|
||||
trough@2.2.0: {}
|
||||
|
||||
trystero@0.20.0(@libp2p/interface@2.1.2)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/message-hash@0.1.16)(@waku/proto@0.0.7)(@waku/relay@0.0.15(@libp2p/interface@2.1.2)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4))(bufferutil@4.0.8)(utf-8-validate@6.0.4):
|
||||
trystero@0.20.0(@libp2p/interface@1.7.0)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/message-hash@0.1.16)(@waku/proto@0.0.7)(@waku/relay@0.0.15(@libp2p/interface@1.7.0)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4))(bufferutil@4.0.8)(utf-8-validate@6.0.4):
|
||||
dependencies:
|
||||
'@noble/curves': 1.6.0
|
||||
'@supabase/supabase-js': 2.45.4(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
'@thaunknown/simple-peer': 10.0.10
|
||||
'@waku/discovery': 0.0.3(@libp2p/interface@2.1.2)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/proto@0.0.7)
|
||||
'@waku/sdk': 0.0.26(@libp2p/interface@2.1.2)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/message-hash@0.1.16)(@waku/relay@0.0.15(@libp2p/interface@2.1.2)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4))(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
'@waku/discovery': 0.0.3(@libp2p/interface@1.7.0)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/proto@0.0.7)
|
||||
'@waku/sdk': 0.0.26(@libp2p/interface@1.7.0)(@waku/enr@0.0.26(@multiformats/multiaddr@12.3.1))(@waku/message-hash@0.1.16)(@waku/relay@0.0.15(@libp2p/interface@1.7.0)(@multiformats/multiaddr@12.3.1)(bufferutil@4.0.8)(libp2p@1.9.4)(utf-8-validate@6.0.4))(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
firebase: 10.14.0
|
||||
libp2p: 1.9.4
|
||||
mqtt: 5.10.1(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
|
|
|
@ -9,7 +9,7 @@ export default defineBackground({
|
|||
|
||||
main() {
|
||||
browser.runtime.onMessage.addListener(async (event: EVENT) => {
|
||||
if (event === EVENT.OPEN_OPTIONS_PAGE) {
|
||||
if (event === EVENT.OPTIONS_PAGE_OPEN) {
|
||||
browser.runtime.openOptionsPage()
|
||||
}
|
||||
})
|
||||
|
|
|
@ -52,7 +52,7 @@ export default function App() {
|
|||
useEffect(() => {
|
||||
danmakuIsEnabled && send(danmakuDomain.command.MountCommand(danmakuContainerRef.current!))
|
||||
return () => {
|
||||
danmakuIsEnabled && send(danmakuDomain.command.DestroyCommand())
|
||||
danmakuIsEnabled && send(danmakuDomain.command.UnmountCommand())
|
||||
}
|
||||
}, [danmakuIsEnabled])
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ export interface DanmakuContainerProps {
|
|||
const DanmakuContainer = forwardRef<HTMLDivElement, DanmakuContainerProps>(({ className }, ref) => {
|
||||
return (
|
||||
<div
|
||||
className={cn('fixed left-0 top-20 z-infinity w-full h-full invisible pointer-events-none shadow-md', className)}
|
||||
className={cn('fixed left-0 top-0 z-infinity w-full h-full invisible pointer-events-none shadow-md', className)}
|
||||
ref={ref}
|
||||
></div>
|
||||
)
|
||||
|
|
|
@ -1,18 +1,33 @@
|
|||
import { Avatar, AvatarFallback } from '@/components/ui/Avatar'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { APP_STATUS_STORAGE_KEY } from '@/constants/config'
|
||||
import { EVENT } from '@/constants/event'
|
||||
import { AppStatus } from '@/domain/AppStatus'
|
||||
import { LocalStorageImpl } from '@/domain/impls/Storage'
|
||||
import { TextMessage } from '@/domain/Room'
|
||||
import { cn } from '@/utils'
|
||||
import { AvatarImage } from '@radix-ui/react-avatar'
|
||||
import { FC } from 'react'
|
||||
import { FC, MouseEvent } from 'react'
|
||||
|
||||
export interface PromptItemProps {
|
||||
data: TextMessage
|
||||
className?: string
|
||||
onMouseEnter?: (e: MouseEvent<HTMLButtonElement>) => void
|
||||
onMouseLeave?: (e: MouseEvent<HTMLButtonElement>) => void
|
||||
}
|
||||
|
||||
const DanmakuMessage: FC<PromptItemProps> = ({ data, className }) => {
|
||||
const DanmakuMessage: FC<PromptItemProps> = ({ data, className, onMouseEnter, onMouseLeave }) => {
|
||||
const handleOpenApp = async () => {
|
||||
const appStatus = await LocalStorageImpl.value.get<AppStatus>(APP_STATUS_STORAGE_KEY)
|
||||
LocalStorageImpl.value.set<AppStatus>(APP_STATUS_STORAGE_KEY, { ...appStatus!, open: true, unread: 0 })
|
||||
dispatchEvent(new CustomEvent(EVENT.APP_OPEN))
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
onClick={handleOpenApp}
|
||||
className={cn(
|
||||
'flex justify-center pointer-events-auto visible gap-x-2 border px-2.5 py-0.5 rounded-full bg-primary/30 text-base font-medium text-white backdrop-blur-md',
|
||||
className
|
||||
|
|
|
@ -56,7 +56,7 @@ const AppButton: FC = () => {
|
|||
}
|
||||
|
||||
const handleOpenOptionsPage = () => {
|
||||
browser.runtime.sendMessage(EVENT.OPEN_OPTIONS_PAGE)
|
||||
browser.runtime.sendMessage(EVENT.OPTIONS_PAGE_OPEN)
|
||||
}
|
||||
|
||||
const handleToggleApp = () => {
|
||||
|
|
|
@ -191,7 +191,7 @@ export const MESSAGE_LIST_STORAGE_KEY = 'WEB_CHAT_MESSAGE_LIST' as const
|
|||
|
||||
export const USER_INFO_STORAGE_KEY = 'WEB_CHAT_USER_INFO' as const
|
||||
|
||||
export const APP_STATUS_STORAGE_KEY = 'WEB_CHAT_APP_OPEN_STATUS' as const
|
||||
export const APP_STATUS_STORAGE_KEY = 'WEB_CHAT_APP_STATUS' as const
|
||||
/**
|
||||
* In chrome storage.sync, each key-value pair supports a maximum storage of 8kb
|
||||
* Image is encoded as base64, and the size is increased by about 33%.
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export enum EVENT {
|
||||
OPEN_OPTIONS_PAGE = 'OPEN_OPTIONS_PAGE'
|
||||
OPTIONS_PAGE_OPEN = `WEB_CHAT_OPTIONS_PAGE_OPEN`,
|
||||
APP_OPEN = 'WEB_CHAT_APP_OPEN'
|
||||
}
|
||||
|
|
|
@ -77,11 +77,11 @@ const DanmakuDomain = Remesh.domain({
|
|||
}
|
||||
})
|
||||
|
||||
const DestroyCommand = domain.command({
|
||||
name: 'Danmaku.DestroyCommand',
|
||||
const UnmountCommand = domain.command({
|
||||
name: 'Danmaku.UnmountCommand',
|
||||
impl: () => {
|
||||
danmaku.destroy()
|
||||
return [DestroyEvent()]
|
||||
danmaku.unmount()
|
||||
return [UnmountEvent()]
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -101,8 +101,8 @@ const DanmakuDomain = Remesh.domain({
|
|||
name: 'Danmaku.MountEvent'
|
||||
})
|
||||
|
||||
const DestroyEvent = domain.event({
|
||||
name: 'Danmaku.DestroyEvent'
|
||||
const UnmountEvent = domain.event({
|
||||
name: 'Danmaku.UnmountEvent'
|
||||
})
|
||||
|
||||
domain.effect({
|
||||
|
@ -129,14 +129,14 @@ const DanmakuDomain = Remesh.domain({
|
|||
UnshiftCommand,
|
||||
ClearCommand,
|
||||
MountCommand,
|
||||
DestroyCommand
|
||||
UnmountCommand
|
||||
},
|
||||
event: {
|
||||
PushEvent,
|
||||
UnshiftEvent,
|
||||
ClearEvent,
|
||||
MountEvent,
|
||||
DestroyEvent
|
||||
UnmountEvent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ export interface Danmaku {
|
|||
unshift: (message: TextMessage) => void
|
||||
clear: () => void
|
||||
mount: (root: HTMLElement) => void
|
||||
destroy: () => void
|
||||
unmount: () => void
|
||||
}
|
||||
|
||||
export const DanmakuExtern = Remesh.extern<Danmaku>({
|
||||
|
@ -14,8 +14,8 @@ export const DanmakuExtern = Remesh.extern<Danmaku>({
|
|||
mount: () => {
|
||||
throw new Error('"mount" not implemented.')
|
||||
},
|
||||
destroy() {
|
||||
throw new Error('"destroy" not implemented.')
|
||||
unmount() {
|
||||
throw new Error('"unmount" not implemented.')
|
||||
},
|
||||
clear: () => {
|
||||
throw new Error('"clear" not implemented.')
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Remesh } from 'remesh'
|
||||
|
||||
export type StorageValue = null | string | number | boolean | object
|
||||
export type WatchEvent = 'update' | 'remove'
|
||||
export type WatchCallback = (event: WatchEvent, key: string) => any
|
||||
export type WatchCallback = () => any
|
||||
export type Unwatch = () => Promise<void>
|
||||
|
||||
export interface Storage {
|
||||
|
|
|
@ -2,78 +2,63 @@ import { DanmakuExtern } from '@/domain/externs/Danmaku'
|
|||
|
||||
import { TextMessage } from '@/domain/Room'
|
||||
import { createElement } from 'react'
|
||||
import _Danmaku from 'danmaku'
|
||||
import DanmakuMessage from '@/app/content/components/DanmakuMessage'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
|
||||
// import { create } from 'danmaku'
|
||||
// const manager = create<TextMessage>({
|
||||
// trackHeight: '20%',
|
||||
// plugin: {
|
||||
// init(manager) {
|
||||
// 'shadow shadow-slate-200 bg-slate-100'.split(' ').forEach((c) => {
|
||||
// manager.container.node.classList.add(c)
|
||||
// })
|
||||
// },
|
||||
// $createNode(dm) {
|
||||
// if (!dm.node) return
|
||||
// createRoot(dm.node).render(createElement(DanmakuMessage, { data: dm.data }))
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
// manager.mount(document.body)
|
||||
// manager.startPlaying()
|
||||
import { create, Manager } from 'danmu'
|
||||
|
||||
export class Danmaku {
|
||||
private container?: Element
|
||||
private _danmaku?: _Danmaku
|
||||
|
||||
mount(container: HTMLElement) {
|
||||
this.container = container
|
||||
|
||||
this._danmaku = new _Danmaku({
|
||||
container
|
||||
private manager?: Manager<TextMessage>
|
||||
constructor() {
|
||||
this.manager = create<TextMessage>({
|
||||
durationRange: [10000, 13000],
|
||||
plugin: {
|
||||
$createNode(manager) {
|
||||
if (!manager.node) return
|
||||
createRoot(manager.node).render(
|
||||
createElement(DanmakuMessage, {
|
||||
data: manager.data,
|
||||
onMouseEnter: () => manager.pause(),
|
||||
onMouseLeave: () => manager.resume()
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
destroy() {
|
||||
mount(container: HTMLElement) {
|
||||
this.container = container
|
||||
this.manager!.mount(container)
|
||||
this.manager!.startPlaying()
|
||||
}
|
||||
|
||||
unmount() {
|
||||
if (!this.container) {
|
||||
throw new Error('Danmaku not mounted')
|
||||
}
|
||||
this._danmaku!.destroy()
|
||||
this.manager!.unmount()
|
||||
}
|
||||
|
||||
push(message: TextMessage) {
|
||||
if (!this.container) {
|
||||
throw new Error('Danmaku not mounted')
|
||||
}
|
||||
|
||||
const root = document.createElement('div')
|
||||
createRoot(root).render(createElement(DanmakuMessage, { data: message }))
|
||||
|
||||
// Wait for React render to complete
|
||||
requestIdleCallback(() => {
|
||||
this._danmaku!.emit({
|
||||
render() {
|
||||
return root.firstElementChild! as HTMLElement
|
||||
}
|
||||
})
|
||||
})
|
||||
this.manager!.push(message)
|
||||
}
|
||||
|
||||
unshift(message: TextMessage) {
|
||||
if (!this.container) {
|
||||
throw new Error('Danmaku not mounted')
|
||||
}
|
||||
// console.log(message)
|
||||
this.manager!.unshift(message)
|
||||
}
|
||||
|
||||
clear() {
|
||||
if (!this.container) {
|
||||
throw new Error('Danmaku not mounted')
|
||||
}
|
||||
this._danmaku!.clear()
|
||||
this.manager!.clear()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import { STORAGE_NAME } from '@/constants/config'
|
|||
import { webExtensionDriver } from '@/utils/webExtensionDriver'
|
||||
import { browser } from 'wxt/browser'
|
||||
import { Storage } from '@/domain/externs/Storage'
|
||||
import { EVENT } from '@/constants/event'
|
||||
|
||||
export const localStorage = createStorage({
|
||||
driver: localStorageDriver({ base: `${STORAGE_NAME}:` })
|
||||
|
@ -25,7 +26,20 @@ export const LocalStorageImpl = LocalStorageExtern.impl({
|
|||
set: localStorage.setItem,
|
||||
remove: localStorage.removeItem,
|
||||
clear: localStorage.clear,
|
||||
watch: localStorage.watch as Storage['watch'],
|
||||
watch: async (callback) => {
|
||||
const unwatch = await localStorage.watch(callback)
|
||||
|
||||
/**
|
||||
* Because the storage event cannot be triggered in the same browsing context
|
||||
* it is necessary to listen for click events from DanmukuMessage.
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event
|
||||
*/
|
||||
addEventListener(EVENT.APP_OPEN, callback)
|
||||
return async () => {
|
||||
removeEventListener(EVENT.APP_OPEN, callback)
|
||||
return unwatch()
|
||||
}
|
||||
},
|
||||
unwatch: localStorage.unwatch
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in a new issue