diff --git a/src/components/left/main/ForumPanel.tsx b/src/components/left/main/ForumPanel.tsx index 730bcea92..52b646186 100644 --- a/src/components/left/main/ForumPanel.tsx +++ b/src/components/left/main/ForumPanel.tsx @@ -280,9 +280,7 @@ const ForumPanel: FC = ({ }; export default memo(withGlobal( - (global, ownProps, detachWhenChanged): StateProps => { - detachWhenChanged(selectIsForumPanelOpen(global)); - + (global): StateProps => { const chatId = selectTabState(global).forumPanelChatId; const chat = chatId ? selectChat(global, chatId) : undefined; const { @@ -296,4 +294,5 @@ export default memo(withGlobal( withInterfaceAnimations: selectCanAnimateInterface(global), }; }, + (global) => selectIsForumPanelOpen(global), )(ForumPanel)); diff --git a/src/components/story/StorySlides.tsx b/src/components/story/StorySlides.tsx index 5648f42cc..97cf3a6f9 100644 --- a/src/components/story/StorySlides.tsx +++ b/src/components/story/StorySlides.tsx @@ -294,7 +294,7 @@ function StorySlides({ ); } -export default memo(withGlobal((global, ownProps, detachWhenChanged): StateProps => { +export default memo(withGlobal((global): StateProps => { const { storyViewer: { userId: currentUserId, storyId: currentStoryId, isSingleUser, isSingleStory, isPrivate, isArchive, @@ -303,9 +303,6 @@ export default memo(withGlobal((global, ownProps, detachWhenChanged): const { byUserId, orderedUserIds: { archived, active } } = global.stories; const user = currentUserId ? selectUser(global, currentUserId) : undefined; - const isOpen = selectIsStoryViewerOpen(global); - detachWhenChanged(isOpen); - return { byUserId, userIds: user?.areStoriesHidden ? archived : active, @@ -316,4 +313,4 @@ export default memo(withGlobal((global, ownProps, detachWhenChanged): isPrivate, isArchive, }; -})(StorySlides)); +}, (global) => selectIsStoryViewerOpen(global))(StorySlides)); diff --git a/src/lib/teact/teactn.tsx b/src/lib/teact/teactn.tsx index 86aeed86b..4d1c0f5c5 100644 --- a/src/lib/teact/teactn.tsx +++ b/src/lib/teact/teactn.tsx @@ -36,10 +36,8 @@ type ActionHandler = ( payload: any, ) => GlobalState | void | Promise; -type DetachWhenChanged = (current: any) => void; -type MapStateToProps = ( - (global: GlobalState, ownProps: OwnProps, detachWhenChanged: DetachWhenChanged) => AnyLiteral - ); +type MapStateToProps = (global: GlobalState, ownProps: OwnProps) => AnyLiteral; +type ActivationFn = (global: GlobalState, ownProps: OwnProps) => boolean; let currentGlobal = {} as GlobalState; @@ -56,12 +54,10 @@ const immediateCallbacks: Function[] = []; const actions = {} as Actions; const containers = new Map; + activationFn?: ActivationFn; ownProps: Props; mappedProps?: Props; forceUpdate: Function; - isDetached: boolean; - detachReason: any; - detachWhenChanged: DetachWhenChanged; DEBUG_updates: number; DEBUG_componentName: string; }>(); @@ -165,21 +161,17 @@ function updateContainers() { // eslint-disable-next-line no-restricted-syntax for (const container of containers.values()) { const { - mapStateToProps, ownProps, mappedProps, forceUpdate, isDetached, detachWhenChanged, + mapStateToProps, activationFn, ownProps, mappedProps, forceUpdate, } = container; - if (isDetached) { + if (activationFn && !activationFn(currentGlobal, ownProps)) { continue; } let newMappedProps; try { - newMappedProps = mapStateToProps(currentGlobal, ownProps, detachWhenChanged); - - if (container.isDetached) { - continue; - } + newMappedProps = mapStateToProps(currentGlobal, ownProps); } catch (err: any) { handleError(err); @@ -246,6 +238,7 @@ export function removeCallback(cb: Function, isImmediate = false) { export function withGlobal( mapStateToProps: MapStateToProps = () => ({}), + activationFn?: ActivationFn, ) { return (Component: FC) => { function TeactNContainer(props: OwnProps) { @@ -262,20 +255,9 @@ export function withGlobal( if (!container) { container = { mapStateToProps, + activationFn, ownProps: props, forceUpdate, - isDetached: false, - detachReason: undefined, - // This allows to ignore changes in global during animation before unmount - detachWhenChanged: (current) => { - const { detachReason } = container!; - - if (detachReason === undefined && current !== undefined) { - container!.detachReason = current; - } else if (detachReason !== undefined && detachReason !== current) { - container!.isDetached = true; - } - }, DEBUG_updates: 0, DEBUG_componentName: Component.name, }; @@ -283,18 +265,19 @@ export function withGlobal( containers.set(id, container); } - if (!container.mappedProps || !arePropsShallowEqual(container.ownProps, props)) { - container.ownProps = props; - - if (!container.isDetached) { - try { - container.mappedProps = mapStateToProps(currentGlobal, props, container.detachWhenChanged); - } catch (err: any) { - handleError(err); - } + if (!container.mappedProps || ( + !arePropsShallowEqual(container.ownProps, props) + && (!activationFn || activationFn(currentGlobal, props)) + )) { + try { + container.mappedProps = mapStateToProps(currentGlobal, props); + } catch (err: any) { + handleError(err); } } + container.ownProps = props; + // eslint-disable-next-line react/jsx-props-no-spreading return ; } @@ -338,8 +321,8 @@ export function typify< handler: ActionHandlers[ActionName], ) => void, withGlobal: withGlobal as ( - mapStateToProps: ( - (global: ProjectGlobalState, ownProps: OwnProps, detachWhenChanged: DetachWhenChanged) => AnyLiteral), + mapStateToProps: (global: ProjectGlobalState, ownProps: OwnProps) => AnyLiteral, + activationFn?: (global: ProjectGlobalState, ownProps: OwnProps) => boolean, ) => (Component: FC) => FC, }; }