diff --git a/shared/index.tsx b/shared/index.tsx index 24ccdc3e..826460ca 100644 --- a/shared/index.tsx +++ b/shared/index.tsx @@ -126,7 +126,7 @@ export { useGroupTextPanelUnread, } from './redux/hooks/useGroup'; export { useUserInfo, useUserId } from './redux/hooks/useUserInfo'; -export { userActions, groupActions } from './redux/slices'; +export { userActions, groupActions, uiActions } from './redux/slices'; export type { ChatConverseState } from './redux/slices/chat'; export { setupRedux } from './redux/setup'; export { createStore } from './redux/store'; diff --git a/shared/redux/slices/index.ts b/shared/redux/slices/index.ts index ba464a56..247175a6 100644 --- a/shared/redux/slices/index.ts +++ b/shared/redux/slices/index.ts @@ -2,11 +2,13 @@ import { combineReducers } from '@reduxjs/toolkit'; import { userReducer } from './user'; import { chatReducer } from './chat'; import { groupReducer } from './group'; +import { uiReducer } from './ui'; export const appReducer = combineReducers({ user: userReducer, chat: chatReducer, group: groupReducer, + ui: uiReducer, }); export type AppState = ReturnType; @@ -14,3 +16,4 @@ export type AppState = ReturnType; export { userActions } from './user'; export { chatActions } from './chat'; export { groupActions } from './group'; +export { uiActions } from './ui'; diff --git a/shared/redux/slices/ui.ts b/shared/redux/slices/ui.ts new file mode 100644 index 00000000..ce0d8729 --- /dev/null +++ b/shared/redux/slices/ui.ts @@ -0,0 +1,28 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +interface UIState { + panelWinUrls: string[]; +} + +const initialState: UIState = { + panelWinUrls: [], +}; + +const uiSlice = createSlice({ + name: 'ui', + initialState, + reducers: { + addPanelWindowUrl(state, action: PayloadAction<{ url: string }>) { + const panelUrl = action.payload.url; + state.panelWinUrls.push(panelUrl); + }, + deletePanelWindowUrl(state, action: PayloadAction<{ url: string }>) { + const panelUrl = action.payload.url; + const index = state.panelWinUrls.indexOf(panelUrl); + state.panelWinUrls.splice(index, 1); + }, + }, +}); + +export const uiActions = uiSlice.actions; +export const uiReducer = uiSlice.reducer; diff --git a/web/src/components/Panel/personal/ConversePanel.tsx b/web/src/components/Panel/personal/ConversePanel.tsx index aca9fbb6..4675d62b 100644 --- a/web/src/components/Panel/personal/ConversePanel.tsx +++ b/web/src/components/Panel/personal/ConversePanel.tsx @@ -2,7 +2,7 @@ import { ChatBox } from '@/components/ChatBox'; import { UserListItem } from '@/components/UserListItem'; import { Icon } from '@iconify/react'; import { Button, Tooltip } from 'antd'; -import React from 'react'; +import React, { useState } from 'react'; import { ChatConverseState, t, @@ -13,6 +13,8 @@ import { CommonPanelWrapper } from '../common/Wrapper'; import _compact from 'lodash/compact'; import { openModal } from '@/components/Modal'; import { AppendDMConverseMembers } from '@/components/modals/AppendDMConverseMembers'; +import { openInNewWindow, panelWindowManager } from '@/utils/window-helper'; +import { usePanelWindow } from '@/hooks/usePanelWindow'; const ConversePanelTitle: React.FC<{ converse: ChatConverseState }> = React.memo(({ converse }) => { @@ -44,6 +46,17 @@ export const ConversePanel: React.FC = React.memo( (state) => state.chat.converses[converseId] ); + const { hasOpenedPanel, openPanelWindow, closePanelWindow } = + usePanelWindow(`/panel/personal/converse/${converseId}`); + if (hasOpenedPanel) { + return ( +
+
{t('面板已在独立窗口打开')}
+ +
+ ); + } + return ( } @@ -53,6 +66,14 @@ export const ConversePanel: React.FC = React.memo( } return _compact([ + +