TeactN: Replace detachWhenChanged with activationFn

This commit is contained in:
Alexander Zinchuk 2023-09-04 04:05:26 +02:00
parent 44c31ff6a0
commit 1fc598a7e3
3 changed files with 24 additions and 45 deletions

View File

@ -280,9 +280,7 @@ const ForumPanel: FC<OwnProps & StateProps> = ({
}; };
export default memo(withGlobal<OwnProps>( export default memo(withGlobal<OwnProps>(
(global, ownProps, detachWhenChanged): StateProps => { (global): StateProps => {
detachWhenChanged(selectIsForumPanelOpen(global));
const chatId = selectTabState(global).forumPanelChatId; const chatId = selectTabState(global).forumPanelChatId;
const chat = chatId ? selectChat(global, chatId) : undefined; const chat = chatId ? selectChat(global, chatId) : undefined;
const { const {
@ -296,4 +294,5 @@ export default memo(withGlobal<OwnProps>(
withInterfaceAnimations: selectCanAnimateInterface(global), withInterfaceAnimations: selectCanAnimateInterface(global),
}; };
}, },
(global) => selectIsForumPanelOpen(global),
)(ForumPanel)); )(ForumPanel));

View File

@ -294,7 +294,7 @@ function StorySlides({
); );
} }
export default memo(withGlobal<OwnProps>((global, ownProps, detachWhenChanged): StateProps => { export default memo(withGlobal<OwnProps>((global): StateProps => {
const { const {
storyViewer: { storyViewer: {
userId: currentUserId, storyId: currentStoryId, isSingleUser, isSingleStory, isPrivate, isArchive, userId: currentUserId, storyId: currentStoryId, isSingleUser, isSingleStory, isPrivate, isArchive,
@ -303,9 +303,6 @@ export default memo(withGlobal<OwnProps>((global, ownProps, detachWhenChanged):
const { byUserId, orderedUserIds: { archived, active } } = global.stories; const { byUserId, orderedUserIds: { archived, active } } = global.stories;
const user = currentUserId ? selectUser(global, currentUserId) : undefined; const user = currentUserId ? selectUser(global, currentUserId) : undefined;
const isOpen = selectIsStoryViewerOpen(global);
detachWhenChanged(isOpen);
return { return {
byUserId, byUserId,
userIds: user?.areStoriesHidden ? archived : active, userIds: user?.areStoriesHidden ? archived : active,
@ -316,4 +313,4 @@ export default memo(withGlobal<OwnProps>((global, ownProps, detachWhenChanged):
isPrivate, isPrivate,
isArchive, isArchive,
}; };
})(StorySlides)); }, (global) => selectIsStoryViewerOpen(global))(StorySlides));

View File

@ -36,10 +36,8 @@ type ActionHandler = (
payload: any, payload: any,
) => GlobalState | void | Promise<void>; ) => GlobalState | void | Promise<void>;
type DetachWhenChanged = (current: any) => void; type MapStateToProps<OwnProps = undefined> = (global: GlobalState, ownProps: OwnProps) => AnyLiteral;
type MapStateToProps<OwnProps = undefined> = ( type ActivationFn<OwnProps = undefined> = (global: GlobalState, ownProps: OwnProps) => boolean;
(global: GlobalState, ownProps: OwnProps, detachWhenChanged: DetachWhenChanged) => AnyLiteral
);
let currentGlobal = {} as GlobalState; let currentGlobal = {} as GlobalState;
@ -56,12 +54,10 @@ const immediateCallbacks: Function[] = [];
const actions = {} as Actions; const actions = {} as Actions;
const containers = new Map<string, { const containers = new Map<string, {
mapStateToProps: MapStateToProps<any>; mapStateToProps: MapStateToProps<any>;
activationFn?: ActivationFn<any>;
ownProps: Props; ownProps: Props;
mappedProps?: Props; mappedProps?: Props;
forceUpdate: Function; forceUpdate: Function;
isDetached: boolean;
detachReason: any;
detachWhenChanged: DetachWhenChanged;
DEBUG_updates: number; DEBUG_updates: number;
DEBUG_componentName: string; DEBUG_componentName: string;
}>(); }>();
@ -165,21 +161,17 @@ function updateContainers() {
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
for (const container of containers.values()) { for (const container of containers.values()) {
const { const {
mapStateToProps, ownProps, mappedProps, forceUpdate, isDetached, detachWhenChanged, mapStateToProps, activationFn, ownProps, mappedProps, forceUpdate,
} = container; } = container;
if (isDetached) { if (activationFn && !activationFn(currentGlobal, ownProps)) {
continue; continue;
} }
let newMappedProps; let newMappedProps;
try { try {
newMappedProps = mapStateToProps(currentGlobal, ownProps, detachWhenChanged); newMappedProps = mapStateToProps(currentGlobal, ownProps);
if (container.isDetached) {
continue;
}
} catch (err: any) { } catch (err: any) {
handleError(err); handleError(err);
@ -246,6 +238,7 @@ export function removeCallback(cb: Function, isImmediate = false) {
export function withGlobal<OwnProps extends AnyLiteral>( export function withGlobal<OwnProps extends AnyLiteral>(
mapStateToProps: MapStateToProps<OwnProps> = () => ({}), mapStateToProps: MapStateToProps<OwnProps> = () => ({}),
activationFn?: ActivationFn<OwnProps>,
) { ) {
return (Component: FC) => { return (Component: FC) => {
function TeactNContainer(props: OwnProps) { function TeactNContainer(props: OwnProps) {
@ -262,20 +255,9 @@ export function withGlobal<OwnProps extends AnyLiteral>(
if (!container) { if (!container) {
container = { container = {
mapStateToProps, mapStateToProps,
activationFn,
ownProps: props, ownProps: props,
forceUpdate, 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_updates: 0,
DEBUG_componentName: Component.name, DEBUG_componentName: Component.name,
}; };
@ -283,18 +265,19 @@ export function withGlobal<OwnProps extends AnyLiteral>(
containers.set(id, container); containers.set(id, container);
} }
if (!container.mappedProps || !arePropsShallowEqual(container.ownProps, props)) { if (!container.mappedProps || (
container.ownProps = props; !arePropsShallowEqual(container.ownProps, props)
&& (!activationFn || activationFn(currentGlobal, props))
if (!container.isDetached) { )) {
try { try {
container.mappedProps = mapStateToProps(currentGlobal, props, container.detachWhenChanged); container.mappedProps = mapStateToProps(currentGlobal, props);
} catch (err: any) { } catch (err: any) {
handleError(err); handleError(err);
}
} }
} }
container.ownProps = props;
// eslint-disable-next-line react/jsx-props-no-spreading // eslint-disable-next-line react/jsx-props-no-spreading
return <Component {...container.mappedProps} {...props} />; return <Component {...container.mappedProps} {...props} />;
} }
@ -338,8 +321,8 @@ export function typify<
handler: ActionHandlers[ActionName], handler: ActionHandlers[ActionName],
) => void, ) => void,
withGlobal: withGlobal as <OwnProps extends AnyLiteral>( withGlobal: withGlobal as <OwnProps extends AnyLiteral>(
mapStateToProps: ( mapStateToProps: (global: ProjectGlobalState, ownProps: OwnProps) => AnyLiteral,
(global: ProjectGlobalState, ownProps: OwnProps, detachWhenChanged: DetachWhenChanged) => AnyLiteral), activationFn?: (global: ProjectGlobalState, ownProps: OwnProps) => boolean,
) => (Component: FC) => FC<OwnProps>, ) => (Component: FC) => FC<OwnProps>,
}; };
} }