mirror of https://github.com/msgbyte/tailchat
refactor: refactor group panel wrapper, extract shared logic
Its make ready for hide navbar in mobilepull/90/head
parent
4a842fd161
commit
7a4d55ea61
@ -1,133 +0,0 @@
|
||||
import React, { PropsWithChildren, useEffect, useMemo } from 'react';
|
||||
import { t, useGroupInfo, useGroupPanelInfo } from 'tailchat-shared';
|
||||
import _isNil from 'lodash/isNil';
|
||||
import { MembersPanel } from './MembersPanel';
|
||||
import { CommonPanelWrapper } from '../common/Wrapper';
|
||||
import { usePanelWindow } from '@/hooks/usePanelWindow';
|
||||
import { OpenedPanelTip } from '@/components/OpenedPanelTip';
|
||||
import { IconBtn } from '@/components/IconBtn';
|
||||
import {
|
||||
GroupPluginPanelActionProps,
|
||||
pluginPanelActions,
|
||||
} from '@/plugin/common';
|
||||
import { useUserSessionPreference } from '@/hooks/useUserPreference';
|
||||
import { GroupPanelContext } from '@/context/GroupPanelContext';
|
||||
|
||||
/**
|
||||
* 记录下最后访问的面板id
|
||||
*/
|
||||
function useRecordGroupPanel(groupId: string, panelId: string) {
|
||||
const [lastVisitPanel, setLastVisitPanel] = useUserSessionPreference(
|
||||
'groupLastVisitPanel'
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setLastVisitPanel({
|
||||
...lastVisitPanel,
|
||||
[groupId]: panelId,
|
||||
});
|
||||
}, [groupId, panelId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 群组面板通用包装器
|
||||
*/
|
||||
interface GroupPanelWrapperProps extends PropsWithChildren {
|
||||
groupId: string;
|
||||
panelId: string;
|
||||
|
||||
/**
|
||||
* 是否显示面板头
|
||||
*/
|
||||
showHeader: boolean;
|
||||
}
|
||||
export const GroupPanelWrapper: React.FC<GroupPanelWrapperProps> = React.memo(
|
||||
(props) => {
|
||||
const { groupId, panelId } = props;
|
||||
const groupInfo = useGroupInfo(groupId);
|
||||
const panelInfo = useGroupPanelInfo(groupId, panelId);
|
||||
const groupMemberCount = (groupInfo?.members ?? []).length;
|
||||
useRecordGroupPanel(groupId, panelId);
|
||||
|
||||
const { hasOpenedPanel, openPanelWindow, closePanelWindow } =
|
||||
usePanelWindow(`/panel/group/${groupId}/${panelId}`);
|
||||
|
||||
const groupPanelContextValue = useMemo(
|
||||
() => ({
|
||||
groupId,
|
||||
panelId,
|
||||
}),
|
||||
[groupId, panelId]
|
||||
);
|
||||
|
||||
if (_isNil(panelInfo)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (hasOpenedPanel) {
|
||||
return <OpenedPanelTip onClosePanelWindow={closePanelWindow} />;
|
||||
}
|
||||
|
||||
if (!props.showHeader) {
|
||||
return (
|
||||
<GroupPanelContext.Provider value={groupPanelContextValue}>
|
||||
{props.children}
|
||||
</GroupPanelContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<GroupPanelContext.Provider value={groupPanelContextValue}>
|
||||
<CommonPanelWrapper
|
||||
header={panelInfo.name}
|
||||
actions={(setRightPanel) => [
|
||||
...pluginPanelActions
|
||||
.filter(
|
||||
(action): action is GroupPluginPanelActionProps =>
|
||||
action.position === 'group'
|
||||
)
|
||||
.map((action) => (
|
||||
<IconBtn
|
||||
key={action.name}
|
||||
title={action.label}
|
||||
shape="square"
|
||||
icon={action.icon}
|
||||
iconClassName="text-2xl"
|
||||
onClick={() =>
|
||||
action.onClick({
|
||||
groupId: props.groupId,
|
||||
panelId: props.panelId,
|
||||
})
|
||||
}
|
||||
/>
|
||||
)),
|
||||
<IconBtn
|
||||
key="open"
|
||||
title={t('在新窗口打开')}
|
||||
shape="square"
|
||||
icon="mdi:dock-window"
|
||||
iconClassName="text-2xl"
|
||||
onClick={openPanelWindow}
|
||||
/>,
|
||||
<IconBtn
|
||||
key="members"
|
||||
title={t('成员列表')}
|
||||
shape="square"
|
||||
icon="mdi:account-supervisor-outline"
|
||||
iconClassName="text-2xl"
|
||||
onClick={() =>
|
||||
setRightPanel({
|
||||
name: t('成员') + ` (${groupMemberCount})`,
|
||||
panel: <MembersPanel groupId={props.groupId} />,
|
||||
})
|
||||
}
|
||||
/>,
|
||||
]}
|
||||
>
|
||||
{props.children}
|
||||
</CommonPanelWrapper>
|
||||
</GroupPanelContext.Provider>
|
||||
);
|
||||
}
|
||||
);
|
||||
GroupPanelWrapper.displayName = 'GroupPanelWrapper';
|
@ -0,0 +1,55 @@
|
||||
import { IconBtn } from '@/components/IconBtn';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { t, useGroupPanelInfo } from 'tailchat-shared';
|
||||
import {
|
||||
CommonPanelWrapper,
|
||||
CommonPanelWrapperProps,
|
||||
} from '../../common/Wrapper';
|
||||
import _isNil from 'lodash/isNil';
|
||||
import { usePanelWindow } from '@/hooks/usePanelWindow';
|
||||
import { OpenedPanelTip } from '@/components/OpenedPanelTip';
|
||||
|
||||
interface GroupPanelWithHeader extends PropsWithChildren {
|
||||
groupId: string;
|
||||
panelId: string;
|
||||
|
||||
prefixActions?: CommonPanelWrapperProps['actions'];
|
||||
suffixActions?: CommonPanelWrapperProps['actions'];
|
||||
}
|
||||
export const GroupPanelContainer: React.FC<GroupPanelWithHeader> = React.memo(
|
||||
(props) => {
|
||||
const { groupId, panelId } = props;
|
||||
const panelInfo = useGroupPanelInfo(groupId, panelId);
|
||||
const { hasOpenedPanel, openPanelWindow, closePanelWindow } =
|
||||
usePanelWindow(`/panel/group/${groupId}/${panelId}`);
|
||||
|
||||
if (_isNil(panelInfo)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (hasOpenedPanel) {
|
||||
return <OpenedPanelTip onClosePanelWindow={closePanelWindow} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<CommonPanelWrapper
|
||||
header={panelInfo.name}
|
||||
actions={(ctx) => [
|
||||
...(props.prefixActions?.(ctx) ?? []),
|
||||
<IconBtn
|
||||
key="open"
|
||||
title={t('在新窗口打开')}
|
||||
shape="square"
|
||||
icon="mdi:dock-window"
|
||||
iconClassName="text-2xl"
|
||||
onClick={openPanelWindow}
|
||||
/>,
|
||||
...(props.suffixActions?.(ctx) ?? []),
|
||||
]}
|
||||
>
|
||||
{props.children}
|
||||
</CommonPanelWrapper>
|
||||
);
|
||||
}
|
||||
);
|
||||
GroupPanelContainer.displayName = 'GroupPanelWithHeader';
|
Loading…
Reference in New Issue