Selaa lähdekoodia

add mobile support

AykutSarac 2 vuotta sitten
vanhempi
commit
50f803d018

+ 50 - 6
src/components/Sidebar/index.tsx

@@ -12,6 +12,7 @@ import {
   AiOutlineSave,
   AiOutlineFileAdd,
   AiOutlineLink,
+  AiOutlineEdit,
 } from "react-icons/ai";
 
 import { Tooltip } from "src/components/Tooltip";
@@ -23,7 +24,7 @@ import useConfig from "src/hooks/store/useConfig";
 import { getNextLayout } from "src/containers/Editor/LiveEditor/helpers";
 import { HiHeart } from "react-icons/hi";
 import shallow from "zustand/shallow";
-import { IoAlertCircleSharp } from "react-icons/io5";
+import { MdCenterFocusWeak } from "react-icons/md";
 
 const StyledSidebar = styled.div`
   display: flex;
@@ -34,6 +35,11 @@ const StyledSidebar = styled.div`
   background: ${({ theme }) => theme.BACKGROUND_TERTIARY};
   padding: 4px;
   border-right: 1px solid ${({ theme }) => theme.BACKGROUND_MODIFIER_ACCENT};
+
+  @media only screen and (max-width: 568px) {
+    flex-direction: row;
+    width: 100%;
+  }
 `;
 
 const StyledElement = styled.div<{ beta?: boolean }>`
@@ -80,6 +86,26 @@ const StyledTopWrapper = styled.nav`
   & > div:nth-child(n + 1) {
     border-bottom: 1px solid ${({ theme }) => theme.BACKGROUND_MODIFIER_ACCENT};
   }
+
+  .mobile {
+    display: none;
+  }
+
+  @media only screen and (max-width: 568px) {
+    flex-direction: row;
+
+    & > div:nth-child(n + 1) {
+      border-bottom: none;
+    }
+
+    .mobile {
+      display: initial;
+    }
+
+    .desktop {
+      display: none;
+    }
+  }
 `;
 
 const StyledBottomWrapper = styled.nav`
@@ -93,6 +119,10 @@ const StyledBottomWrapper = styled.nav`
   a:nth-child(0) {
     border-top: 1px solid ${({ theme }) => theme.BACKGROUND_MODIFIER_ACCENT};
   }
+
+  @media only screen and (max-width: 568px) {
+    display: none;
+  }
 `;
 
 const StyledLogo = styled.div`
