update icons & options

This commit is contained in:
AykutSarac 2022-05-04 21:08:17 +03:00
parent c71832525e
commit 0539e0b72f
7 changed files with 84 additions and 109 deletions

View File

@ -1,29 +1,22 @@
import React from "react";
import toast from "react-hot-toast";
import Link from "next/link";
import styled from "styled-components";
import { FaFileImport } from "react-icons/fa";
import { CanvasDirection } from "reaflow";
import { TiFlowMerge } from "react-icons/ti";
import { BsList } from "react-icons/bs";
import { MdUploadFile } from "react-icons/md";
import { RiPatreonFill } from "react-icons/ri";
import { CgArrowsMergeAltH, CgArrowsShrinkH } from "react-icons/cg";
import {
MdUnfoldMore,
MdUnfoldLess,
MdAutoFixHigh,
MdOutlineAutoFixOff,
} from "react-icons/md";
import {
AiFillHome,
AiFillDelete,
AiOutlineDelete,
AiFillGithub,
AiOutlineTwitter,
AiOutlineSave,
AiOutlineFileAdd,
} from "react-icons/ai";
import {
CgArrowLongDownE,
CgArrowLongLeftE,
CgArrowLongRightE,
CgArrowLongUpE,
} from "react-icons/cg";
import { CanvasDirection } from "reaflow";
import toast from "react-hot-toast";
import { Tooltip } from "../Tooltip";
import { Tooltip } from "src/components/Tooltip";
import { ConfigActionType } from "src/reducer/reducer";
import { useConfig } from "src/hocs/config";
import { useRouter } from "next/router";
@ -33,7 +26,7 @@ const StyledSidebar = styled.div`
justify-content: space-between;
flex-direction: column;
align-items: center;
width: 42px;
width: 36px;
background: ${({ theme }) => theme.BACKGROUND_TERTIARY};
padding: 8px;
border-right: 1px solid ${({ theme }) => theme.BACKGROUND_MODIFIER_ACCENT};
@ -64,6 +57,10 @@ const StyledText = styled.span<{ secondary?: boolean }>`
secondary ? theme.INTERACTIVE_NORMAL : theme.ORANGE};
`;
const StyledFlowIcon = styled(TiFlowMerge)<{ rotate: number }>`
transform: rotate(${({ rotate }) => `${rotate}deg`});
`;
const StyledTopWrapper = styled.nav`
display: flex;
justify-content: space-between;
@ -101,15 +98,15 @@ const StyledImportFile = styled.label`
}
`;
function getLayoutIcon(layout: CanvasDirection) {
if (layout === "LEFT") return <CgArrowLongLeftE />;
if (layout === "UP") return <CgArrowLongUpE />;
if (layout === "RIGHT") return <CgArrowLongRightE />;
return <CgArrowLongDownE />;
function rotateLayout(layout: CanvasDirection) {
if (layout === "LEFT") return 90;
if (layout === "UP") return 180;
if (layout === "RIGHT") return 270;
return 360;
}
export const Sidebar: React.FC = () => {
const { settings, dispatch } = useConfig();
const { json, settings, dispatch } = useConfig();
const router = useRouter();
const [jsonFile, setJsonFile] = React.useState<File | null>(null);
@ -123,11 +120,9 @@ export const Sidebar: React.FC = () => {
toast.success(`Cleared JSON and removed from memory.`);
};
const toggleAutoFormat = () => {
dispatch({ type: ConfigActionType.TOGGLE_AUTOFORMAT });
toast(
`Auto format has been ${settings.autoformat ? "disabled." : "enabled."}`
);
const handleSave = () => {
localStorage.setItem("json", json);
toast.success("Saved JSON successfully!");
};
const toggleExpandCollapse = () => {
@ -160,36 +155,6 @@ export const Sidebar: React.FC = () => {
</StyledLogo>
</StyledElement>
</Link>
<Tooltip title="Home">
<StyledElement onClick={() => router.push("/")}>
<AiFillHome />
</StyledElement>
</Tooltip>
<Tooltip title="Auto Format">
<StyledElement onClick={toggleAutoFormat}>
{settings.autoformat ? <MdAutoFixHigh /> : <MdOutlineAutoFixOff />}
</StyledElement>
</Tooltip>
<Tooltip title="Change Layout">
<StyledElement
onClick={() => dispatch({ type: ConfigActionType.TOGGLE_LAYOUT })}
>
{getLayoutIcon(settings.layout)}
</StyledElement>
</Tooltip>
<Tooltip title="Toggle Compact Nodes">
<StyledElement
title="Toggle Expand/Collapse"
onClick={toggleExpandCollapse}
>
{settings.expand ? <MdUnfoldMore /> : <MdUnfoldLess />}
</StyledElement>
</Tooltip>
<Tooltip title="Clear JSON">
<StyledElement onClick={handleClear}>
<AiFillDelete />
</StyledElement>
</Tooltip>
<Tooltip title="Import File">
<StyledElement>
<StyledImportFile>
@ -199,10 +164,35 @@ export const Sidebar: React.FC = () => {
type="file"
accept="application/JSON"
/>
<FaFileImport />
<AiOutlineFileAdd />
</StyledImportFile>
</StyledElement>
</Tooltip>
<Tooltip title="Change Layout">
<StyledElement
onClick={() => dispatch({ type: ConfigActionType.TOGGLE_LAYOUT })}
>
<StyledFlowIcon rotate={rotateLayout(settings.layout)} />
</StyledElement>
</Tooltip>
<Tooltip title={settings.expand ? "Shrink Nodes" : "Expand Nodes"}>
<StyledElement
title="Toggle Expand/Collapse"
onClick={toggleExpandCollapse}
>
{settings.expand ? <CgArrowsMergeAltH /> : <CgArrowsShrinkH />}
</StyledElement>
</Tooltip>
<Tooltip title="Clear JSON">
<StyledElement onClick={handleClear}>
<AiOutlineDelete />
</StyledElement>
</Tooltip>
<Tooltip title="Save JSON">
<StyledElement onClick={handleSave}>
<AiOutlineSave />
</StyledElement>
</Tooltip>
</StyledTopWrapper>
<StyledBottomWrapper>
<StyledElement>
@ -219,6 +209,13 @@ export const Sidebar: React.FC = () => {
</a>
</Link>
</StyledElement>
<StyledElement>
<Link href="https://www.patreon.com/aykutsarac">
<a aria-label="Patreon" rel="me" target="_blank">
<RiPatreonFill />
</a>
</Link>
</StyledElement>
</StyledBottomWrapper>
</StyledSidebar>
);

View File

@ -15,7 +15,7 @@ const StyledTooltip = styled.div<{ visible: boolean }>`
position: absolute;
top: 0;
right: 0;
transform: translate(calc(100% + 15px), 25%);
transform: translate(calc(100% + 15px), 20%);
z-index: 5;
background: ${({ theme }) => theme.BACKGROUND_PRIMARY};
color: ${({ theme }) => theme.TEXT_NORMAL};

View File

@ -36,7 +36,6 @@ export const defaultJson = {
export const defaultConfig: StorageConfig = {
layout: "RIGHT",
expand: true,
autoformat: true,
hideEditor: false,
zoomPanPinch: null,
lightmode: false

View File

@ -2,10 +2,10 @@ import React from "react";
import toast from "react-hot-toast";
import {
AiOutlineFullscreen,
AiOutlineSave,
AiOutlineMinus,
AiOutlinePlus,
} from "react-icons/ai";
import { FiDownload } from "react-icons/fi";
import { HiOutlineSun, HiOutlineMoon } from "react-icons/hi";
import { MdCenterFocusWeak } from "react-icons/md";
import { Input } from "src/components/Input";
@ -42,10 +42,6 @@ const StyledToolElement = styled.button`
export const Tools: React.FC = () => {
const { json, settings, dispatch } = useConfig();
const handleSave = () => {
localStorage.setItem("json", json);
toast.success("Saved JSON successfully!");
};
const zoomIn = () => dispatch({ type: ConfigActionType.ZOOM_IN });
@ -66,8 +62,13 @@ export const Tools: React.FC = () => {
{settings.lightmode ? <HiOutlineMoon /> : <HiOutlineSun />}
</StyledToolElement>
<Input />
<StyledToolElement aria-label="save" onClick={handleSave}>
<AiOutlineSave />
<StyledToolElement
aria-label="save"
onClick={() => {
// export as png
}}
>
<FiDownload />
</StyledToolElement>
<StyledToolElement aria-label="center canvas" onClick={centerView}>
<MdCenterFocusWeak />

View File

@ -2,7 +2,7 @@ import React from "react";
import Editor from "@monaco-editor/react";
import parseJson from "parse-json";
import styled from "styled-components";
import { ErrorContainer } from "../../components/ErrorContainer/ErrorContainer";
import { ErrorContainer } from "src/components/ErrorContainer/ErrorContainer";
import { ConfigActionType } from "src/reducer/reducer";
import { useConfig } from "src/hocs/config";
import { Loading } from "src/components/Loading";
@ -16,6 +16,7 @@ const StyledEditorWrapper = styled.div`
`;
const editorOptions = {
formatOnPaste: true,
minimap: {
enabled: false,
},
@ -35,36 +36,24 @@ export const JsonEditor: React.FC = () => {
);
React.useEffect(() => {
if (settings.autoformat) {
return setValue(JSON.stringify(JSON.parse(json), null, 2));
}
setValue(json);
}, [settings.autoformat, json]);
setValue(JSON.stringify(JSON.parse(json), null, 2));
}, [json]);
React.useEffect(() => {
const formatTimer = setTimeout(
() => {
try {
if (value) {
const parsedJson = parseJson(value);
if (settings.autoformat) {
setValue(JSON.stringify(parsedJson, null, 2));
} else {
setValue(value);
}
dispatch({ type: ConfigActionType.SET_JSON, payload: value });
}
const formatTimer = setTimeout(() => {
try {
if (!value) {
setError((err) => ({ ...err, message: "" }));
} catch (jsonError: any) {
setError((err) => ({ ...err, message: jsonError.message }));
return dispatch({ type: ConfigActionType.SET_JSON, payload: "[]" });
}
},
settings.autoformat ? 1200 : 1800
);
parseJson(value);
dispatch({ type: ConfigActionType.SET_JSON, payload: value });
setError((err) => ({ ...err, message: "" }));
} catch (jsonError: any) {
setError((err) => ({ ...err, message: jsonError.message }));
}
}, 1500);
return () => clearTimeout(formatTimer);
}, [value, dispatch]);
@ -76,8 +65,8 @@ export const JsonEditor: React.FC = () => {
height="100%"
defaultLanguage="json"
value={value}
options={editorOptions}
theme={editorTheme}
options={editorOptions}
loading={<Loading message="Loading Editor..." />}
onChange={(value) => setValue(value as string)}
/>

View File

@ -6,7 +6,6 @@ export enum ConfigActionType {
SET_CONFIG,
TOGGLE_LAYOUT,
TOGGLE_EXPAND,
TOGGLE_AUTOFORMAT,
TOGGLE_DOCK,
TOGGLE_THEME,
ZOOM_IN,
@ -70,15 +69,6 @@ export const useConfigReducer: React.Reducer<AppConfig, ReducerAction> = (
);
return state;
case ConfigActionType.TOGGLE_AUTOFORMAT:
return {
...state,
settings: {
...state.settings,
autoformat: !state.settings.autoformat,
},
};
case ConfigActionType.TOGGLE_DOCK:
return {
...state,

View File

@ -5,7 +5,6 @@ import { CanvasDirection } from "reaflow";
export interface StorageConfig {
layout: CanvasDirection;
expand: boolean;
autoformat: boolean;
hideEditor: boolean;
zoomPanPinch: ReactZoomPanPinchRef | null;
lightmode: boolean;