This commit is contained in:
2026-04-25 16:36:34 +08:00
commit db90e7579b
1876 changed files with 189777 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
import React, {
PropsWithChildren,
useCallback,
useContext,
useState,
} from 'react';
import _noop from 'lodash/noop';
import type { ReplyMsgType } from '../utils/message-helper';
/**
* 一个消息盒的上下文
*/
interface ChatBoxContextProps {
replyMsg: ReplyMsgType | null;
setReplyMsg: (msg: ReplyMsgType | null) => void;
}
const ChatBoxContext = React.createContext<ChatBoxContextProps>({
replyMsg: null,
setReplyMsg: _noop,
});
ChatBoxContext.displayName = 'ChatBoxContext';
export const ChatBoxContextProvider: React.FC<PropsWithChildren> = React.memo(
(props) => {
const [replyMsg, setReplyMsg] = useState<ReplyMsgType | null>(null);
return (
<ChatBoxContext.Provider
value={{
replyMsg,
setReplyMsg,
}}
>
{props.children}
</ChatBoxContext.Provider>
);
}
);
ChatBoxContextProvider.displayName = 'ChatBoxContextProvider';
export function useChatBoxContext(): ChatBoxContextProps & {
hasContext: boolean;
clearReplyMsg: () => void;
} {
const context = useContext(ChatBoxContext);
const clearReplyMsg = useCallback(() => {
context.setReplyMsg(null);
}, [context.setReplyMsg]);
return {
hasContext: context.setReplyMsg !== _noop,
replyMsg: context.replyMsg,
setReplyMsg: context.setReplyMsg,
clearReplyMsg,
};
}

View File

@@ -0,0 +1,42 @@
import React, { PropsWithChildren, useContext, useEffect } from 'react';
import { parseColorScheme } from '../utils/color-scheme-helper';
import { sharedEvent } from '../event';
import { useStorage } from '../manager/storage';
const ColorSchemeContext = React.createContext<{
/**
* 'dark' | 'light' | 'auto' | string
*/
colorScheme: string;
setColorScheme: (colorScheme: string) => void;
}>({
colorScheme: 'dark',
setColorScheme: () => {},
});
ColorSchemeContext.displayName = 'ColorSchemeContext';
export const ColorSchemeContextProvider: React.FC<PropsWithChildren> =
React.memo((props) => {
const [colorScheme = 'dark', { save: setColorScheme }] = useStorage(
'colorScheme',
'dark'
);
useEffect(() => {
sharedEvent.emit('loadColorScheme', colorScheme);
}, [colorScheme]);
return (
<ColorSchemeContext.Provider value={{ colorScheme, setColorScheme }}>
{props.children}
</ColorSchemeContext.Provider>
);
});
ColorSchemeContextProvider.displayName = 'ColorSchemeContextProvider';
export function useColorScheme() {
const { colorScheme, setColorScheme } = useContext(ColorSchemeContext);
const { isDarkMode, extraSchemeName } = parseColorScheme(colorScheme);
return { colorScheme, setColorScheme, isDarkMode, extraSchemeName };
}

View File

@@ -0,0 +1,65 @@
import React from 'react';
import type { ChatMessage, SendMessagePayload } from '../model/message';
import { useConverseMessage } from '../redux/hooks/useConverseMessage';
import { createContextFactory } from './factory';
interface ConverseMessageContextProps {
messages: ChatMessage[];
loading: boolean;
error?: Error;
isLoadingMore: boolean;
hasMoreMessage: boolean;
fetchMoreMessage: () => Promise<void>;
sendMessage: (payload: SendMessagePayload) => void | Promise<void>;
}
const {
Context: ConverseMessageContext,
useContext: useConverseMessageContext,
} = createContextFactory<ConverseMessageContextProps>({
defaultValue: {} as ConverseMessageContextProps,
displayName: 'ConverseMessageContext',
});
/**
* 会话消息列表相关上下文
*/
export const ConverseMessageProvider: React.FC<
React.PropsWithChildren<{
converseId: string;
isGroup: boolean;
}>
> = React.memo((props) => {
const { converseId, isGroup } = props;
const {
messages,
loading,
error,
isLoadingMore,
hasMoreMessage,
handleFetchMoreMessage: fetchMoreMessage,
handleSendMessage: sendMessage,
} = useConverseMessage({
converseId,
isGroup,
});
return (
<ConverseMessageContext.Provider
value={{
messages,
loading,
error,
isLoadingMore,
hasMoreMessage,
fetchMoreMessage,
sendMessage,
}}
>
{props.children}
</ConverseMessageContext.Provider>
);
});
ConverseMessageProvider.displayName = 'ConverseMessageProvider';
export { useConverseMessageContext };

View File

@@ -0,0 +1,37 @@
import React, { PropsWithChildren, useContext } from 'react';
import type { GroupInfo } from '..';
/**
* 群组信息上下文
*/
interface GroupInfoContextProps {
groupInfo: GroupInfo | null;
}
const GroupInfoContext = React.createContext<GroupInfoContextProps>({
groupInfo: null,
});
GroupInfoContext.displayName = 'GroupInfoContext';
export const GroupInfoContextProvider: React.FC<
PropsWithChildren<{
groupInfo: GroupInfo;
}>
> = React.memo((props) => {
return (
<GroupInfoContext.Provider
value={{
groupInfo: props.groupInfo,
}}
>
{props.children}
</GroupInfoContext.Provider>
);
});
GroupInfoContextProvider.displayName = 'GroupInfoContextProvider';
export function useGroupInfoContext(): GroupInfoContextProps['groupInfo'] {
const context = useContext(GroupInfoContext);
return context.groupInfo;
}

View File

@@ -0,0 +1,22 @@
import React from 'react';
interface CreateContextFactoryOptions<Props> {
defaultValue: Props;
displayName: string;
}
export function createContextFactory<Props>(
options: CreateContextFactoryOptions<Props>
) {
const Context = React.createContext(options.defaultValue);
Context.displayName = options.displayName;
function useContext(): Props {
return React.useContext(Context);
}
return {
Context,
useContext,
};
}