Skip to content

Commit 1423459

Browse files
committed
feat: socket event
Signed-off-by: Innei <[email protected]>
1 parent a734909 commit 1423459

File tree

6 files changed

+74
-18
lines changed

6 files changed

+74
-18
lines changed

src/atoms/activity.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { atom, useAtomValue } from 'jotai'
2+
3+
import { jotaiStore } from '~/lib/store'
4+
5+
type Activity = {
6+
processName: string
7+
media: {
8+
title: string
9+
artist: string
10+
} | null
11+
}
12+
13+
const activityAtom = atom({
14+
processName: '',
15+
media: null,
16+
} as Activity)
17+
18+
export const useActivity = () => useAtomValue(activityAtom)
19+
export const setActivityProcessName = (processName: string) =>
20+
jotaiStore.set(activityAtom, (prev) => ({ ...prev, processName }))
21+
22+
export const setActivityMediaInfo = (media: Activity['media']) =>
23+
jotaiStore.set(activityAtom, (prev) => ({ ...prev, media }))

src/components/layout/header/internal/Activity.tsx

+18-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
'use client'
22

33
import { useQuery } from '@tanstack/react-query'
4-
import React, { memo, useMemo, useState } from 'react'
4+
import React, { memo, useEffect, useMemo, useState } from 'react'
55
import { AnimatePresence, m } from 'framer-motion'
66
import Image from 'next/image'
77
import type { RequestError } from '@mx-space/api-client'
88

