feat: add socket state
This commit is contained in:
parent
5588aca522
commit
e095a081b9
@ -7,8 +7,10 @@ import { useIsLogined } from '../store/user';
|
|||||||
|
|
||||||
const useSocketStore = create<{
|
const useSocketStore = create<{
|
||||||
socket: Socket | null;
|
socket: Socket | null;
|
||||||
|
connected: boolean;
|
||||||
}>(() => ({
|
}>(() => ({
|
||||||
socket: null,
|
socket: null,
|
||||||
|
connected: false,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export function createSocketIOClient(workspaceId: string) {
|
export function createSocketIOClient(workspaceId: string) {
|
||||||
@ -23,6 +25,24 @@ export function createSocketIOClient(workspaceId: string) {
|
|||||||
forceNew: true,
|
forceNew: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on('connect', () => {
|
||||||
|
useSocketStore.setState({
|
||||||
|
connected: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
useSocketStore.setState({
|
||||||
|
connected: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('connect_error', () => {
|
||||||
|
useSocketStore.setState({
|
||||||
|
connected: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
useSocketStore.setState({
|
useSocketStore.setState({
|
||||||
socket,
|
socket,
|
||||||
});
|
});
|
||||||
@ -111,6 +131,10 @@ export function useSocketSubscribe<T>(
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useSocketConnected() {
|
||||||
|
return useSocketStore((state) => state.connected);
|
||||||
|
}
|
||||||
|
|
||||||
interface UseSocketSubscribeListOptions<K, T> {
|
interface UseSocketSubscribeListOptions<K, T> {
|
||||||
filter?: (data: T) => boolean;
|
filter?: (data: T) => boolean;
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,10 @@ interface CommonHeaderProps {
|
|||||||
export const CommonHeader: React.FC<CommonHeaderProps> = React.memo((props) => {
|
export const CommonHeader: React.FC<CommonHeaderProps> = React.memo((props) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full items-center">
|
<div className="flex w-full items-center">
|
||||||
<div className="flex flex-1 items-center">
|
<div className="flex flex-1 flex-shrink items-center overflow-hidden">
|
||||||
<h1 className="text-xl font-bold">{props.title}</h1>
|
<h1 className="overflow-hidden text-ellipsis whitespace-nowrap text-xl font-bold">
|
||||||
|
{props.title}
|
||||||
|
</h1>
|
||||||
|
|
||||||
{props.desc && (
|
{props.desc && (
|
||||||
<span className="text-muted-foreground ml-2 self-end text-sm">
|
<span className="text-muted-foreground ml-2 self-end text-sm">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { AppRouterOutput, trpc } from '@/api/trpc';
|
import { AppRouterOutput } from '@/api/trpc';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Badge } from '../ui/badge';
|
import { Badge } from '../ui/badge';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
@ -6,8 +6,6 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';
|
|||||||
import { MarkdownViewer } from '../MarkdownEditor';
|
import { MarkdownViewer } from '../MarkdownEditor';
|
||||||
import { FeedIcon } from './FeedIcon';
|
import { FeedIcon } from './FeedIcon';
|
||||||
import { cn } from '@/utils/style';
|
import { cn } from '@/utils/style';
|
||||||
import { useCurrentWorkspaceId } from '@/store/user';
|
|
||||||
import { useTranslation } from '@i18next-toolkit/react';
|
|
||||||
|
|
||||||
type FeedEventItemType =
|
type FeedEventItemType =
|
||||||
AppRouterOutput['feed']['fetchEventsByCursor']['items'][number];
|
AppRouterOutput['feed']['fetchEventsByCursor']['items'][number];
|
||||||
@ -43,8 +41,10 @@ export const FeedEventItem: React.FC<{
|
|||||||
|
|
||||||
<Badge variant="secondary">{event.eventName}</Badge>
|
<Badge variant="secondary">{event.eventName}</Badge>
|
||||||
|
|
||||||
{event.tags.map((tag) => (
|
{event.tags.map((tag, i) => (
|
||||||
<Badge variant="outline">{tag}</Badge>
|
<Badge key={i} variant="outline">
|
||||||
|
{tag}
|
||||||
|
</Badge>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ import { version } from '@/utils/env';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { LuMoreVertical } from 'react-icons/lu';
|
import { LuMoreVertical } from 'react-icons/lu';
|
||||||
import { trpc } from '@/api/trpc';
|
import { trpc } from '@/api/trpc';
|
||||||
|
import { useSocketConnected } from '@/api/socketio';
|
||||||
|
import { cn } from '@/utils/style';
|
||||||
|
|
||||||
interface UserConfigProps {
|
interface UserConfigProps {
|
||||||
isCollapsed: boolean;
|
isCollapsed: boolean;
|
||||||
@ -57,6 +59,7 @@ export const UserConfig: React.FC<UserConfigProps> = React.memo((props) => {
|
|||||||
setUserInfo(userInfo);
|
setUserInfo(userInfo);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const socketConnected = useSocketConnected();
|
||||||
|
|
||||||
const handleChangeColorSchema = useEvent((colorScheme) => {
|
const handleChangeColorSchema = useEvent((colorScheme) => {
|
||||||
useSettingsStore.setState({
|
useSettingsStore.setState({
|
||||||
@ -67,10 +70,21 @@ export const UserConfig: React.FC<UserConfigProps> = React.memo((props) => {
|
|||||||
const nickname = userInfo?.nickname ?? userInfo?.username ?? '';
|
const nickname = userInfo?.nickname ?? userInfo?.username ?? '';
|
||||||
|
|
||||||
const avatar = (
|
const avatar = (
|
||||||
|
<div className="relative">
|
||||||
<Avatar size={props.isCollapsed ? 'sm' : 'default'}>
|
<Avatar size={props.isCollapsed ? 'sm' : 'default'}>
|
||||||
<AvatarImage src={userInfo?.avatar ?? undefined} />
|
{userInfo?.avatar && <AvatarImage src={userInfo.avatar} />}
|
||||||
<AvatarFallback>{nickname.substring(0, 2).toUpperCase()}</AvatarFallback>
|
|
||||||
|
<AvatarFallback>
|
||||||
|
{nickname.substring(0, 2).toUpperCase()}
|
||||||
|
</AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'absolute bottom-0 right-0 h-2 w-2 rounded-full border border-white border-opacity-50',
|
||||||
|
socketConnected ? 'bg-green-400' : 'bg-gray-400'
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const name = (
|
const name = (
|
||||||
|
@ -50,7 +50,11 @@ export const feedRouter = router({
|
|||||||
include: {
|
include: {
|
||||||
_count: {
|
_count: {
|
||||||
select: {
|
select: {
|
||||||
events: true,
|
events: {
|
||||||
|
where: {
|
||||||
|
archived: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user