From 924b6d42858dd4cddd8607fe54b97ba7217eea5b Mon Sep 17 00:00:00 2001
From: Fedor Katurov <gotham48@gmail.com>
Date: Fri, 5 Jun 2020 17:24:42 +0700
Subject: [PATCH] ignoring image modal key sliding when modal is shown

---
 src/components/node/NodeAudioBlock/index.tsx  |  5 +--
 .../node/NodeAudioImageBlock/index.tsx        |  5 +--
 .../node/NodeImageSlideBlock/index.tsx        | 24 +++++------
 src/components/node/NodeTextBlock/index.tsx   |  5 +--
 src/components/node/NodeVideoBlock/index.tsx  |  6 +--
 src/containers/node/NodeLayout/index.tsx      | 42 ++++++++++++-------
 src/redux/node/constants.ts                   | 22 +++++-----
 7 files changed, 54 insertions(+), 55 deletions(-)

diff --git a/src/components/node/NodeAudioBlock/index.tsx b/src/components/node/NodeAudioBlock/index.tsx
index 7a4bde45..6b3595e9 100644
--- a/src/components/node/NodeAudioBlock/index.tsx
+++ b/src/components/node/NodeAudioBlock/index.tsx
@@ -3,10 +3,9 @@ import { INode } from '~/redux/types';
 import { UPLOAD_TYPES } from '~/redux/uploads/constants';
 import { AudioPlayer } from '~/components/media/AudioPlayer';
 import * as styles from './styles.scss';
+import { INodeComponentProps } from '~/redux/node/constants';
 