9+
import {
10+
setActivityMediaInfo,
11+
setActivityProcessName,
12+
useActivity,
13+
} from '~/atoms/activity'
914
import { FloatPopover } from '~/components/ui/float-popover'
1015
import { apiClient } from '~/lib/request'
1116
import { useAggregationSelector } from '~/providers/root/aggregation-data-provider'
@@ -44,7 +49,7 @@ const appLabels: { [app: string]: string } = {
4449
Chrome: 'chrome',
4550
'Chrome Canary': 'chrome_canary',
4651
QQ音乐: 'qq_music',
47-
NeteaseMusic: 'netease',
52+
NetEaseMusic: 'netease',
4853
iTerm2: 'iterm2',
4954
Xcode: 'xcode',
5055
Typora: 'typora',
@@ -55,6 +60,8 @@ const appLabels: { [app: string]: string } = {
5560
export function Activity() {
5661
const [isEnabled, setIsEnabled] = useState(true)
5762

63+
const activity = useActivity()
64+
5865
const { data } = useQuery(
5966
['activity'],
6067
async () => {
@@ -73,14 +80,21 @@ export function Activity() {
7380
})
7481
},
7582
{
76-
refetchInterval: 5000,
83+
refetchInterval: 1000 * 5 * 60,
7784
retry: false,
7885
enabled: isEnabled,
7986
meta: {
8087
persist: false,
8188
},
8289
},
8390
)
91+
92+
useEffect(() => {
93+
if (!data) return
94+
data.mediaInfo && setActivityMediaInfo(data.mediaInfo)
95+
setActivityProcessName(data.processName)
96+
}, [data])
97+
8498
const ownerName = useAggregationSelector((data) => data.user.name)
8599
const memoProcessName = useMemo(
86100
() => ({ processName: data?.processName || '' }),
@@ -89,7 +103,7 @@ export function Activity() {
89103
if (!data) {
90104
return null
91105
}
92-
const { processName, mediaInfo: media } = data
106+
const { processName, media } = activity
93107
if (!appLabels[processName]) {
94108
console.log('Not collected process name: ', processName)
95109
return null

src/components/layout/header/internal/AnimatedLogo.tsx

+16
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
'use client'
22

3+
import { useQuery } from '@tanstack/react-query'
4+
import { useCallback } from 'react'
35
import { AnimatePresence, m } from 'framer-motion'
46
import { useRouter } from 'next/navigation'
57

68
import { getAdminUrl, isLogged, useViewport } from '~/atoms'
79
import { useSingleAndDoubleClick } from '~/hooks/common/use-single-double-click'
10+
import { useConfig } from '~/hooks/data/use-config'
811
import { Routes } from '~/lib/route-builder'
912
import { toast } from '~/lib/toast'
1013

@@ -14,8 +17,21 @@ import { SiteOwnerAvatar } from './SiteOwnerAvatar'
1417

1518
const TapableLogo = () => {
1619
const router = useRouter()
20+
21+
const { data: isLiving } = useQuery({
22+
queryKey: ['live-check'],
23+
enabled: false,
24+
})
25+
const {
26+
module: { bilibili: { liveId } = {} },
27+
} = useConfig()
28+
const goLive = useCallback(() => {
29+
window.open(`https://live.bilibili.com/${liveId}`)
30+
}, [liveId])
31+
1732
const fn = useSingleAndDoubleClick(
1833
() => {
34+
if (isLiving) return goLive()
1935
router.push(Routes.Home)
2036
},
2137
() => {

src/components/layout/header/internal/SiteOwnerAvatar.tsx

+1-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { useQuery } from '@tanstack/react-query'
44
import { useCallback } from 'react'
55
import Image from 'next/image'
66

7-
import { appConfig } from '~/app.config'
87
import { clsxm } from '~/lib/helper'
98
import { useAggregationSelector } from '~/providers/root/aggregation-data-provider'
109

@@ -26,19 +25,12 @@ export const SiteOwnerAvatar: Component = ({ className }) => {
2625
},
2726
})
2827

29-
const handleGoLive = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
30-
e.stopPropagation()
31-
window.open(`https://live.bilibili.com/${appConfig.module.bilibili.liveId}`)
32-
}, [])
3328
if (!avatar) return
3429
return (
3530
<div
3631
role={isLiving ? 'button' : 'img'}
37-
aria-hidden
38-
onClick={handleGoLive}
39-
tabIndex={isLiving ? 0 : -1}
4032
className={clsxm(
41-
'overflow pointer-events-none relative select-none',
33+
'overflow pointer-events-none relative z-[9] select-none',
4234

4335
isLiving ? 'cursor-pointer rounded-full' : '',
4436
className,

src/hooks/common/use-single-double-click.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function useSingleAndDoubleClick(
1919
if (click === 2) actionDoubleClick()
2020

2121
return () => clearTimeout(timer)
22-
}, [click])
22+
}, [actionDoubleClick, actionSimpleClick, click])
2323

2424
return () => setClick((prev) => prev + 1)
2525
}

src/socket/handler.ts

+15-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { AppRouterInstance } from 'next/dist/shared/lib/app-router-context'
1111

1212
import { sayQueryKey } from '~/app/says/query'
1313
import { setOnlineCount } from '~/atoms'
14+
import { setActivityMediaInfo, setActivityProcessName } from '~/atoms/activity'
1415
import { isDev } from '~/lib/env'
1516
import { routeBuilder, Routes } from '~/lib/route-builder'
1617
import { toast } from '~/lib/toast'
@@ -29,13 +30,13 @@ import {
2930
import { EventTypes } from '~/types/events'
3031

3132
export const eventHandler = (
32-
type: EventTypes,
33+
type: string,
3334
data: any,
3435
router: AppRouterInstance,
3536
) => {
3637
switch (type) {
37-
case 'VISITOR_ONLINE':
38-
case 'VISITOR_OFFLINE': {
38+
case EventTypes.VISITOR_ONLINE:
39+
case EventTypes.VISITOR_OFFLINE: {
3940
const { online } = data
4041
setOnlineCount(online)
4142
break
@@ -74,7 +75,7 @@ export const eventHandler = (
7475
break
7576
}
7677

77-
case 'NOTE_DELETE': {
78+
case EventTypes.NOTE_DELETE: {
7879
const note = data as NoteModel
7980
if (getCurrentNoteData()?.data.id === note.id) {
8081
router.replace(routeBuilder(Routes.PageDeletd, {}))
@@ -110,6 +111,16 @@ export const eventHandler = (
110111
break
111112
}
112113

114+
case 'fn#media-update': {
115+
setActivityMediaInfo(data)
116+
break
117+
}
118+
119+
case 'fn#ps-update': {
120+
setActivityProcessName(data.process)
121+
break
122+
}
123+
113124
default: {
114125
if (isDev) {
115126
console.log(type, data)

0 commit comments

Comments
 (0)