You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tailchat/web/src/components/Panel/group/TextPanel.tsx

74 lines
2.1 KiB
TypeScript

import { ChatBox } from '@/components/ChatBox';
import { ChatInputMentionsContextProvider } from '@/components/ChatBox/ChatInputBox/context';
import React, { useCallback, useLayoutEffect, useState } from 'react';
import {
useGroupPanelInfo,
useGroupMemberInfos,
useGroupMemberMute,
useUserId,
t,
humanizeMsDuration,
useInterval,
} from 'tailchat-shared';
import { GroupPanelWrapper } from './Wrapper';
interface TextPanelProps {
groupId: string;
panelId: string;
}
export const TextPanel: React.FC<TextPanelProps> = React.memo(
({ groupId, panelId }) => {
const groupMembers = useGroupMemberInfos(groupId);
const panelInfo = useGroupPanelInfo(groupId, panelId);
const userId = useUserId();
const muteUntil = useGroupMemberMute(groupId, userId ?? '');
const [placeholder, setPlaceholder] = useState<string | undefined>(
undefined
);
const updatePlaceholder = useCallback(() => {
if (muteUntil) {
setPlaceholder(
muteUntil
? t('禁言中, 还剩 {{remain}}', {
remain: humanizeMsDuration(
new Date().valueOf() - new Date(muteUntil).valueOf()
),
})
: undefined
);
} else {
setPlaceholder(undefined);
}
}, [muteUntil]);
useInterval(
updatePlaceholder,
10000 // 10s 检查一次,因为 humanizeMsDuration 不会精确到秒
);
useLayoutEffect(() => {
// 当到期时间发生变化后立即更新
updatePlaceholder();
}, [muteUntil]);
if (panelInfo === undefined) {
return null;
}
return (
<GroupPanelWrapper groupId={groupId} panelId={panelId} showHeader={true}>
<ChatInputMentionsContextProvider
users={groupMembers.map((m) => ({
id: m._id,
display: m.nickname,
}))}
disabled={Boolean(muteUntil)}
placeholder={placeholder}
>
<ChatBox converseId={panelId} isGroup={true} groupId={groupId} />
</ChatInputMentionsContextProvider>
</GroupPanelWrapper>
);
}
);
TextPanel.displayName = 'TextPanel';