From 6c0ebcf7bcc7f283b388d2f28528f08c8ff24f88 Mon Sep 17 00:00:00 2001 From: 1ilit Date: Sat, 9 Mar 2024 22:39:46 +0200 Subject: [PATCH] Abstract SettingsContext out --- src/App.jsx | 74 ++++++++-- src/components/Area.jsx | 6 +- src/components/Canvas.jsx | 4 +- src/components/ControlPanel.jsx | 4 +- src/components/Issues.jsx | 5 +- src/components/Relationship.jsx | 6 +- src/components/Sidebar.jsx | 4 +- src/components/Table.jsx | 4 +- src/context/SettingsContext.jsx | 21 +++ src/hooks/useLayout.js | 7 - src/hooks/useSettings.js | 6 + src/pages/BugReport.jsx | 14 +- src/pages/Editor.jsx | 237 ++++++++++++++------------------ src/pages/Shortcuts.jsx | 14 +- src/pages/Survey.jsx | 14 +- 15 files changed, 210 insertions(+), 210 deletions(-) create mode 100644 src/context/SettingsContext.jsx create mode 100644 src/hooks/useSettings.js diff --git a/src/App.jsx b/src/App.jsx index 4a054b7..d972c1f 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -4,39 +4,85 @@ import Survey from "./pages/Survey"; import BugReport from "./pages/BugReport"; import Shortcuts from "./pages/Shortcuts"; import Templates from "./pages/Templates"; -import { useEffect } from "react"; +import { useEffect, useLayoutEffect } from "react"; import LandingPage from "./pages/LandingPage"; -import LayoutContextProvider from "./context/LayoutContext"; +import SettingsContextProvider from "./context/SettingsContext"; +import useSettings from "./hooks/useSettings"; -const Wrapper = ({ children }) => { +function ThemedPage({ children }) { + const { setSettings } = useSettings(); + + useLayoutEffect(() => { + const theme = localStorage.getItem("theme"); + if (theme === "dark") { + setSettings((prev) => ({ ...prev, mode: "dark" })); + const body = document.body; + if (body.hasAttribute("theme-mode")) { + body.setAttribute("theme-mode", "dark"); + } + } else { + setSettings((prev) => ({ ...prev, mode: "light" })); + const body = document.body; + if (body.hasAttribute("theme-mode")) { + body.setAttribute("theme-mode", "light"); + } + } + }, [setSettings]); + + return children; +} + +function RestoreScroll() { const location = useLocation(); useEffect(() => { window.scroll(0, 0); }, [location.pathname]); - return children; -}; + return null; +} function App() { return ( - - + + + } /> + - + + } + /> + + + + } + /> + + + + } + /> + + + } /> - } /> - } /> - } /> } /> - - + + ); } diff --git a/src/components/Area.jsx b/src/components/Area.jsx index ac07e51..b53d09b 100644 --- a/src/components/Area.jsx +++ b/src/components/Area.jsx @@ -16,19 +16,19 @@ import { import { AreaContext, SelectContext, - SettingsContext, StateContext, TabContext, UndoRedoContext, } from "../pages/Editor"; import useLayout from "../hooks/useLayout"; +import useSettings from "../hooks/useSettings"; export default function Area(props) { const [hovered, setHovered] = useState(false); const [editField, setEditField] = useState({}); const { setState } = useContext(StateContext); - const {layout} = useLayout(); - const { settings } = useContext(SettingsContext); + const { layout } = useLayout(); + const { settings } = useSettings(); const { tab, setTab } = useContext(TabContext); const { updateArea, deleteArea } = useContext(AreaContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); diff --git a/src/components/Canvas.jsx b/src/components/Canvas.jsx index c598c52..45540d1 100644 --- a/src/components/Canvas.jsx +++ b/src/components/Canvas.jsx @@ -6,7 +6,6 @@ import Relationship from "./Relationship"; import { AreaContext, NoteContext, - SettingsContext, TableContext, UndoRedoContext, SelectContext, @@ -14,13 +13,14 @@ import { } from "../pages/Editor"; import Note from "./Note"; import { Toast } from "@douyinfe/semi-ui"; +import useSettings from "../hooks/useSettings"; export default function Canvas() { const { tables, updateTable, relationships, addRelationship } = useContext(TableContext); const { areas, updateArea } = useContext(AreaContext); const { notes, updateNote } = useContext(NoteContext); - const { settings } = useContext(SettingsContext); + const { settings } = useSettings(); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); const { transform, setTransform } = useContext(TransformContext); const { selectedElement, setSelectedElement } = useContext(SelectContext); diff --git a/src/components/ControlPanel.jsx b/src/components/ControlPanel.jsx index 37f0a16..f1232fb 100644 --- a/src/components/ControlPanel.jsx +++ b/src/components/ControlPanel.jsx @@ -53,7 +53,6 @@ import { NoteContext, TransformContext, SelectContext, - SettingsContext, StateContext, TabContext, TableContext, @@ -73,6 +72,7 @@ import { Parser } from "node-sql-parser"; import Todo from "./Todo"; import { Thumbnail } from "./Thumbnail"; import useLayout from "../hooks/useLayout"; +import useSettings from "../hooks/useSettings"; export default function ControlPanel({ diagramId, @@ -124,7 +124,7 @@ export default function ControlPanel({ const [data, setData] = useState(null); const { state, setState } = useContext(StateContext); const { layout, setLayout } = useLayout(); - const { settings, setSettings } = useContext(SettingsContext); + const { settings, setSettings } = useSettings(); const { relationships, tables, diff --git a/src/components/Issues.jsx b/src/components/Issues.jsx index 38f3a7f..aab30c4 100644 --- a/src/components/Issues.jsx +++ b/src/components/Issues.jsx @@ -1,10 +1,11 @@ import { useContext, useState, useEffect } from "react"; import { Collapse, Badge } from "@douyinfe/semi-ui"; -import { SettingsContext, TableContext, TypeContext } from "../pages/Editor"; +import { TableContext, TypeContext } from "../pages/Editor"; import { validateDiagram, arrayIsEqual } from "../utils"; +import useSettings from "../hooks/useSettings"; export default function Issues() { - const { settings } = useContext(SettingsContext); + const { settings } = useSettings(); const { types } = useContext(TypeContext); const { tables, relationships } = useContext(TableContext); const [issues, setIssues] = useState([]); diff --git a/src/components/Relationship.jsx b/src/components/Relationship.jsx index 71e2f06..38be3b4 100644 --- a/src/components/Relationship.jsx +++ b/src/components/Relationship.jsx @@ -1,11 +1,11 @@ -import { useContext, useRef, useState } from "react"; +import { useRef, useState } from "react"; import { calcPath } from "../utils"; import { Cardinality } from "../data/data"; -import { SettingsContext } from "../pages/Editor"; +import useSettings from "../hooks/useSettings"; export default function Relationship(props) { const [hovered, setHovered] = useState(false); - const { settings } = useContext(SettingsContext); + const { settings } = useSettings(); const pathRef = useRef(); let cardinalityStart = "1"; diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx index f8d5ad4..2316f1b 100644 --- a/src/components/Sidebar.jsx +++ b/src/components/Sidebar.jsx @@ -9,12 +9,12 @@ import { Tooltip, SideSheet, List, Badge } from "@douyinfe/semi-ui"; import { BotMessageContext, MessageContext, - SettingsContext, UndoRedoContext, } from "../pages/Editor"; import Todo from "./Todo"; import Chat from "./Chat"; import DrawBot from "./DrawBot"; +import useSettings from "../hooks/useSettings"; export default function Sidebar() { const SidesheetType = { @@ -27,7 +27,7 @@ export default function Sidebar() { }; const { undoStack } = useContext(UndoRedoContext); const { messages } = useContext(MessageContext); - const { settings } = useContext(SettingsContext); + const { settings } = useSettings(); const { botMessages } = useContext(BotMessageContext); const [sidesheet, setSidesheet] = useState(SidesheetType.NONE); const [seen, setSeen] = useState(0); diff --git a/src/components/Table.jsx b/src/components/Table.jsx index e58e73c..7a30aef 100644 --- a/src/components/Table.jsx +++ b/src/components/Table.jsx @@ -33,7 +33,6 @@ import { } from "@douyinfe/semi-ui"; import { SelectContext, - SettingsContext, TabContext, TableContext, TypeContext, @@ -41,6 +40,7 @@ import { } from "../pages/Editor"; import { getSize, hasCheck, hasPrecision, isSized } from "../utils"; import useLayout from "../hooks/useLayout"; +import useSettings from "../hooks/useSettings"; export default function Table(props) { const [isHovered, setIsHovered] = useState(false); @@ -50,7 +50,7 @@ export default function Table(props) { const { deleteTable, updateTable, updateField, setRelationships } = useContext(TableContext); const { tab, setTab } = useContext(TabContext); - const { settings } = useContext(SettingsContext); + const { settings } = useSettings(); const { types } = useContext(TypeContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); const { selectedElement, setSelectedElement } = useContext(SelectContext); diff --git a/src/context/SettingsContext.jsx b/src/context/SettingsContext.jsx new file mode 100644 index 0000000..bf90e24 --- /dev/null +++ b/src/context/SettingsContext.jsx @@ -0,0 +1,21 @@ +import { createContext, useState } from "react"; + +export const SettingsContext = createContext(null); + +export default function SettingsContextProvider({ children }) { + const [settings, setSettings] = useState({ + strictMode: false, + showFieldSummary: true, + showGrid: true, + mode: "light", + autosave: true, + panning: true, + showCardinality: true, + }); + + return ( + + {children} + + ); +} diff --git a/src/hooks/useLayout.js b/src/hooks/useLayout.js index c910d62..4de0b46 100644 --- a/src/hooks/useLayout.js +++ b/src/hooks/useLayout.js @@ -1,13 +1,6 @@ import { useContext } from "react"; import { LayoutContext } from "../context/LayoutContext"; -/** - * Access layout state - * - * Layout includes: header, sidebar, toolbar, issues, fullscreen - * - * @returns `{ layout, setLayout }` - */ export default function useLayout() { return useContext(LayoutContext); } diff --git a/src/hooks/useSettings.js b/src/hooks/useSettings.js new file mode 100644 index 0000000..858ec35 --- /dev/null +++ b/src/hooks/useSettings.js @@ -0,0 +1,6 @@ +import { useContext } from "react"; +import { SettingsContext } from "../context/SettingsContext"; + +export default function useSettings() { + return useContext(SettingsContext); +} diff --git a/src/pages/BugReport.jsx b/src/pages/BugReport.jsx index 7f35787..ac3250f 100644 --- a/src/pages/BugReport.jsx +++ b/src/pages/BugReport.jsx @@ -136,19 +136,7 @@ export default function BugReport() { const [theme, setTheme] = useState(""); useEffect(() => { - const t = localStorage.getItem("theme"); - setTheme(t); - if (t === "dark") { - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "dark"); - } - } else { - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "light"); - } - } + setTheme(localStorage.getItem("theme")); document.title = "Report a bug | drawDB"; document.body.setAttribute("class", "theme"); }, [setTheme]); diff --git a/src/pages/Editor.jsx b/src/pages/Editor.jsx index e6636b2..946292a 100644 --- a/src/pages/Editor.jsx +++ b/src/pages/Editor.jsx @@ -15,13 +15,13 @@ import { Divider, Tooltip } from "@douyinfe/semi-ui"; import { exitFullscreen } from "../utils"; import useLayout from "../hooks/useLayout"; import LayoutContextProvider from "../context/LayoutContext"; +import useSettings from "../hooks/useSettings"; export const StateContext = createContext(); export const TableContext = createContext(); export const AreaContext = createContext(); export const TabContext = createContext(); export const NoteContext = createContext(); -export const SettingsContext = createContext(); export const UndoRedoContext = createContext(); export const SelectContext = createContext(); export const TaskContext = createContext(); @@ -52,15 +52,7 @@ function WorkSpace() { const [width, setWidth] = useState(340); const [tab, setTab] = useState(Tab.tables); const { layout, setLayout } = useLayout(); - const [settings, setSettings] = useState({ - strictMode: false, - showFieldSummary: true, - showGrid: true, - mode: "light", - autosave: true, - panning: true, - showCardinality: true, - }); + const { settings, setSettings } = useSettings(); const [transform, setTransform] = useState({ zoom: 1, pan: { x: 0, y: 0 }, @@ -94,8 +86,8 @@ function WorkSpace() { { id: prev.length, name: `table_${prev.length}`, - x: -settings.pan.x, - y: -settings.pan.y, + x: -transform.pan.x, + y: -transform.pan.y, fields: [ { name: "id", @@ -211,8 +203,8 @@ function WorkSpace() { { id: prev.length, name: `area_${prev.length}`, - x: -settings.pan.x, - y: -settings.pan.y, + x: -transform.pan.x, + y: -transform.pan.y, width: 200, height: 200, color: defaultTableTheme, @@ -244,8 +236,8 @@ function WorkSpace() { ...prev, { id: prev.length, - x: -settings.pan.x, - y: -settings.pan.y, + x: -transform.pan.x, + y: -transform.pan.y, title: `note_${prev.length}`, content: "", color: defaultNoteTheme, @@ -690,22 +682,7 @@ function WorkSpace() { break; } } - - const theme = localStorage.getItem("theme"); - if (theme === "dark") { - setSettings((prev) => ({ ...prev, mode: "dark" })); - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "dark"); - } - } else { - setSettings((prev) => ({ ...prev, mode: "light" })); - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "light"); - } - } - }, []); + }, [setSettings]); return ( @@ -731,115 +708,107 @@ function WorkSpace() { value={{ notes, setNotes, updateNote, addNote, deleteNote }} > - - + - - - -
- -
setResize(false)} - onMouseMove={dragHandler} - > - {layout.sidebar && ( - - )} -
- - {!( - layout.sidebar || - layout.toolbar || - layout.header - ) && ( -
-
- - -
- {parseInt(transform.zoom * 100)}% -
- - +
+ +
setResize(false)} + onMouseMove={dragHandler} + > + {layout.sidebar && ( + + )} +
+ + {!( + layout.sidebar || + layout.toolbar || + layout.header + ) && ( +
+
+ + +
+ {parseInt(transform.zoom * 100)}%
- - - + +
- )} -
+ + + +
+ )}
- - - - - +
+ + + + diff --git a/src/pages/Shortcuts.jsx b/src/pages/Shortcuts.jsx index 26e2f49..6d59680 100644 --- a/src/pages/Shortcuts.jsx +++ b/src/pages/Shortcuts.jsx @@ -76,19 +76,7 @@ export default function Shortcuts() { }; useEffect(() => { - const t = localStorage.getItem("theme"); - setTheme(t); - if (t === "dark") { - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "dark"); - } - } else { - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "light"); - } - } + setTheme(localStorage.getItem("theme")); document.title = "Shortcuts | drawDB"; document.body.setAttribute("class", "theme"); }, [setTheme]); diff --git a/src/pages/Survey.jsx b/src/pages/Survey.jsx index c3239e1..65fe80c 100644 --- a/src/pages/Survey.jsx +++ b/src/pages/Survey.jsx @@ -239,19 +239,7 @@ export default function Survey() { useEffect(() => window.scroll(0, 0)); useEffect(() => { - const t = localStorage.getItem("theme"); - setTheme(t); - if (t === "dark") { - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "dark"); - } - } else { - const body = document.body; - if (body.hasAttribute("theme-mode")) { - body.setAttribute("theme-mode", "light"); - } - } + setTheme(localStorage.getItem("theme")); document.title = "Share you feedback | drawDB"; document.body.setAttribute("class", "theme"); }, [setTheme]);