-interface IProps {
-  node: INode;
-}
+interface IProps extends INodeComponentProps {}
 
 const NodeAudioBlock: FC<IProps> = ({ node }) => {
   const audios = useMemo(
diff --git a/src/components/node/NodeAudioImageBlock/index.tsx b/src/components/node/NodeAudioImageBlock/index.tsx
index 95eb3fde..366bd861 100644
--- a/src/components/node/NodeAudioImageBlock/index.tsx
+++ b/src/components/node/NodeAudioImageBlock/index.tsx
@@ -5,10 +5,9 @@ import { UPLOAD_TYPES } from '~/redux/uploads/constants';
 import path from 'ramda/es/path';
 import { getURL } from '~/utils/dom';
 import { PRESETS } from '~/constants/urls';
+import { INodeComponentProps } from '~/redux/node/constants';
 
-interface IProps {
-  node: INode;
-}
+interface IProps extends INodeComponentProps {}
 
 const NodeAudioImageBlock: FC<IProps> = ({ node }) => {
   const images = useMemo(
diff --git a/src/components/node/NodeImageSlideBlock/index.tsx b/src/components/node/NodeImageSlideBlock/index.tsx
index ad62265c..dbdfc494 100644
--- a/src/components/node/NodeImageSlideBlock/index.tsx
+++ b/src/components/node/NodeImageSlideBlock/index.tsx
@@ -1,24 +1,15 @@
-import React, { FC, useMemo, useState, useEffect, useRef, useCallback, KeyboardEvent } from 'react';
-import { ImageSwitcher } from '../ImageSwitcher';
+import React, { FC, useMemo, useState, useEffect, useRef, useCallback } from 'react';
 import * as styles from './styles.scss';
-import { INode } from '~/redux/types';
 import classNames from 'classnames';
 import { UPLOAD_TYPES } from '~/redux/uploads/constants';
-import { NODE_SETTINGS } from '~/redux/node/constants';
+import { INodeComponentProps } from '~/redux/node/constants';
 import { getURL } from '~/utils/dom';
 import { PRESETS } from '~/constants/urls';
 import { LoaderCircle } from '~/components/input/LoaderCircle';
 import { throttle } from 'throttle-debounce';
-import * as MODAL_ACTIONS from '~/redux/modal/actions';
 import { Icon } from '~/components/input/Icon';
 
-interface IProps {
-  is_loading: boolean;
-  node: INode;
-  layout: {};
-  updateLayout: () => void;
-  modalShowPhotoswipe: typeof MODAL_ACTIONS.modalShowPhotoswipe;
-}
+interface IProps extends INodeComponentProps {}
 
 const getX = event =>
   (event.touches && event.touches.length) || (event.changedTouches && event.changedTouches.length)
@@ -28,6 +19,7 @@ const getX = event =>
 const NodeImageSlideBlock: FC<IProps> = ({
   node,
   is_loading,
+  is_modal_shown,
   updateLayout,
   modalShowPhotoswipe,
 }) => {
@@ -250,7 +242,11 @@ const NodeImageSlideBlock: FC<IProps> = ({
 
   const onKeyDown = useCallback(
     event => {
-      if (event.target.tagName && ['TEXTAREA', 'INPUT'].includes(event.target.tagName)) return;
+      if (
+        (event.target.tagName && ['TEXTAREA', 'INPUT'].includes(event.target.tagName)) ||
+        is_modal_shown
+      )
+        return;
 
       switch (event.key) {
         case 'ArrowLeft':
@@ -259,7 +255,7 @@ const NodeImageSlideBlock: FC<IProps> = ({
           return onNext();
       }
     },
-    [onNext, onPrev]
+    [onNext, onPrev, is_modal_shown]
   );
 
   useEffect(() => {
diff --git a/src/components/node/NodeTextBlock/index.tsx b/src/components/node/NodeTextBlock/index.tsx
index 93100b84..a272ac17 100644
--- a/src/components/node/NodeTextBlock/index.tsx
+++ b/src/components/node/NodeTextBlock/index.tsx
@@ -3,10 +3,9 @@ import { INode } from '~/redux/types';
 import path from 'ramda/es/path';
 import { formatTextParagraphs } from '~/utils/dom';
 import * as styles from './styles.scss';
+import { INodeComponentProps } from '~/redux/node/constants';
 
-interface IProps {
-  node: INode;
-}
+interface IProps extends INodeComponentProps {}
 
 const NodeTextBlock: FC<IProps> = ({ node }) => (
   <div
diff --git a/src/components/node/NodeVideoBlock/index.tsx b/src/components/node/NodeVideoBlock/index.tsx
index 0c250b4c..9c03764c 100644
--- a/src/components/node/NodeVideoBlock/index.tsx
+++ b/src/components/node/NodeVideoBlock/index.tsx
@@ -1,11 +1,9 @@
 import React, { FC, useMemo } from 'react';
-import { INode } from '~/redux/types';
 import * as styles from './styles.scss';
 import path from 'ramda/es/path';
+import { INodeComponentProps } from '~/redux/node/constants';
 
-interface IProps {
-  node: INode;
-}
+interface IProps extends INodeComponentProps {}
 
 const NodeVideoBlock: FC<IProps> = ({ node }) => {
   const video = useMemo(() => {
diff --git a/src/containers/node/NodeLayout/index.tsx b/src/containers/node/NodeLayout/index.tsx
index b9385158..012dcf71 100644
--- a/src/containers/node/NodeLayout/index.tsx
+++ b/src/containers/node/NodeLayout/index.tsx
@@ -12,7 +12,12 @@ import { NodeNoComments } from '~/components/node/NodeNoComments';
 import { NodeRelated } from '~/components/node/NodeRelated';
 import { NodeComments } from '~/components/node/NodeComments';
 import { NodeTags } from '~/components/node/NodeTags';
-import { NODE_COMPONENTS, NODE_INLINES, NODE_HEADS } from '~/redux/node/constants';
+import {
+  NODE_COMPONENTS,
+  NODE_INLINES,
+  NODE_HEADS,
+  INodeComponentProps,
+} from '~/redux/node/constants';
 import { selectUser } from '~/redux/auth/selectors';
 import pick from 'ramda/es/pick';
 import { NodeRelatedPlaceholder } from '~/components/node/NodeRelated/placeholder';
@@ -25,10 +30,12 @@ import * as styles from './styles.scss';
 import * as NODE_ACTIONS from '~/redux/node/actions';
 import * as MODAL_ACTIONS from '~/redux/modal/actions';
 import { IState } from '~/redux/store';
+import { selectModal } from '~/redux/modal/selectors';
 
 const mapStateToProps = (state: IState) => ({
   node: selectNode(state),
   user: selectUser(state),
+  modal: pick(['is_shown'])(selectModal(state)),
 });
 
 const mapDispatchToProps = {
@@ -63,6 +70,7 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
       comment_data,
       comment_count,
     },
+    modal: { is_shown: is_modal_shown },
     user,
     user: { is_user },
     nodeGotoNode,
@@ -106,6 +114,20 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
     const onStar = useCallback(() => nodeStar(node.id), [nodeStar, node]);
     const onLock = useCallback(() => nodeLock(node.id, !node.deleted_at), [nodeStar, node]);
 
+    const createNodeBlock = useCallback(
+      (block: FC<INodeComponentProps>) =>
+        block &&
+        createElement(block, {
+          node,
+          is_loading,
+          updateLayout,
+          layout,
+          modalShowPhotoswipe,
+          is_modal_shown,
+        }),
+      [node, is_loading, updateLayout, layout, modalShowPhotoswipe, is_modal_shown]
+    );
+
     useEffect(() => {
       if (!node.cover) return;
       nodeSetCoverImage(node.cover);
@@ -114,12 +136,10 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
 
     return (
       <>
-        {head &&
-          createElement(head, { node, is_loading, updateLayout, layout, modalShowPhotoswipe })}
+        {createNodeBlock(head)}
 
         <Card className={styles.node} seamless>
-          {block &&
-            createElement(block, { node, is_loading, updateLayout, layout, modalShowPhotoswipe })}
+          {createNodeBlock(block)}
 
           <NodePanel
             node={pick(
@@ -144,17 +164,7 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
               <Padder>
                 <Group horizontal className={styles.content}>
                   <Group className={styles.comments}>
-                    {inline && (
-                      <div className={styles.inline}>
-                        {createElement(inline, {
-                          node,
-                          is_loading,
-                          updateLayout,
-                          layout,
-                          modalShowPhotoswipe,
-                        })}
-                      </div>
-                    )}
+                    {inline && <div className={styles.inline}>{createNodeBlock(inline)}</div>}
 
                     {is_loading || is_loading_comments || (!comments.length && !inline) ? (
                       <NodeNoComments is_loading={is_loading_comments || is_loading} />
diff --git a/src/redux/node/constants.ts b/src/redux/node/constants.ts
index 981acceb..507168da 100644
--- a/src/redux/node/constants.ts
+++ b/src/redux/node/constants.ts
@@ -76,24 +76,22 @@ export const NODE_TYPES = {
   TEXT: 'text',
 };
 
-type INodeComponents = Record<
-  ValueOf<typeof NODE_TYPES>,
-  FC<{
-    node: INode;
-    is_loading: boolean;
-    layout: {};
-    updateLayout: () => void;
-    modalShowPhotoswipe: typeof modalShowPhotoswipe;
-  }>
->;
+export type INodeComponentProps = {
+  node: INode;
+  is_loading: boolean;
+  is_modal_shown: boolean;
+  layout: {};
+  updateLayout: () => void;
+  modalShowPhotoswipe: typeof modalShowPhotoswipe;
+};
+
+export type INodeComponents = Record<ValueOf<typeof NODE_TYPES>, FC<INodeComponentProps>>;
 
 export const NODE_HEADS: INodeComponents = {
-  // [NODE_TYPES.IMAGE]: NodeImageBlock,
   [NODE_TYPES.IMAGE]: NodeImageSlideBlock,
 };
 
 export const NODE_COMPONENTS: INodeComponents = {
-  // [NODE_TYPES.IMAGE]: NodeImageSlideBlock,
   [NODE_TYPES.VIDEO]: NodeVideoBlock,
   [NODE_TYPES.AUDIO]: NodeAudioImageBlock,
 };