Skip to content

fix:网页面板下,右侧pin的面板拖拽事件丢失问题 || fix: Under the web page panel, the panel drag event on the right pin is lost #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/shared/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ export {
useHasGroupPermission,
} from './redux/hooks/useGroupPermission';
export { useUserInfo, useUserId } from './redux/hooks/useUserInfo';
export { useDragstatus, updateDragStatus } from './redux/hooks/usePanel'
export { useInboxList, useInboxItem } from './redux/hooks/useInbox';
export { useUnread } from './redux/hooks/useUnread';
export {
Expand Down
27 changes: 27 additions & 0 deletions client/shared/redux/hooks/usePanel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useAppSelector ,useAppDispatch} from './useAppSelector';
import {dragActions} from '../slices/drag'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why your code not auto format? did you skip github hooks manual?

import { useMemoizedFn } from '../..';

/**
* 返回面板拖拽状态
*/
export function useDragstatus():boolean {
return useAppSelector((state) => state.drag.isDraging ?? []);
}

export function updateDragStatus(){
const dispatch = useAppDispatch();
const setStatus = useMemoizedFn(
(status:boolean) => {
dispatch(dragActions.setDragStatus(status))}
);

/**
* 更新
*/
const updateStatus= useMemoizedFn((status: boolean) => {
setStatus(status);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can direct call dispatch(dragActions.setDragStatus(status)). and suggest replace useMemoizedFn with useEvent

});
return updateStatus ;
}

29 changes: 29 additions & 0 deletions client/shared/redux/slices/drag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';

export interface DragState {
/**
* 拖拽
*/
isDraging:boolean

}

const initialState: DragState = {
isDraging: false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its should be isDragging

};

const globalSlice = createSlice({
name: 'global',
initialState,
reducers: {
setDragStatus(
state,
action: PayloadAction<DragState['isDraging']>
) {
state.isDraging = action.payload;
},
},
});

export const dragActions = globalSlice.actions;
export const dragReducer = globalSlice.reducer;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its looks like should not create a new slice and should merge into uiSlice.

3 changes: 3 additions & 0 deletions client/shared/redux/slices/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import { chatReducer } from './chat';
import { groupReducer } from './group';
import { uiReducer } from './ui';
import { globalReducer } from './global';
import { dragReducer } from './drag'

export const appReducer = combineReducers({
global: globalReducer,
user: userReducer,
chat: chatReducer,
group: groupReducer,
ui: uiReducer,
drag:dragReducer
});

export type AppState = ReturnType<typeof appReducer>;
Expand All @@ -20,3 +22,4 @@ export { userActions } from './user';
export { chatActions } from './chat';
export { groupActions } from './group';
export { uiActions } from './ui';
export {dragActions} from './drag'
12 changes: 10 additions & 2 deletions client/web/src/components/SplitPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import clsx from 'clsx';
import React, { PropsWithChildren } from 'react';
import Split from 'react-split';
import { useStorage } from 'tailchat-shared';
import { useStorage, updateDragStatus} from 'tailchat-shared';
import './SplitPanel.less';


/**
* Reference: https://split.js.org/#/
*/
Expand All @@ -13,18 +14,25 @@ interface SplitPanelProps extends PropsWithChildren {
}
export const SplitPanel: React.FC<SplitPanelProps> = React.memo((props) => {
const [sizes, { save: saveSizes }] = useStorage('pin-sizes', [90, 10]);

const updateStatus = updateDragStatus()
const handleDragEnd = (sizes: number[]) => {
saveSizes(sizes);
updateStatus(false)

};

const handleDragEnter = ()=>{
updateStatus(true)
}

return (
<Split
className={clsx('split', props.className)}
sizes={sizes}
minSize={250}
expandToMin={true}
onDragEnd={handleDragEnd}
onDragStart={handleDragEnter}
>
{props.children}
</Split>
Expand Down
14 changes: 9 additions & 5 deletions client/web/src/components/Webview.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React, { useEffect, useRef, useState } from 'react';
import { t } from 'tailchat-shared';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { t , useDragstatus } from 'tailchat-shared';
import { withKeepAliveOverlay } from './KeepAliveOverlay';
import { Loading } from './Loading';



interface WebviewProps {
className?: string;
style?: React.CSSProperties;
Expand All @@ -15,25 +17,27 @@ interface WebviewProps {
export const Webview: React.FC<WebviewProps> = (props) => {
const ref = useRef<HTMLIFrameElement>(null);
const [spinning, setSpinning] = useState(true);

const status = useDragstatus()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An important problem is component Webview is a pure component and should not dependency with redux. redux has a scope in main route, the other route not use redux anywhere and not need it.

This code will restrict this component must be render under redux context.

My suggestion is change pin logic, and overlay a translucent div on both sides of the drag bar. To make sure drag event not send into iframe

useEffect(() => {
const callback = () => {
setSpinning(false);
};
ref.current?.addEventListener('load', callback);

return () => {
ref.current?.removeEventListener('load', callback);
};
}, []);
const pointerEvents =useMemo(()=>{
return status ? 'none' : 'auto'
},[status])

return (
<Loading
spinning={spinning}
className="w-full h-full"
tip={t('加载网页中...')}
>
<iframe ref={ref} className="w-full h-full" src={props.url} />
<iframe ref={ref} style={{pointerEvents}} className="w-full h-full" src={props.url} />
</Loading>
);
};
Expand Down