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