@@ -109,13 +139,14 @@ function rotateLayout(layout: CanvasDirection) {
 export const Sidebar: React.FC = () => {
   const getJson = useConfig((state) => state.getJson);
   const setConfig = useConfig((state) => state.setConfig);
+  const centerView = useConfig((state) => state.centerView);
   const [uploadVisible, setUploadVisible] = React.useState(false);
   const [clearVisible, setClearVisible] = React.useState(false);
   const [shareVisible, setShareVisible] = React.useState(false);
   const { push } = useRouter();
 
-  const [expand, layout] = useConfig(
-    (state) => [state.expand, state.layout],
+  const [expand, layout, hideEditor] = useConfig(
+    (state) => [state.expand, state.layout, state.hideEditor],
     shallow
   );
 
@@ -149,6 +180,11 @@ export const Sidebar: React.FC = () => {
             </StyledLogo>
           </StyledElement>
         </Link>
+        <Tooltip className="mobile" title="Edit JSON">
+          <StyledElement onClick={() => setConfig("hideEditor", !hideEditor)}>
+            <AiOutlineEdit />
+          </StyledElement>
+        </Tooltip>
         <Tooltip title="Import File">
           <StyledElement onClick={() => setUploadVisible(true)}>
             <AiOutlineFileAdd />
@@ -159,7 +195,15 @@ export const Sidebar: React.FC = () => {
             <StyledFlowIcon rotate={rotateLayout(layout)} />
           </StyledElement>
         </Tooltip>
-        <Tooltip title={expand ? "Shrink Nodes" : "Expand Nodes"}>
+        <Tooltip className="mobile" title="Center View">
+          <StyledElement onClick={centerView}>
+            <MdCenterFocusWeak />
+          </StyledElement>
+        </Tooltip>
+        <Tooltip
+          className="desktop"
+          title={expand ? "Shrink Nodes" : "Expand Nodes"}
+        >
           <StyledElement
             title="Toggle Expand/Collapse"
             onClick={toggleExpandCollapse}
@@ -167,7 +211,7 @@ export const Sidebar: React.FC = () => {
             {expand ? <CgArrowsMergeAltH /> : <CgArrowsShrinkH />}
           </StyledElement>
         </Tooltip>
-        <Tooltip title="Save JSON">
+        <Tooltip className="desktop" title="Save JSON">
           <StyledElement onClick={handleSave}>
             <AiOutlineSave />
           </StyledElement>
@@ -177,7 +221,7 @@ export const Sidebar: React.FC = () => {
             <AiOutlineDelete />
           </StyledElement>
         </Tooltip>
-        <Tooltip title="Share">
+        <Tooltip className="desktop" title="Share">
           <StyledElement onClick={() => setShareVisible(true)}>
             <AiOutlineLink />
           </StyledElement>

+ 7 - 2
src/components/Tooltip/index.tsx

@@ -1,7 +1,7 @@
 import React from "react";
 import styled from "styled-components";
 
-interface TooltipProps {
+interface TooltipProps extends React.ComponentPropsWithoutRef<"div"> {
   title?: string;
 }
 
@@ -41,6 +41,10 @@ const StyledTooltip = styled.div<{ visible: boolean }>`
     border-color: transparent ${({ theme }) => theme.BACKGROUND_PRIMARY}
       transparent transparent;
   }
+
+  @media only screen and (max-width: 568px) {
+    display: none;
+  }
 `;
 
 const StyledChildren = styled.div``;
@@ -48,11 +52,12 @@ const StyledChildren = styled.div``;
 export const Tooltip: React.FC<React.PropsWithChildren<TooltipProps>> = ({
   children,
   title,
+  ...props
 }) => {
   const [visible, setVisible] = React.useState(false);
 
   return (
-    <StyledTooltipWrapper>
+    <StyledTooltipWrapper {...props}>
       {title && <StyledTooltip visible={visible}>{title}</StyledTooltip>}
 
       <StyledChildren

+ 1 - 0
src/constants/globalStyle.ts

@@ -10,6 +10,7 @@ const GlobalStyle = createGlobalStyle`
     font-weight: 400;
     font-size: 16px;
     scroll-behavior: smooth;
+    height: 100%;
 
     background-color: #000000;
     opacity: 1;

+ 7 - 6
src/containers/Editor/Panes.tsx

@@ -1,4 +1,4 @@
-import { Allotment } from "allotment";
+import { Allotment, LayoutPriority } from "allotment";
 import React from "react";
 import { JsonEditor } from "src/containers/Editor/JsonEditor";
 import dynamic from "next/dynamic";
@@ -18,18 +18,19 @@ const LiveEditor = dynamic(() => import("src/containers/Editor/LiveEditor"), {
 
 const Panes: React.FC = () => {
   const hideEditor = useConfig((state) => state.hideEditor);
+  const isMobile = window.innerWidth <= 568;
 
   return (
-    <StyledEditor>
+    <StyledEditor proportionalLayout={false} vertical={isMobile}>
       <Allotment.Pane
-        preferredSize={400}
-        minSize={300}
-        maxSize={600}
+        preferredSize={isMobile ? "100%" : 400}
+        minSize={hideEditor ? 0 : 300}
+        maxSize={isMobile ? Infinity : 500}
         visible={!hideEditor}
       >
         <JsonEditor />
       </Allotment.Pane>
-      <Allotment.Pane>
+      <Allotment.Pane minSize={0} maxSize={isMobile && !hideEditor ? 0 : Infinity}>
         <LiveEditor />
       </Allotment.Pane>
     </StyledEditor>

+ 4 - 1
src/containers/Editor/Tools.tsx

@@ -25,8 +25,11 @@ export const StyledTools = styled.div`
   padding: 4px 16px;
   background: ${({ theme }) => theme.BACKGROUND_PRIMARY};
   color: ${({ theme }) => theme.SILVER};
-
   box-shadow: 0 1px 0px ${({ theme }) => theme.BACKGROUND_TERTIARY};
+
+  @media only screen and (max-width: 568px) {
+    display: none;
+  }
 `;
 
 const StyledToolElement = styled.button`

+ 2 - 5
src/containers/Home/index.tsx

@@ -60,11 +60,8 @@ const Home: React.FC = () => {
         <Styles.StyledMinorTitle>
           Paste - Import - Fetch!
         </Styles.StyledMinorTitle>
-        <Styles.StyledButton
-          onClick={() => window.location.replace("/editor")}
-          disabled={isMobile}
-        >
-          {isMobile ? "Incompatible Device" : "GO TO EDITOR"}
+        <Styles.StyledButton onClick={() => window.location.replace("/editor")}>
+          GO TO EDITOR
         </Styles.StyledButton>
 
         {!isMobile && (

+ 0 - 47
src/containers/Incompatible/index.tsx

@@ -1,47 +0,0 @@
-import { useRouter } from "next/router";
-import React from "react";
-import { Button } from "src/components/Button";
-import styled from "styled-components";
-
-export const StyledIncompatible = styled.div`
-  display: none;
-
-  @media only screen and (max-width: 568px) {
-    position: fixed;
-    top: 0;
-    left: 0;
-    display: flex;
-    flex-direction: column;
-    background: ${({ theme }) => theme.BLACK_LIGHT};
-    color: ${({ theme }) => theme.SILVER};
-    width: 100%;
-    height: 100vh;
-    justify-content: center;
-    align-items: center;
-    z-index: 200;
-
-    button {
-      margin-top: 60px;
-    }
-
-    &::before {
-      content: "Uh, oh!";
-      font-weight: 600;
-      font-size: 60px;
-      opacity: 0.6;
-    }
-  }
-`;
-
-export const Incompatible: React.FC = () => {
-  const { push } = useRouter();
-
-  return (
-    <StyledIncompatible>
-      This app is not compatible with your device!
-      <Button className="incompatible" onClick={() => push("/")}>
-        Go Back
-      </Button>
-    </StyledIncompatible>
-  );
-};

+ 9 - 2
src/pages/Editor/index.tsx

@@ -3,15 +3,23 @@ import Head from "next/head";
 import styled from "styled-components";
 import Panes from "src/containers/Editor/Panes";
 import { Sidebar } from "src/components/Sidebar";
-import { Incompatible } from "src/containers/Incompatible";
 
 export const StyledPageWrapper = styled.div`
   display: flex;
+  flex-direction: row;
   height: 100vh;
+  width: 100%;
+
+  @media only screen and (max-width: 568px) {
+    position: fixed;
+    height: -webkit-fill-available;
+    flex-direction: column;
+  }
 `;
 
 export const StyledEditorWrapper = styled.div`
   width: 100%;
+  height: 100%;
   overflow: hidden;
 `;
 
@@ -30,7 +38,6 @@ const EditorPage: React.FC = () => {
         <StyledEditorWrapper>
           <Panes />
         </StyledEditorWrapper>
-        <Incompatible />
       </StyledPageWrapper>
     </StyledEditorWrapper>
   );