mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-13 19:20:04 +00:00
🐛 fix: gate inbox unread count by login state (#15724)
This commit is contained in:
@@ -7,23 +7,14 @@ import { memo, useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { DESKTOP_HEADER_ICON_SMALL_SIZE } from '@/const/layoutTokens';
|
||||
import { useClientDataSWR } from '@/libs/swr';
|
||||
import { notificationService } from '@/services/notification';
|
||||
import { serverConfigSelectors, useServerConfigStore } from '@/store/serverConfig';
|
||||
|
||||
import InboxDrawer from './InboxDrawer';
|
||||
import { UNREAD_COUNT_KEY } from './InboxDrawer/constants';
|
||||
import { useInboxUnreadCount } from './useInboxUnreadCount';
|
||||
|
||||
const InboxButton = memo(() => {
|
||||
const { t } = useTranslation('notification');
|
||||
const [open, setOpen] = useState(false);
|
||||
const enableBusinessFeatures = useServerConfigStore(serverConfigSelectors.enableBusinessFeatures);
|
||||
|
||||
const { data: unreadCount = 0 } = useClientDataSWR<number>(
|
||||
enableBusinessFeatures ? UNREAD_COUNT_KEY : null,
|
||||
() => notificationService.getUnreadCount(),
|
||||
{ refreshInterval: 10_000 },
|
||||
);
|
||||
const { enabled, unreadCount } = useInboxUnreadCount();
|
||||
|
||||
const handleToggle = useCallback(() => {
|
||||
setOpen((prev) => !prev);
|
||||
@@ -33,7 +24,7 @@ const InboxButton = memo(() => {
|
||||
setOpen(false);
|
||||
}, []);
|
||||
|
||||
if (!enableBusinessFeatures) return null;
|
||||
if (!enabled) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { UNREAD_COUNT_KEY } from './InboxDrawer/constants';
|
||||
import { INBOX_UNREAD_COUNT_REFRESH_INTERVAL, useInboxUnreadCount } from './useInboxUnreadCount';
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
state: {
|
||||
enableBusinessFeatures: true,
|
||||
isSignedIn: false,
|
||||
},
|
||||
useClientDataSWR: vi.fn(() => ({ data: undefined })),
|
||||
}));
|
||||
|
||||
vi.mock('@/libs/swr', () => ({
|
||||
useClientDataSWR: mocks.useClientDataSWR,
|
||||
}));
|
||||
|
||||
vi.mock('@/services/notification', () => ({
|
||||
notificationService: {
|
||||
getUnreadCount: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@/store/serverConfig', () => ({
|
||||
serverConfigSelectors: {
|
||||
enableBusinessFeatures: (state: { serverConfig: { enableBusinessFeatures: boolean } }) =>
|
||||
state.serverConfig.enableBusinessFeatures,
|
||||
},
|
||||
useServerConfigStore: (
|
||||
selector: (state: { serverConfig: { enableBusinessFeatures: boolean } }) => boolean,
|
||||
) => selector({ serverConfig: { enableBusinessFeatures: mocks.state.enableBusinessFeatures } }),
|
||||
}));
|
||||
|
||||
vi.mock('@/store/user', () => ({
|
||||
useUserStore: (selector: (state: { isSignedIn: boolean }) => boolean) =>
|
||||
selector({ isSignedIn: mocks.state.isSignedIn }),
|
||||
}));
|
||||
|
||||
vi.mock('@/store/user/selectors', () => ({
|
||||
authSelectors: {
|
||||
isLogin: (state: { isSignedIn: boolean }) => state.isSignedIn,
|
||||
},
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
mocks.state.enableBusinessFeatures = true;
|
||||
mocks.state.isSignedIn = false;
|
||||
mocks.useClientDataSWR.mockClear();
|
||||
mocks.useClientDataSWR.mockReturnValue({ data: undefined });
|
||||
});
|
||||
|
||||
describe('useInboxUnreadCount', () => {
|
||||
it('does not request unread count before login', () => {
|
||||
const { result } = renderHook(() => useInboxUnreadCount());
|
||||
|
||||
expect(result.current.enabled).toBe(false);
|
||||
expect(mocks.useClientDataSWR).toHaveBeenCalledWith(null, expect.any(Function), {
|
||||
refreshInterval: INBOX_UNREAD_COUNT_REFRESH_INTERVAL,
|
||||
});
|
||||
});
|
||||
|
||||
it('requests unread count when business features are enabled and user is logged in', () => {
|
||||
mocks.state.isSignedIn = true;
|
||||
|
||||
const { result } = renderHook(() => useInboxUnreadCount());
|
||||
|
||||
expect(result.current.enabled).toBe(true);
|
||||
expect(mocks.useClientDataSWR).toHaveBeenCalledWith(UNREAD_COUNT_KEY, expect.any(Function), {
|
||||
refreshInterval: INBOX_UNREAD_COUNT_REFRESH_INTERVAL,
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps unread count polling on the same 10 second cadence', () => {
|
||||
expect(INBOX_UNREAD_COUNT_REFRESH_INTERVAL).toBe(10_000);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import { useClientDataSWR } from '@/libs/swr';
|
||||
import { notificationService } from '@/services/notification';
|
||||
import { serverConfigSelectors, useServerConfigStore } from '@/store/serverConfig';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { authSelectors } from '@/store/user/selectors';
|
||||
|
||||
import { UNREAD_COUNT_KEY } from './InboxDrawer/constants';
|
||||
|
||||
export const INBOX_UNREAD_COUNT_REFRESH_INTERVAL = 10_000;
|
||||
|
||||
export const useInboxUnreadCount = () => {
|
||||
const enableBusinessFeatures = useServerConfigStore(serverConfigSelectors.enableBusinessFeatures);
|
||||
const isLogin = useUserStore(authSelectors.isLogin);
|
||||
const enabled = enableBusinessFeatures && isLogin === true;
|
||||
|
||||
const { data: unreadCount = 0 } = useClientDataSWR<number>(
|
||||
enabled ? UNREAD_COUNT_KEY : null,
|
||||
() => notificationService.getUnreadCount(),
|
||||
{ refreshInterval: INBOX_UNREAD_COUNT_REFRESH_INTERVAL },
|
||||
);
|
||||
|
||||
return { enabled, unreadCount };
|
||||
};
|
||||
Reference in New Issue
Block a user