Browse Source

enable perfmode by default

AykutSarac 2 năm trước cách đây
mục cha
commit
74125565f9

+ 1 - 1
package.json

@@ -26,8 +26,8 @@
     "react-dom": "^18.2.0",
     "react-hot-toast": "^2.3.0",
     "react-icons": "^4.4.0",
+    "react-in-viewport": "^1.0.0-alpha.28",
     "react-linkify-it": "^1.0.7",
-    "react-render-if-visible": "^2.1.0",
     "react-twitter-embed": "^4.0.4",
     "react-zoom-pan-pinch": "^2.1.3",
     "reaflow": "^5.0.6",

+ 34 - 23
src/components/CustomNode/ObjectNode.tsx

@@ -1,6 +1,7 @@
 import React from "react";
-import { ConditionalWrapper, CustomNodeProps } from "src/components/CustomNode";
+import { CustomNodeProps } from "src/components/CustomNode";
 import useConfig from "src/hooks/store/useConfig";
+import { useInViewport } from "react-in-viewport";
 import * as Styled from "./styles";
 
 const ObjectNode: React.FC<CustomNodeProps<[string, string][]>> = ({
@@ -10,31 +11,41 @@ const ObjectNode: React.FC<CustomNodeProps<[string, string][]>> = ({
   x,
   y,
 }) => {
+  const ref = React.useRef(null);
+  const { inViewport } = useInViewport(ref);
   const performanceMode = useConfig((state) => state.performanceMode);
 
   return (
-    <Styled.StyledForeignObject width={width} height={height} x={0} y={0}>
-      <ConditionalWrapper condition={performanceMode}>
-        <Styled.StyledText width={width} height={height}>
-          {value.map((val, idx) => (
-            <Styled.StyledRow
-              data-key={JSON.stringify(val[1])}
-              data-x={x}
-              data-y={y}
-              key={idx}
-              width={`${width - 20}px`}
-              value={JSON.stringify(val[1])}
-            >
-              <Styled.StyledKey objectKey>
-                {JSON.stringify(val[0]).replaceAll('"', "")}:{" "}
-              </Styled.StyledKey>
-              <Styled.StyledLinkItUrl>
-                {JSON.stringify(val[1])}
-              </Styled.StyledLinkItUrl>
-            </Styled.StyledRow>
-          ))}
-        </Styled.StyledText>
-      </ConditionalWrapper>
+    <Styled.StyledForeignObject
+      width={width}
+      height={height}
+      x={0}
+      y={0}
+      ref={ref}
+    >
+      {(!performanceMode || inViewport) && (
+        <Styled.StyledTextWrapper>
+          <Styled.StyledText width={width} height={height}>
+            {value.map((val, idx) => (
+              <Styled.StyledRow
+                data-key={JSON.stringify(val[1])}
+                data-x={x}
+                data-y={y}
+                key={idx}
+                width={`${width - 20}px`}
+                value={JSON.stringify(val[1])}
+              >
+                <Styled.StyledKey objectKey>
+                  {JSON.stringify(val[0]).replaceAll('"', "")}:{" "}
+                </Styled.StyledKey>
+                <Styled.StyledLinkItUrl>
+                  {JSON.stringify(val[1])}
+                </Styled.StyledLinkItUrl>
+              </Styled.StyledRow>
+            ))}
+          </Styled.StyledText>
+        </Styled.StyledTextWrapper>
+      )}
     </Styled.StyledForeignObject>
   );
 };

+ 28 - 20
src/components/CustomNode/TextNode.tsx

@@ -1,6 +1,7 @@
 import React from "react";
 import { MdCompareArrows } from "react-icons/md";
-import { ConditionalWrapper, CustomNodeProps } from "src/components/CustomNode";
+import { useInViewport } from "react-in-viewport";
+import { CustomNodeProps } from "src/components/CustomNode";
 import useConfig from "src/hooks/store/useConfig";
 import useGraph from "src/hooks/store/useGraph";
 import useStored from "src/hooks/store/useStored";
@@ -37,7 +38,10 @@ const TextNode: React.FC<
   x,
   y,
 }) => {
+  const ref = React.useRef(null);
+  const { inViewport } = useInViewport(ref);
   const performanceMode = useConfig((state) => state.performanceMode);
+
   const hideCollapse = useStored((state) => state.hideCollapse);
   const expandNodes = useGraph((state) => state.expandNodes);
   const collapseNodes = useGraph((state) => state.collapseNodes);
@@ -58,27 +62,31 @@ const TextNode: React.FC<
       x={0}
       y={0}
       data-nodeid={node.id}
+      ref={ref}
     >
-      <ConditionalWrapper condition={performanceMode}>
-        <Styled.StyledText
-          hideCollapse={hideCollapse}
-          hasCollapse={isParent && hasCollapse}
-          width={width}
-          height={height}
-        >
-          <Styled.StyledKey
-            data-x={x}
-            data-y={y}
-            data-key={JSON.stringify(value)}
-            parent={isParent}
+      {(!performanceMode || inViewport) && (
+        <Styled.StyledTextWrapper>
+          <Styled.StyledText
+            hideCollapse={hideCollapse}
+            hasCollapse={isParent && hasCollapse}
+            width={width}
+            height={height}
           >
-            <Styled.StyledLinkItUrl>
-              {JSON.stringify(value).replaceAll('"', "")}
-            </Styled.StyledLinkItUrl>
-          </Styled.StyledKey>
-        </Styled.StyledText>
-      </ConditionalWrapper>
-      {isParent && hasCollapse && !hideCollapse && (
+            <Styled.StyledKey
+              data-x={x}
+              data-y={y}
+              data-key={JSON.stringify(value)}
+              parent={isParent}
+            >
+              <Styled.StyledLinkItUrl>
+                {JSON.stringify(value).replaceAll('"', "")}
+              </Styled.StyledLinkItUrl>
+            </Styled.StyledKey>
+          </Styled.StyledText>
+        </Styled.StyledTextWrapper>
+      )}
+
+      {inViewport && isParent && hasCollapse && !hideCollapse && (
         <StyledExpand onClick={handleExpand}>
           <MdCompareArrows size={18} />
         </StyledExpand>

+ 0 - 14
src/components/CustomNode/index.tsx

@@ -1,8 +1,6 @@
 import React from "react";
-import RenderIfVisible from "react-render-if-visible";
 import { Label, Node, NodeProps } from "reaflow";
 import ObjectNode from "./ObjectNode";
-import { StyledTextWrapper } from "./styles";
 import TextNode from "./TextNode";
 
 export interface CustomNodeProps<T> {
@@ -20,18 +18,6 @@ const baseLabelStyle = {
   strokeWidth: 0,
 };
 
-export const ConditionalWrapper: React.FC<{
-  condition?: boolean;
-  children: React.ReactNode;
-}> = ({ condition, children }) =>
-  condition ? (
-    <RenderIfVisible rootElementClass="renderVisible">
-      {children}
-    </RenderIfVisible>
-  ) : (
-    <StyledTextWrapper>{children}</StyledTextWrapper>
-  );
-
 export const CustomNode = (nodeProps: NodeProps) => {
   const { properties } = nodeProps;
 

+ 0 - 25
src/containers/Editor/Settings.tsx

@@ -1,9 +1,6 @@
 import React from "react";
-import toast from "react-hot-toast";
-import { IoAlertCircleSharp } from "react-icons/io5";
 import { Modal } from "src/components/Modal";
 import Toggle from "src/components/Toggle";
-import useConfig from "src/hooks/store/useConfig";
 import useStored from "src/hooks/store/useStored";
 import styled from "styled-components";
 import shallow from "zustand/shallow";
@@ -13,10 +10,6 @@ const StyledToggle = styled(Toggle)`
   background: black;
 `;
 
-const StyledAlertIcon = styled(IoAlertCircleSharp)`
-  color: ${({ theme }) => theme.ORANGE};
-`;
-
 const StyledModalWrapper = styled.div`
   display: flex;
   flex-direction: column;
@@ -27,25 +20,10 @@ export const Settings: React.FC<{
   visible: boolean;
   setVisible: React.Dispatch<React.SetStateAction<boolean>>;
 }> = ({ visible, setVisible }) => {
-  const performanceMode = useConfig((state) => state.performanceMode);
   const [toggleHideCollapse, hideCollapse] = useStored(
     (state) => [state.toggleHideCollapse, state.hideCollapse],
     shallow
   );
-  const setConfig = useConfig((state) => state.setConfig);
-
-  const togglePerformance = () => {
-    const toastMsg = performanceMode
-      ? "Disabled Performance Mode\nSearch Node & Save Image enabled."
-      : "Enabled Performance Mode\nSearch Node & Save Image disabled.";
-
-    toast(toastMsg, {
-      icon: <StyledAlertIcon size={36} />,
-      duration: 3000,
-    });
-
-    setConfig("performanceMode", !performanceMode);
-  };
 
   return (
     <Modal visible={visible} setVisible={setVisible}>
@@ -55,9 +33,6 @@ export const Settings: React.FC<{
           <StyledToggle onChange={toggleHideCollapse} checked={hideCollapse}>
             Hide Collapse/Expand Button
           </StyledToggle>
-          <StyledToggle onChange={togglePerformance} checked={performanceMode}>
-            Performance Mode (Experimental)
-          </StyledToggle>
         </StyledModalWrapper>
       </Modal.Content>
       <Modal.Controls setVisible={setVisible} />

+ 8 - 15
src/containers/Editor/Tools.tsx

@@ -52,11 +52,7 @@ export const Tools: React.FC = () => {
   const lightmode = useStored((state) => state.lightmode);
   const setLightTheme = useStored((state) => state.setLightTheme);
 
-  const [performanceMode, hideEditor] = useConfig(
-    (state) => [state.performanceMode, state.hideEditor],
-    shallow
-  );
-
+  const hideEditor = useConfig((state) => state.hideEditor);
   const setConfig = useConfig((state) => state.setConfig);
 
   const zoomIn = useConfig((state) => state.zoomIn);
@@ -79,16 +75,13 @@ export const Tools: React.FC = () => {
       <StyledToolElement aria-label="switch theme" onClick={toggleTheme}>
         {lightmode ? <HiOutlineMoon /> : <HiOutlineSun />}
       </StyledToolElement>
-      {!performanceMode && <SearchInput />}
-
-      {!performanceMode && (
-        <StyledToolElement
-          aria-label="save"
-          onClick={() => setDownloadVisible(true)}
-        >
-          <FiDownload />
-        </StyledToolElement>
-      )}
+      <SearchInput />
+      <StyledToolElement
+        aria-label="save"
+        onClick={() => setDownloadVisible(true)}
+      >
+        <FiDownload />
+      </StyledToolElement>
       <StyledToolElement aria-label="center canvas" onClick={centerView}>
         <MdCenterFocusWeak />
       </StyledToolElement>

+ 6 - 0
src/containers/Modals/DownloadModal/index.tsx

@@ -8,6 +8,7 @@ import { TwitterPicker } from "react-color";
 import { TwitterPickerStylesProps } from "react-color/lib/components/twitter/Twitter";
 import styled from "styled-components";
 import toast from "react-hot-toast";
+import useConfig from "src/hooks/store/useConfig";
 
 const ColorPickerStyles: Partial<TwitterPickerStylesProps> = {
   card: {
@@ -95,6 +96,7 @@ export const DownloadModal: React.FC<ModalProps> = ({
   visible,
   setVisible,
 }) => {
+  const setConfig = useConfig((state) => state.setConfig);
   const [fileDetails, setFileDetails] = React.useState({
     filename: "jsoncrack.com",
     backgroundColor: "transparent",
@@ -104,6 +106,7 @@ export const DownloadModal: React.FC<ModalProps> = ({
   const clipboardImage = async () => {
     try {
       toast.loading("Copying to clipboard...", { id: "toastClipboard" });
+      setConfig("performanceMode", false);
 
       const imageElement = document.querySelector(
         "svg[id*='ref']"
@@ -128,12 +131,14 @@ export const DownloadModal: React.FC<ModalProps> = ({
     } finally {
       toast.dismiss("toastClipboard");
       setVisible(false);
+      setConfig("performanceMode", true);
     }
   };
 
   const exportAsImage = async () => {
     try {
       toast.loading("Downloading...", { id: "toastDownload" });
+      setConfig("performanceMode", false);
 
       const imageElement = document.querySelector(
         "svg[id*='ref']"
@@ -150,6 +155,7 @@ export const DownloadModal: React.FC<ModalProps> = ({
     } finally {
       toast.dismiss("toastDownload");
       setVisible(false);
+      setConfig("performanceMode", true);
     }
   };
 

+ 1 - 1
src/hooks/store/useConfig.tsx

@@ -27,7 +27,7 @@ const initialStates: Config = {
   layout: "RIGHT",
   expand: true,
   hideEditor: false,
-  performanceMode: false,
+  performanceMode: true,
 };
 
 const useConfig = create<Config & ConfigActions>()((set, get) => ({

+ 7 - 5
yarn.lock

@@ -6019,6 +6019,13 @@ react-icons@^4.4.0:
   resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.4.0.tgz#a13a8a20c254854e1ec9aecef28a95cdf24ef703"
   integrity sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==
 
+react-in-viewport@^1.0.0-alpha.28:
+  version "1.0.0-alpha.28"
+  resolved "https://registry.yarnpkg.com/react-in-viewport/-/react-in-viewport-1.0.0-alpha.28.tgz#3957cb7931ec26582497acd14f7c3941f020fe75"
+  integrity sha512-SjBVCPUIRfJb516BUev1u/dejBfI5jIcskDz4Irq2RezNG7D199eER8reRzZX+w/FLxz21rpdqRbJbagv5n37Q==
+  dependencies:
+    hoist-non-react-statics "^3.0.0"
+
 react-is@^16.13.1, react-is@^16.7.0:
   version "16.13.1"
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@@ -6039,11 +6046,6 @@ react-linkify-it@^1.0.7:
   resolved "https://registry.yarnpkg.com/react-linkify-it/-/react-linkify-it-1.0.7.tgz#80486c0176644691345b19722678e4d716de5384"
   integrity sha512-B0Vy0KCAdpkT7Ql/bOpPuAP4l20f78Eaq1yD/q9J2RltPSwD900I0GzQPXaH6gnoWX/qmkBXL42Q3jTnWw8KCw==
 
-react-render-if-visible@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/react-render-if-visible/-/react-render-if-visible-2.1.0.tgz#2a8d3c3e2f32394c78967bb58ee7546666831605"
-  integrity sha512-mOLrj0eDezdTB9zxjBaOOP+cOHVKhoCQCk6qZlHev9a6Edb0eQs2CfHqBa1PNq3kfCW28NAS8QJMXXMJsUonxw==
-
 react-scrolllock@^5.0.1:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/react-scrolllock/-/react-scrolllock-5.0.1.tgz#da1cfb7b6d55c86ae41dbad5274b778c307752b7"