From d717c19193b0d845bf17ee5fcd606fe009c20c49 Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 10:29:17 +0900 Subject: [PATCH 01/16] =?UTF-8?q?style:=20Link=20component=20=EC=BB=A8?= =?UTF-8?q?=EB=B2=A4=EC=85=98=20=EC=B6=94=EA=B0=80=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Router/Link.tsx | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Caecae/src/Shared/Router/Link.tsx b/Caecae/src/Shared/Router/Link.tsx index abfc1b9..5ed4c31 100644 --- a/Caecae/src/Shared/Router/Link.tsx +++ b/Caecae/src/Shared/Router/Link.tsx @@ -2,23 +2,23 @@ import React, { ReactNode, useContext, MouseEvent } from "react"; import { RouterContext } from "./Router"; interface LinkProps { - to: string; - children: ReactNode; + to: string; + children: ReactNode; } const Link: React.FC = ({ to, children }) => { - const { changePath } = useContext(RouterContext); + const { changePath } = useContext(RouterContext); - const handleClick = (event: MouseEvent) => { - event.preventDefault(); - changePath(to); - }; + const handleClick = (event: MouseEvent) => { + event.preventDefault(); + changePath(to); + }; - return ( - - {children} - - ); + return ( + + {children} + + ); }; export default Link; From ebcabc9fb68cdffd36ef7b479bc8f2b7b6b817f3 Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 10:38:06 +0900 Subject: [PATCH 02/16] =?UTF-8?q?feat:=20=EA=B0=95=EC=A0=9C=EB=A1=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=9E=9C=EB=8D=94=EB=A7=81=EB=90=98=EB=8A=94=20useFor?= =?UTF-8?q?ceRendering=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Hooks/useForceRendering.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 Caecae/src/Shared/Hooks/useForceRendering.tsx diff --git a/Caecae/src/Shared/Hooks/useForceRendering.tsx b/Caecae/src/Shared/Hooks/useForceRendering.tsx new file mode 100644 index 0000000..4434a16 --- /dev/null +++ b/Caecae/src/Shared/Hooks/useForceRendering.tsx @@ -0,0 +1,11 @@ +import { useState } from "react"; + +const useForceRendering = () => { + const [state, setState] = useState(false); + return () => { + state; + setState((prev) => !prev); + }; +}; + +export default useForceRendering; From 1c87822852efd767f34914483adac449076f892c Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 10:40:25 +0900 Subject: [PATCH 03/16] =?UTF-8?q?feat:=20Route=20props=EC=97=90=20isFullSc?= =?UTF-8?q?reen=20=EB=B3=80=EC=88=98=20=EC=B6=94=EA=B0=80=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Router/Route.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Caecae/src/Shared/Router/Route.tsx b/Caecae/src/Shared/Router/Route.tsx index 7c6edfb..45cbc99 100644 --- a/Caecae/src/Shared/Router/Route.tsx +++ b/Caecae/src/Shared/Router/Route.tsx @@ -1,7 +1,8 @@ -import React, { ReactElement } from "react"; +import { ReactElement } from "react"; interface RouteProps { path: string; + isFullScreen: boolean; element: ReactElement; } From e946be0fa293dc60ec192538a442520f504fce22 Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 10:42:51 +0900 Subject: [PATCH 04/16] =?UTF-8?q?feat:=20isFullScreen=EC=9D=B4=EB=9D=BC?= =?UTF-8?q?=EB=8A=94=20=EB=B3=80=EC=88=98=EB=A5=BC=20=ED=86=B5=ED=95=9C=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EB=B6=80=20=EB=9E=9C=EB=8D=94=EB=A7=81=20?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=20=EC=B6=94=EA=B0=80=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Router/Router.tsx | 43 +++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/Caecae/src/Shared/Router/Router.tsx b/Caecae/src/Shared/Router/Router.tsx index abfe26a..f26a5c8 100644 --- a/Caecae/src/Shared/Router/Router.tsx +++ b/Caecae/src/Shared/Router/Router.tsx @@ -1,4 +1,12 @@ -import { useState, createContext, ReactNode, FC, useEffect } from "react"; +import { + useState, + createContext, + ReactNode, + FC, + useEffect, + useRef, +} from "react"; +import useForceRendering from "../Hooks/useForceRendering"; interface RouterProps { children: ReactNode; @@ -6,20 +14,36 @@ interface RouterProps { interface RouterContextType { path: string; + fullScreenPath: string[]; changePath: (path: string) => void; + addFullScreenPath: (path: string) => void; + isFullScreen: boolean; } const RouterContext = createContext({ path: "", + fullScreenPath: [], changePath: () => undefined, + addFullScreenPath: () => undefined, + isFullScreen: false, }); RouterContext.displayName = "RouterContext"; const Router: FC = ({ children }) => { + const forceRerendering = useForceRendering(); const [path, setPath] = useState(window.location.pathname); - + const fullScreenPaths = useRef([]); + const isFullScreen = useRef(false); useEffect(() => { + if (fullScreenPaths.current.includes(window.location.pathname)) { + isFullScreen.current = true; + forceRerendering(); + } const handleLocationChange = () => { + isFullScreen.current = false; + if (fullScreenPaths.current.includes(window.location.pathname)) { + isFullScreen.current = true; + } setPath(window.location.pathname); }; @@ -33,15 +57,28 @@ const Router: FC = ({ children }) => { const changePath = (newPath: string) => { if (path !== newPath) { window.history.pushState({}, "", newPath); + isFullScreen.current = false; + if (fullScreenPaths.current.includes(newPath)) { + isFullScreen.current = true; + } setPath(newPath); } }; + const addFullScreenPath = (path: string) => { + const newPaths = fullScreenPaths.current; + if (newPaths.includes(path)) return; + newPaths.push(path); + fullScreenPaths.current = newPaths; + }; + const contextValue = { path: path, changePath: changePath, + fullScreenPath: fullScreenPaths.current, + addFullScreenPath: addFullScreenPath, + isFullScreen: isFullScreen.current, }; - return ( {children} From d3f5012754da771a94631f35ac4c9da9cf2f74b6 Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 10:44:20 +0900 Subject: [PATCH 05/16] =?UTF-8?q?feat:=20=EB=9E=9C=EB=8D=94=EB=A7=81?= =?UTF-8?q?=EB=90=A0=EB=95=8C=EB=8A=94=20=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EA=B3=A0=20=EC=9D=98=EC=A1=B4=EC=84=B1=EB=B0=B0=EC=97=B4?= =?UTF-8?q?=EC=9D=B4=20=EB=B3=80=EA=B2=BD=EB=90=A0=EC=8B=9C=EC=97=90?= =?UTF-8?q?=EB=A7=8C=20=EB=B0=98=EC=9D=91=ED=95=98=EB=8A=94=20useChangeDep?= =?UTF-8?q?endency=20=EA=B5=AC=ED=98=84=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Hooks/useChangeDependency.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Caecae/src/Shared/Hooks/useChangeDependency.tsx diff --git a/Caecae/src/Shared/Hooks/useChangeDependency.tsx b/Caecae/src/Shared/Hooks/useChangeDependency.tsx new file mode 100644 index 0000000..abfcbdc --- /dev/null +++ b/Caecae/src/Shared/Hooks/useChangeDependency.tsx @@ -0,0 +1,14 @@ +import { useEffect, useRef } from "react"; + +const useChangeDependency = (cb: () => void, dependency: unknown[]) => { + const initRef = useRef(false); + useEffect(() => { + if (!initRef.current) { + initRef.current = true; + } else { + cb(); + } + }, dependency); +}; + +export default useChangeDependency; From 6d266975285638f52d502291072dc6095ac3ca67 Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 10:44:57 +0900 Subject: [PATCH 06/16] =?UTF-8?q?feat:=20=EC=A1=B0=EA=B1=B4=EB=B6=80=20?= =?UTF-8?q?=EB=9E=9C=EB=8D=94=EB=A7=81=EC=9D=B4=20=EB=90=A0=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=20=EC=82=AC=EC=9A=A9=EB=90=A0=20useIsShowing?= =?UTF-8?q?=20hook=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Hooks/useIsShowing.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 Caecae/src/Shared/Hooks/useIsShowing.tsx diff --git a/Caecae/src/Shared/Hooks/useIsShowing.tsx b/Caecae/src/Shared/Hooks/useIsShowing.tsx new file mode 100644 index 0000000..da3bf03 --- /dev/null +++ b/Caecae/src/Shared/Hooks/useIsShowing.tsx @@ -0,0 +1,10 @@ +import { useContext } from "react"; +import { RouterContext } from "../Router/Router"; + +const useIsShowing = (): boolean => { + const { isFullScreen } = useContext(RouterContext); + console.log(isFullScreen); + return !isFullScreen; +}; + +export default useIsShowing; From c94a72e0ed118daa96158f122b0e063fbd65aaa2 Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 10:46:21 +0900 Subject: [PATCH 07/16] =?UTF-8?q?rename:=20Router=20->=20Hyunouter=20?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=EB=AA=85=20=EB=B3=80=EA=B2=BD=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Router/Link.tsx | 24 -------- Caecae/src/Shared/Router/Route.tsx | 13 ----- Caecae/src/Shared/Router/Router.tsx | 89 ----------------------------- Caecae/src/Shared/Router/Routes.tsx | 37 ------------ 4 files changed, 163 deletions(-) delete mode 100644 Caecae/src/Shared/Router/Link.tsx delete mode 100644 Caecae/src/Shared/Router/Route.tsx delete mode 100644 Caecae/src/Shared/Router/Router.tsx delete mode 100644 Caecae/src/Shared/Router/Routes.tsx diff --git a/Caecae/src/Shared/Router/Link.tsx b/Caecae/src/Shared/Router/Link.tsx deleted file mode 100644 index 5ed4c31..0000000 --- a/Caecae/src/Shared/Router/Link.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React, { ReactNode, useContext, MouseEvent } from "react"; -import { RouterContext } from "./Router"; - -interface LinkProps { - to: string; - children: ReactNode; -} - -const Link: React.FC = ({ to, children }) => { - const { changePath } = useContext(RouterContext); - - const handleClick = (event: MouseEvent) => { - event.preventDefault(); - changePath(to); - }; - - return ( - - {children} - - ); -}; - -export default Link; diff --git a/Caecae/src/Shared/Router/Route.tsx b/Caecae/src/Shared/Router/Route.tsx deleted file mode 100644 index 45cbc99..0000000 --- a/Caecae/src/Shared/Router/Route.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { ReactElement } from "react"; - -interface RouteProps { - path: string; - isFullScreen: boolean; - element: ReactElement; -} - -const Route: React.FC = () => { - return null; // 실제로 렌더링하지 않음 -}; - -export default Route; diff --git a/Caecae/src/Shared/Router/Router.tsx b/Caecae/src/Shared/Router/Router.tsx deleted file mode 100644 index f26a5c8..0000000 --- a/Caecae/src/Shared/Router/Router.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import { - useState, - createContext, - ReactNode, - FC, - useEffect, - useRef, -} from "react"; -import useForceRendering from "../Hooks/useForceRendering"; - -interface RouterProps { - children: ReactNode; -} - -interface RouterContextType { - path: string; - fullScreenPath: string[]; - changePath: (path: string) => void; - addFullScreenPath: (path: string) => void; - isFullScreen: boolean; -} - -const RouterContext = createContext({ - path: "", - fullScreenPath: [], - changePath: () => undefined, - addFullScreenPath: () => undefined, - isFullScreen: false, -}); -RouterContext.displayName = "RouterContext"; - -const Router: FC = ({ children }) => { - const forceRerendering = useForceRendering(); - const [path, setPath] = useState(window.location.pathname); - const fullScreenPaths = useRef([]); - const isFullScreen = useRef(false); - useEffect(() => { - if (fullScreenPaths.current.includes(window.location.pathname)) { - isFullScreen.current = true; - forceRerendering(); - } - const handleLocationChange = () => { - isFullScreen.current = false; - if (fullScreenPaths.current.includes(window.location.pathname)) { - isFullScreen.current = true; - } - setPath(window.location.pathname); - }; - - window.addEventListener("popstate", handleLocationChange); - - return () => { - window.removeEventListener("popstate", handleLocationChange); - }; - }, []); - - const changePath = (newPath: string) => { - if (path !== newPath) { - window.history.pushState({}, "", newPath); - isFullScreen.current = false; - if (fullScreenPaths.current.includes(newPath)) { - isFullScreen.current = true; - } - setPath(newPath); - } - }; - - const addFullScreenPath = (path: string) => { - const newPaths = fullScreenPaths.current; - if (newPaths.includes(path)) return; - newPaths.push(path); - fullScreenPaths.current = newPaths; - }; - - const contextValue = { - path: path, - changePath: changePath, - fullScreenPath: fullScreenPaths.current, - addFullScreenPath: addFullScreenPath, - isFullScreen: isFullScreen.current, - }; - return ( - - {children} - - ); -}; - -export { Router, RouterContext }; diff --git a/Caecae/src/Shared/Router/Routes.tsx b/Caecae/src/Shared/Router/Routes.tsx deleted file mode 100644 index 4252e00..0000000 --- a/Caecae/src/Shared/Router/Routes.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React, { - useContext, - ReactElement, - ReactNode, - isValidElement, -} from "react"; -import { RouterContext } from "./Router"; - -interface RoutesProps { - children: ReactNode; -} - -const Routes: React.FC = ({ children }) => { - const { path } = useContext(RouterContext); - - let element: ReactElement | null = null; - - React.Children.forEach(children, (child) => { - if (!isValidElement(child)) { - return; - } - if (child.type === React.Fragment) { - return; - } - if (!child.props.path || !child.props.element) { - return; - } - if (child.props.path !== path) { - return; - } - element = child.props.element; - }); - - return element; -}; - -export default Routes; From a8041e416580f9f5434cf9cf56d877a3550ac79b Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 10:47:01 +0900 Subject: [PATCH 08/16] =?UTF-8?q?feat:=20=EC=A1=B0=EA=B1=B4=EB=B6=80=20?= =?UTF-8?q?=EB=9E=9C=EB=8D=94=EB=A7=81=EB=90=98=EB=8A=94=20component?= =?UTF-8?q?=EC=97=90=20=EC=93=B0=EC=9D=BC=20useIsShowing=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Hooks/useIsShowing.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Caecae/src/Shared/Hooks/useIsShowing.tsx b/Caecae/src/Shared/Hooks/useIsShowing.tsx index da3bf03..7ba08e0 100644 --- a/Caecae/src/Shared/Hooks/useIsShowing.tsx +++ b/Caecae/src/Shared/Hooks/useIsShowing.tsx @@ -1,5 +1,5 @@ import { useContext } from "react"; -import { RouterContext } from "../Router/Router"; +import { RouterContext } from "../Hyunouter/Router"; const useIsShowing = (): boolean => { const { isFullScreen } = useContext(RouterContext); From 30750ff073818aabd87442d3b8ae17318ebed049 Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 10:49:01 +0900 Subject: [PATCH 09/16] =?UTF-8?q?feat:=20DoAction=20interface=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Hyundux/Actions.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Caecae/src/Shared/Hyundux/Actions.tsx b/Caecae/src/Shared/Hyundux/Actions.tsx index e4b078f..24c6905 100644 --- a/Caecae/src/Shared/Hyundux/Actions.tsx +++ b/Caecae/src/Shared/Hyundux/Actions.tsx @@ -1,7 +1,12 @@ +import State from "./State"; interface Action { - type: string; - actionName: string; - payload?: object; + type: string; + actionName: string; + payload?: object; +} +interface DoAction { + type: string; + doing: (state: State) => State; } -export default Action +export type { Action, DoAction }; From de19dc8f94aa4ad47cf3a5545e26dc93cf420502 Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 11:23:21 +0900 Subject: [PATCH 10/16] =?UTF-8?q?feat:=20DoAction=EC=97=90=20=EB=B0=98?= =?UTF-8?q?=EC=9D=91=EB=90=98=EB=8A=94=20store=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Hyundux/Store.tsx | 60 +++++++++++++++++++---------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/Caecae/src/Shared/Hyundux/Store.tsx b/Caecae/src/Shared/Hyundux/Store.tsx index 71a09ee..d5a9345 100644 --- a/Caecae/src/Shared/Hyundux/Store.tsx +++ b/Caecae/src/Shared/Hyundux/Store.tsx @@ -1,4 +1,4 @@ -import Action from "./Actions"; +import { Action, DoAction } from "./Actions"; import State from "./State"; import Reducer from "./Reducer"; import removeFirst from "./Util/RemoveFirst"; @@ -9,10 +9,10 @@ const store: { reducers: Reducer[]; subscribe: ( initState: State, - reducer: Reducer, + reducer: Reducer | null, cb: (state: State) => void ) => void; - dispatch: (action: Action) => void; + dispatch: (action: Action | DoAction) => void; publish: (state: State) => void; subscribeList: Map(state: State) => void>; } = { @@ -20,17 +20,27 @@ const store: { reducers: [], subscribeList: new Map(), dispatch: async function (action) { - const reducer = this.reducers.filter( - (reducer) => reducer.type == action.type - )[0].reducer; - const { removed, newArray } = removeFirst( - this.states, - (state) => state.type == action.type - ); - const newState = await reducer(removed, action); - // 여기서 모든것을 바로 state를 적용하는것이 아니라 이게 다른 state도 propagation하는지도 확인해야함 - this.states = [...newArray, newState]; - this.publish(newState); + if (isAction(action)) { + const reducer = this.reducers.filter( + (reducer) => reducer.type == action.type + )[0].reducer; + const { removed, newArray } = removeFirst( + this.states, + (state) => state.type == action.type + ); + const newState = await reducer(removed, action); + // 여기서 모든것을 바로 state를 적용하는것이 아니라 이게 다른 state도 propagation하는지도 확인해야함 + this.states = [...newArray, newState]; + this.publish(newState); + } else if (isDoAction(action)) { + const { removed, newArray } = removeFirst( + this.states, + (state) => state.type == action.type + ); + const newState = action.doing(removed); + this.states = [...newArray, newState]; + this.publish(newState); + } }, publish: function (state) { const publishedCallBack = this.subscribeList.get(state.type); @@ -40,7 +50,7 @@ const store: { }, subscribe: function ( state: State, - reducer: Reducer, + reducer: Reducer | null = null, cb: (state: State) => void ) { this.states = replaceFirst( @@ -48,13 +58,23 @@ const store: { state, (element) => element.type == state.type ); - this.reducers = replaceFirst( - this.reducers, - reducer as Reducer, - (element) => element.type == state.type - ); + if (reducer != null) { + this.reducers = replaceFirst( + this.reducers, + reducer as Reducer, + (element) => element.type == state.type + ); + } this.subscribeList.set(state.type, cb as (state: State) => void); }, }; +function isAction(action: unknown): action is Action { + return (action as Action).actionName !== undefined; +} + +function isDoAction(action: unknown): action is DoAction { + return (action as DoAction).doing !== undefined; +} + export default store; From b7c57d46621709d449f70d855f0d8523e4f74a32 Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 11:24:12 +0900 Subject: [PATCH 11/16] =?UTF-8?q?fix:=20reducer=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Hyundux/Reducer.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Caecae/src/Shared/Hyundux/Reducer.tsx b/Caecae/src/Shared/Hyundux/Reducer.tsx index 752419e..5571b70 100644 --- a/Caecae/src/Shared/Hyundux/Reducer.tsx +++ b/Caecae/src/Shared/Hyundux/Reducer.tsx @@ -1,9 +1,9 @@ -import Action from "./Actions"; +import { Action } from "./Actions"; import State from "./State"; interface Reducer { - type: string; - reducer: (state: State, action: Action) => Promise>; + type: string; + reducer: (state: State, action: Action) => Promise>; } export default Reducer; From 26352a5d19bb8a8e93f7d3845f17550cf5a3abfb Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 11:24:52 +0900 Subject: [PATCH 12/16] =?UTF-8?q?rename:=20Router=20->=20Hyunouter=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EB=B3=80=EA=B2=BD=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Hyunouter/Link.tsx | 24 +++++++ Caecae/src/Shared/Hyunouter/Route.tsx | 13 ++++ Caecae/src/Shared/Hyunouter/Router.tsx | 89 ++++++++++++++++++++++++++ Caecae/src/Shared/Hyunouter/Routes.tsx | 41 ++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 Caecae/src/Shared/Hyunouter/Link.tsx create mode 100644 Caecae/src/Shared/Hyunouter/Route.tsx create mode 100644 Caecae/src/Shared/Hyunouter/Router.tsx create mode 100644 Caecae/src/Shared/Hyunouter/Routes.tsx diff --git a/Caecae/src/Shared/Hyunouter/Link.tsx b/Caecae/src/Shared/Hyunouter/Link.tsx new file mode 100644 index 0000000..5ed4c31 --- /dev/null +++ b/Caecae/src/Shared/Hyunouter/Link.tsx @@ -0,0 +1,24 @@ +import React, { ReactNode, useContext, MouseEvent } from "react"; +import { RouterContext } from "./Router"; + +interface LinkProps { + to: string; + children: ReactNode; +} + +const Link: React.FC = ({ to, children }) => { + const { changePath } = useContext(RouterContext); + + const handleClick = (event: MouseEvent) => { + event.preventDefault(); + changePath(to); + }; + + return ( + + {children} + + ); +}; + +export default Link; diff --git a/Caecae/src/Shared/Hyunouter/Route.tsx b/Caecae/src/Shared/Hyunouter/Route.tsx new file mode 100644 index 0000000..45cbc99 --- /dev/null +++ b/Caecae/src/Shared/Hyunouter/Route.tsx @@ -0,0 +1,13 @@ +import { ReactElement } from "react"; + +interface RouteProps { + path: string; + isFullScreen: boolean; + element: ReactElement; +} + +const Route: React.FC = () => { + return null; // 실제로 렌더링하지 않음 +}; + +export default Route; diff --git a/Caecae/src/Shared/Hyunouter/Router.tsx b/Caecae/src/Shared/Hyunouter/Router.tsx new file mode 100644 index 0000000..f26a5c8 --- /dev/null +++ b/Caecae/src/Shared/Hyunouter/Router.tsx @@ -0,0 +1,89 @@ +import { + useState, + createContext, + ReactNode, + FC, + useEffect, + useRef, +} from "react"; +import useForceRendering from "../Hooks/useForceRendering"; + +interface RouterProps { + children: ReactNode; +} + +interface RouterContextType { + path: string; + fullScreenPath: string[]; + changePath: (path: string) => void; + addFullScreenPath: (path: string) => void; + isFullScreen: boolean; +} + +const RouterContext = createContext({ + path: "", + fullScreenPath: [], + changePath: () => undefined, + addFullScreenPath: () => undefined, + isFullScreen: false, +}); +RouterContext.displayName = "RouterContext"; + +const Router: FC = ({ children }) => { + const forceRerendering = useForceRendering(); + const [path, setPath] = useState(window.location.pathname); + const fullScreenPaths = useRef([]); + const isFullScreen = useRef(false); + useEffect(() => { + if (fullScreenPaths.current.includes(window.location.pathname)) { + isFullScreen.current = true; + forceRerendering(); + } + const handleLocationChange = () => { + isFullScreen.current = false; + if (fullScreenPaths.current.includes(window.location.pathname)) { + isFullScreen.current = true; + } + setPath(window.location.pathname); + }; + + window.addEventListener("popstate", handleLocationChange); + + return () => { + window.removeEventListener("popstate", handleLocationChange); + }; + }, []); + + const changePath = (newPath: string) => { + if (path !== newPath) { + window.history.pushState({}, "", newPath); + isFullScreen.current = false; + if (fullScreenPaths.current.includes(newPath)) { + isFullScreen.current = true; + } + setPath(newPath); + } + }; + + const addFullScreenPath = (path: string) => { + const newPaths = fullScreenPaths.current; + if (newPaths.includes(path)) return; + newPaths.push(path); + fullScreenPaths.current = newPaths; + }; + + const contextValue = { + path: path, + changePath: changePath, + fullScreenPath: fullScreenPaths.current, + addFullScreenPath: addFullScreenPath, + isFullScreen: isFullScreen.current, + }; + return ( + + {children} + + ); +}; + +export { Router, RouterContext }; diff --git a/Caecae/src/Shared/Hyunouter/Routes.tsx b/Caecae/src/Shared/Hyunouter/Routes.tsx new file mode 100644 index 0000000..afa1072 --- /dev/null +++ b/Caecae/src/Shared/Hyunouter/Routes.tsx @@ -0,0 +1,41 @@ +import React, { + useContext, + ReactElement, + ReactNode, + isValidElement, +} from "react"; +import { RouterContext } from "./Router"; + +interface RoutesProps { + children: ReactNode; +} + +const Routes: React.FC = ({ children }) => { + const { path, addFullScreenPath } = useContext(RouterContext); + + let element: ReactElement | null = null; + + React.Children.forEach(children, (child) => { + if (!isValidElement(child)) { + return; + } + if (child.props.isFullScreen) { + addFullScreenPath(child.props.path); + } + if (child.type === React.Fragment) { + return; + } + if (!child.props.path || !child.props.element) { + return; + } + if (child.props.path !== path) { + return; + } + + element = child.props.element; + }); + + return element; +}; + +export default Routes; From ced0326a33ccce6228989f60b3233087f0f98482 Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 11:26:01 +0900 Subject: [PATCH 13/16] =?UTF-8?q?rename:=20CountWorkFlow=20->=20CountWork?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=EB=B3=80=EA=B2=BD=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Example_Counter/{CountWorkFlow.tsx => CountWork.tsx} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Caecae/src/Shared/Hyundux/Example_Counter/{CountWorkFlow.tsx => CountWork.tsx} (97%) diff --git a/Caecae/src/Shared/Hyundux/Example_Counter/CountWorkFlow.tsx b/Caecae/src/Shared/Hyundux/Example_Counter/CountWork.tsx similarity index 97% rename from Caecae/src/Shared/Hyundux/Example_Counter/CountWorkFlow.tsx rename to Caecae/src/Shared/Hyundux/Example_Counter/CountWork.tsx index 7841348..350d131 100644 --- a/Caecae/src/Shared/Hyundux/Example_Counter/CountWorkFlow.tsx +++ b/Caecae/src/Shared/Hyundux/Example_Counter/CountWork.tsx @@ -1,7 +1,7 @@ import { createState } from "../State"; import { makePayLoad } from "../Util/StoreUtil"; import Reducer from "../Reducer"; -import Action from "../Actions"; +import { Action } from "../Actions"; const WORKFLOW_NAME = "Count"; From 76e3b4547a96f767496b166c475011355e874482 Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 11:26:43 +0900 Subject: [PATCH 14/16] =?UTF-8?q?fix:=20=EC=9D=B4=EB=A6=84=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Hyundux/Example_Counter/ConuntUI.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Caecae/src/Shared/Hyundux/Example_Counter/ConuntUI.tsx b/Caecae/src/Shared/Hyundux/Example_Counter/ConuntUI.tsx index d1ba6e8..16630c0 100644 --- a/Caecae/src/Shared/Hyundux/Example_Counter/ConuntUI.tsx +++ b/Caecae/src/Shared/Hyundux/Example_Counter/ConuntUI.tsx @@ -1,5 +1,5 @@ import useWork from "../Hooks/useWork.tsx"; -import { action, initCountState, countReducer } from "./CountWorkFlow.tsx"; +import { action, initCountState, countReducer } from "./CountWork.tsx"; import store from "../Store.tsx"; const Counter = () => { From d3525a909702fcfbfd62222d1b37c6cce82b507c Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 11:27:16 +0900 Subject: [PATCH 15/16] =?UTF-8?q?feat:=20Do=EB=A5=BC=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=98=88=EC=A0=9C=EC=9D=B8=20CoutDo=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Hyundux/Example_Counter/CountDo.tsx | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Caecae/src/Shared/Hyundux/Example_Counter/CountDo.tsx diff --git a/Caecae/src/Shared/Hyundux/Example_Counter/CountDo.tsx b/Caecae/src/Shared/Hyundux/Example_Counter/CountDo.tsx new file mode 100644 index 0000000..d2debba --- /dev/null +++ b/Caecae/src/Shared/Hyundux/Example_Counter/CountDo.tsx @@ -0,0 +1,31 @@ +import { createState } from "../State"; +import { DoAction } from "../Actions"; +import State from "../State"; +import { makePayLoad } from "../Util/StoreUtil"; + +const Do_NAME = "Count"; + +// state type +interface CountPayLoad { + count: number; + text: string; +} + +const initCountState = createState(Do_NAME, { + count: 0, + text: "helloWorld", +}); + +// actions +const doAction = { + countUp: (): DoAction => { + return { + type: Do_NAME, + doing: (state: State): State => { + return makePayLoad(state, { count: state.payload.count + 1 }); + }, + }; + }, +}; + +export { doAction, initCountState }; From e84b65f8e69b57d8a539acf411b933d567949a8a Mon Sep 17 00:00:00 2001 From: pccommen Date: Fri, 26 Jul 2024 11:27:39 +0900 Subject: [PATCH 16/16] =?UTF-8?q?feat:=20Do=EB=A5=BC=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=ED=95=98=EB=8A=94=20hook?= =?UTF-8?q?=EC=9D=B8=20useDo=20=EA=B5=AC=ED=98=84=20(CC-88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Caecae/src/Shared/Hyundux/Hooks/useDo.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Caecae/src/Shared/Hyundux/Hooks/useDo.tsx diff --git a/Caecae/src/Shared/Hyundux/Hooks/useDo.tsx b/Caecae/src/Shared/Hyundux/Hooks/useDo.tsx new file mode 100644 index 0000000..58d0453 --- /dev/null +++ b/Caecae/src/Shared/Hyundux/Hooks/useDo.tsx @@ -0,0 +1,13 @@ +import { useState } from "react"; +import _State from "../State"; +import store from "../Store"; + +function useDo(initialState: _State): PayLoad { + const [state, setState] = useState<_State>(initialState); + store.subscribe(state, null, (newState) => { + setState(newState); + }); + return state.payload; +} + +export default useDo;