From 2b1079525b86dad45df11e6ad29a89989a6416ab Mon Sep 17 00:00:00 2001
From: Shin'ya Ueoka <ueokande@i-beam.org>
Date: Sun, 4 Apr 2021 16:44:47 +0900
Subject: Separate Message to InfoMessage and ErrorMessage

---
 src/console/components/InfoMessage.tsx | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 src/console/components/InfoMessage.tsx

(limited to 'src/console/components/InfoMessage.tsx')

diff --git a/src/console/components/InfoMessage.tsx b/src/console/components/InfoMessage.tsx
new file mode 100644
index 0000000..02ad27d
--- /dev/null
+++ b/src/console/components/InfoMessage.tsx
@@ -0,0 +1,15 @@
+import React from "react";
+import { styled } from "./ColorSchemeProvider";
+
+const Wrapper = styled.p`
+  border-top: 1px solid gray;
+  background-color: ${({ theme }) => theme.consoleInfoBackground};
+  color: ${({ theme }) => theme.consoleInfoForeground};
+  font-weight: normal;
+`;
+
+const InfoMessage: React.FC = ({ children }) => {
+  return <Wrapper role="status">{children}</Wrapper>;
+};
+
+export default InfoMessage;
-- 
cgit v1.2.3


From 21f863d76fbb5ed752ad529f8fbe33e75460027e Mon Sep 17 00:00:00 2001
From: Shin'ya Ueoka <ueokande@i-beam.org>
Date: Mon, 5 Apr 2021 23:05:23 +0900
Subject: Replace colorscheme state with React Hooks

---
 src/console/actions/console.ts                     | 22 +------
 src/console/colorscheme/contexts.tsx               | 10 +++
 src/console/colorscheme/hooks.ts                   | 15 +++++
 src/console/colorscheme/providers.tsx              | 31 +++++++++
 src/console/colorscheme/styled.tsx                 |  6 ++
 src/console/colorscheme/theme.ts                   | 47 +++++++++++++
 src/console/components/ColorSchemeProvider.tsx     | 76 ----------------------
 src/console/components/Console.tsx                 | 40 +++++-------
 src/console/components/ErrorMessage.tsx            |  2 +-
 src/console/components/InfoMessage.tsx             |  2 +-
 src/console/components/console/CompletionItem.tsx  |  2 +-
 src/console/components/console/CompletionTitle.tsx |  2 +-
 src/console/components/console/Input.tsx           |  2 +-
 src/console/index.tsx                              |  5 +-
 src/console/reducers/console.ts                    |  9 ---
 15 files changed, 135 insertions(+), 136 deletions(-)
 create mode 100644 src/console/colorscheme/contexts.tsx
 create mode 100644 src/console/colorscheme/hooks.ts
 create mode 100644 src/console/colorscheme/providers.tsx
 create mode 100644 src/console/colorscheme/styled.tsx
 create mode 100644 src/console/colorscheme/theme.ts
 delete mode 100644 src/console/components/ColorSchemeProvider.tsx

(limited to 'src/console/components/InfoMessage.tsx')

diff --git a/src/console/actions/console.ts b/src/console/actions/console.ts
index 646cc31..bce2c67 100644
--- a/src/console/actions/console.ts
+++ b/src/console/actions/console.ts
@@ -1,8 +1,4 @@
 import * as messages from "../../shared/messages";
-import SettingClient from "../clients/SettingClient";
-import ColorScheme from "../../shared/ColorScheme";
-
-const settingClient = new SettingClient();
 
 export const CONSOLE_SHOW_COMMAND = "console.show.command";
 export const CONSOLE_SHOW_ERROR = "console.show.error";
@@ -10,7 +6,6 @@ export const CONSOLE_SHOW_INFO = "console.show.info";
 export const CONSOLE_HIDE_COMMAND = "console.hide.command";
 export const CONSOLE_SET_CONSOLE_TEXT = "console.set.command";
 export const CONSOLE_SHOW_FIND = "console.show.find";
-export const CONSOLE_SET_COLORSCHEME = "completion.set.colorscheme";
 export const CONSOLE_HIDE = "console.hide";
 
 export interface HideAction {
@@ -45,11 +40,6 @@ export interface SetConsoleTextAction {
   consoleText: string;
 }
 
-export interface SetColorSchemeAction {
-  type: typeof CONSOLE_SET_COLORSCHEME;
-  colorscheme: ColorScheme;
-}
-
 export type ConsoleAction =
   | HideAction
   | ShowCommand
@@ -57,8 +47,7 @@ export type ConsoleAction =
   | ShowErrorAction
   | ShowInfoAction
   | HideCommandAction
-  | SetConsoleTextAction
-  | SetColorSchemeAction;
+  | SetConsoleTextAction;
 
 const hide = (): ConsoleAction => {
   return {
@@ -131,14 +120,6 @@ const setConsoleText = (consoleText: string): SetConsoleTextAction => {
   };
 };
 
-const setColorScheme = async (): Promise<SetColorSchemeAction> => {
-  const scheme = await settingClient.getColorScheme();
-  return {
-    type: CONSOLE_SET_COLORSCHEME,
-    colorscheme: scheme,
-  };
-};
-
 export {
   hide,
   showCommand,
@@ -149,5 +130,4 @@ export {
   setConsoleText,
   enterCommand,
   enterFind,
-  setColorScheme,
 };
diff --git a/src/console/colorscheme/contexts.tsx b/src/console/colorscheme/contexts.tsx
new file mode 100644
index 0000000..e94454b
--- /dev/null
+++ b/src/console/colorscheme/contexts.tsx
@@ -0,0 +1,10 @@
+import React from "react";
+import ColorScheme from "../../shared/ColorScheme";
+
+export const ColorSchemeContext = React.createContext<ColorScheme>(
+  ColorScheme.System
+);
+
+export const ColorSchemeUpdateContext = React.createContext<
+  (colorscheme: ColorScheme) => void
+>(() => {});
diff --git a/src/console/colorscheme/hooks.ts b/src/console/colorscheme/hooks.ts
new file mode 100644
index 0000000..c9de754
--- /dev/null
+++ b/src/console/colorscheme/hooks.ts
@@ -0,0 +1,15 @@
+import React from "react";
+import { ColorSchemeUpdateContext } from "./contexts";
+import SettingClient from "../clients/SettingClient";
+
+export const useColorSchemeRefresh = () => {
+  const update = React.useContext(ColorSchemeUpdateContext);
+  const settingClient = new SettingClient();
+  const refresh = React.useCallback(() => {
+    settingClient.getColorScheme().then((newScheme) => {
+      update(newScheme);
+    });
+  }, []);
+
+  return refresh;
+};
diff --git a/src/console/colorscheme/providers.tsx b/src/console/colorscheme/providers.tsx
new file mode 100644
index 0000000..810c8e0
--- /dev/null
+++ b/src/console/colorscheme/providers.tsx
@@ -0,0 +1,31 @@
+import React from "react";
+import ColorScheme from "../../shared/ColorScheme";
+import { DarkTheme, LightTheme } from "./theme";
+import { ColorSchemeContext, ColorSchemeUpdateContext } from "./contexts";
+import { ThemeProvider } from "styled-components";
+
+export const ColorSchemeProvider: React.FC = ({ children }) => {
+  const [colorscheme, setColorScheme] = React.useState(ColorScheme.System);
+  const theme = React.useMemo(() => {
+    if (colorscheme === ColorScheme.System) {
+      if (
+        window.matchMedia &&
+        window.matchMedia("(prefers-color-scheme: dark)").matches
+      ) {
+        return DarkTheme;
+      }
+    } else if (colorscheme === ColorScheme.Dark) {
+      return DarkTheme;
+    }
+    return LightTheme;
+  }, [colorscheme]);
+
+  return (
+    <ColorSchemeContext.Provider value={colorscheme}>
+      <ColorSchemeUpdateContext.Provider value={setColorScheme}>
+        <ThemeProvider theme={theme}>{children}</ThemeProvider>
+      </ColorSchemeUpdateContext.Provider>
+    </ColorSchemeContext.Provider>
+  );
+};
+export default ColorSchemeProvider;
diff --git a/src/console/colorscheme/styled.tsx b/src/console/colorscheme/styled.tsx
new file mode 100644
index 0000000..12e10ec
--- /dev/null
+++ b/src/console/colorscheme/styled.tsx
@@ -0,0 +1,6 @@
+import baseStyled, { ThemedStyledInterface } from "styled-components";
+import { ThemeProperties } from "./theme";
+
+const styled = baseStyled as ThemedStyledInterface<ThemeProperties>;
+
+export default styled;
diff --git a/src/console/colorscheme/theme.ts b/src/console/colorscheme/theme.ts
new file mode 100644
index 0000000..5c17190
--- /dev/null
+++ b/src/console/colorscheme/theme.ts
@@ -0,0 +1,47 @@
+export type ThemeProperties = {
+  completionTitleBackground: string;
+  completionTitleForeground: string;
+  completionItemBackground: string;
+  completionItemForeground: string;
+  completionItemDescriptionForeground: string;
+  completionSelectedBackground: string;
+  completionSelectedForeground: string;
+  commandBackground: string;
+  commandForeground: string;
+  consoleErrorBackground: string;
+  consoleErrorForeground: string;
+  consoleInfoBackground: string;
+  consoleInfoForeground: string;
+};
+
+export const LightTheme: ThemeProperties = {
+  completionTitleBackground: "lightgray",
+  completionTitleForeground: "#000000",
+  completionItemBackground: "#ffffff",
+  completionItemForeground: "#000000",
+  completionItemDescriptionForeground: "#008000",
+  completionSelectedBackground: "#ffff00",
+  completionSelectedForeground: "#000000",
+  commandBackground: "#ffffff",
+  commandForeground: "#000000",
+  consoleErrorBackground: "#ff0000",
+  consoleErrorForeground: "#ffffff",
+  consoleInfoBackground: "#ffffff",
+  consoleInfoForeground: "#018786",
+};
+
+export const DarkTheme: ThemeProperties = {
+  completionTitleBackground: "#052027",
+  completionTitleForeground: "white",
+  completionItemBackground: "#2f474f",
+  completionItemForeground: "white",
+  completionItemDescriptionForeground: "#86fab0",
+  completionSelectedBackground: "#eeff41",
+  completionSelectedForeground: "#000000",
+  commandBackground: "#052027",
+  commandForeground: "white",
+  consoleErrorBackground: "red",
+  consoleErrorForeground: "white",
+  consoleInfoBackground: "#052027",
+  consoleInfoForeground: "#ffffff",
+};
diff --git a/src/console/components/ColorSchemeProvider.tsx b/src/console/components/ColorSchemeProvider.tsx
deleted file mode 100644
index bd63571..0000000
--- a/src/console/components/ColorSchemeProvider.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import React from "react";
-import ColorScheme from "../../shared/ColorScheme";
-import { ThemeProvider } from "styled-components";
-import baseStyled, { ThemedStyledInterface } from "styled-components";
-
-type ThemeProperties = {
-  completionTitleBackground: string;
-  completionTitleForeground: string;
-  completionItemBackground: string;
-  completionItemForeground: string;
-  completionItemDescriptionForeground: string;
-  completionSelectedBackground: string;
-  completionSelectedForeground: string;
-  commandBackground: string;
-  commandForeground: string;
-  consoleErrorBackground: string;
-  consoleErrorForeground: string;
-  consoleInfoBackground: string;
-  consoleInfoForeground: string;
-};
-
-export const LightTheme: ThemeProperties = {
-  completionTitleBackground: "lightgray",
-  completionTitleForeground: "#000000",
-  completionItemBackground: "#ffffff",
-  completionItemForeground: "#000000",
-  completionItemDescriptionForeground: "#008000",
-  completionSelectedBackground: "#ffff00",
-  completionSelectedForeground: "#000000",
-  commandBackground: "#ffffff",
-  commandForeground: "#000000",
-  consoleErrorBackground: "#ff0000",
-  consoleErrorForeground: "#ffffff",
-  consoleInfoBackground: "#ffffff",
-  consoleInfoForeground: "#018786",
-};
-
-export const DarkTheme: ThemeProperties = {
-  completionTitleBackground: "#052027",
-  completionTitleForeground: "white",
-  completionItemBackground: "#2f474f",
-  completionItemForeground: "white",
-  completionItemDescriptionForeground: "#86fab0",
-  completionSelectedBackground: "#eeff41",
-  completionSelectedForeground: "#000000",
-  commandBackground: "#052027",
-  commandForeground: "white",
-  consoleErrorBackground: "red",
-  consoleErrorForeground: "white",
-  consoleInfoBackground: "#052027",
-  consoleInfoForeground: "#ffffff",
-};
-
-interface Props extends React.HTMLAttributes<HTMLElement> {
-  colorscheme: ColorScheme;
-}
-
-const ColorSchemeProvider: React.FC<Props> = ({ colorscheme, children }) => {
-  let theme = LightTheme;
-  if (colorscheme === ColorScheme.System) {
-    if (
-      window.matchMedia &&
-      window.matchMedia("(prefers-color-scheme: dark)").matches
-    ) {
-      theme = DarkTheme;
-    }
-  } else if (colorscheme === ColorScheme.Dark) {
-    theme = DarkTheme;
-  }
-
-  return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
-};
-
-export const styled = baseStyled as ThemedStyledInterface<ThemeProperties>;
-
-export default ColorSchemeProvider;
diff --git a/src/console/components/Console.tsx b/src/console/components/Console.tsx
index b97ed62..f6f4234 100644
--- a/src/console/components/Console.tsx
+++ b/src/console/components/Console.tsx
@@ -3,37 +3,29 @@ import FindPrompt from "./FindPrompt";
 import CommandPrompt from "./CommandPrompt";
 import InfoMessage from "./InfoMessage";
 import ErrorMessage from "./ErrorMessage";
-import * as consoleActions from "../../console/actions/console";
-import ColorSchemeProvider from "./ColorSchemeProvider";
 import AppContext from "./AppContext";
+import { useColorSchemeRefresh } from "../colorscheme/hooks";
 
 const Console: React.FC = () => {
-  const { state, dispatch } = React.useContext(AppContext);
+  const { state } = React.useContext(AppContext);
+  const refreshColorScheme = useColorSchemeRefresh();
 
   React.useEffect(() => {
-    dispatch(consoleActions.setColorScheme());
+    refreshColorScheme();
   }, []);
 
-  const ele = (() => {
-    switch (state.mode) {
-      case "command":
-        return <CommandPrompt />;
-      case "find":
-        return <FindPrompt />;
-      case "info":
-        return <InfoMessage>{state.messageText}</InfoMessage>;
-      case "error":
-        return <ErrorMessage>{state.messageText}</ErrorMessage>;
-      default:
-        return null;
-    }
-  })();
-
-  return (
-    <ColorSchemeProvider colorscheme={state.colorscheme}>
-      {ele}
-    </ColorSchemeProvider>
-  );
+  switch (state.mode) {
+    case "command":
+      return <CommandPrompt />;
+    case "find":
+      return <FindPrompt />;
+    case "info":
+      return <InfoMessage>{state.messageText}</InfoMessage>;
+    case "error":
+      return <ErrorMessage>{state.messageText}</ErrorMessage>;
+    default:
+      return null;
+  }
 };
 
 export default Console;
diff --git a/src/console/components/ErrorMessage.tsx b/src/console/components/ErrorMessage.tsx
index 93b049b..f8d5ae7 100644
--- a/src/console/components/ErrorMessage.tsx
+++ b/src/console/components/ErrorMessage.tsx
@@ -1,5 +1,5 @@
 import React from "react";
-import { styled } from "./ColorSchemeProvider";
+import styled from "../colorscheme/styled";
 
 const Wrapper = styled.p`
   border-top: 1px solid gray;
diff --git a/src/console/components/InfoMessage.tsx b/src/console/components/InfoMessage.tsx
index 02ad27d..ccd9bcf 100644
--- a/src/console/components/InfoMessage.tsx
+++ b/src/console/components/InfoMessage.tsx
@@ -1,5 +1,5 @@
 import React from "react";
-import { styled } from "./ColorSchemeProvider";
+import styled from "../colorscheme/styled";
 
 const Wrapper = styled.p`
   border-top: 1px solid gray;
diff --git a/src/console/components/console/CompletionItem.tsx b/src/console/components/console/CompletionItem.tsx
index 7313491..2de1375 100644
--- a/src/console/components/console/CompletionItem.tsx
+++ b/src/console/components/console/CompletionItem.tsx
@@ -1,5 +1,5 @@
 import React from "react";
-import { styled } from "../ColorSchemeProvider";
+import styled from "../../colorscheme/styled";
 
 const Container = styled.li<{
   shown: boolean;
diff --git a/src/console/components/console/CompletionTitle.tsx b/src/console/components/console/CompletionTitle.tsx
index a8e8a54..4018b3f 100644
--- a/src/console/components/console/CompletionTitle.tsx
+++ b/src/console/components/console/CompletionTitle.tsx
@@ -1,5 +1,5 @@
 import React from "react";
-import { styled } from "../ColorSchemeProvider";
+import styled from "../../colorscheme/styled";
 
 const Li = styled.li<{ shown: boolean }>`
   display: ${({ shown }) => (shown ? "display" : "none")};
diff --git a/src/console/components/console/Input.tsx b/src/console/components/console/Input.tsx
index 7850f43..442bd30 100644
--- a/src/console/components/console/Input.tsx
+++ b/src/console/components/console/Input.tsx
@@ -1,5 +1,5 @@
 import React from "react";
-import { styled } from "../ColorSchemeProvider";
+import styled from "../../colorscheme/styled";
 
 const Container = styled.div`
   background-color: ${({ theme }) => theme.commandBackground};
diff --git a/src/console/index.tsx b/src/console/index.tsx
index 4a5368b..71f2a27 100644
--- a/src/console/index.tsx
+++ b/src/console/index.tsx
@@ -6,6 +6,7 @@ import AppContext from "./components/AppContext";
 import "./index.css";
 import React from "react";
 import ReactDOM from "react-dom";
+import ColorSchemeProvider from "./colorscheme/providers";
 
 const wrapAsync = <T extends unknown>(
   dispatch: React.Dispatch<T>
@@ -48,7 +49,9 @@ const RootComponent: React.FC = () => {
 
   return (
     <AppContext.Provider value={{ state, dispatch: wrapAsync(dispatch) }}>
-      <Console />
+      <ColorSchemeProvider>
+        <Console />
+      </ColorSchemeProvider>
     </AppContext.Provider>
   );
 };
diff --git a/src/console/reducers/console.ts b/src/console/reducers/console.ts
index 3acd0e9..37f1efc 100644
--- a/src/console/reducers/console.ts
+++ b/src/console/reducers/console.ts
@@ -1,8 +1,6 @@
-import ColorScheme from "../../shared/ColorScheme";
 import {
   CONSOLE_HIDE,
   CONSOLE_HIDE_COMMAND,
-  CONSOLE_SET_COLORSCHEME,
   CONSOLE_SET_CONSOLE_TEXT,
   CONSOLE_SHOW_COMMAND,
   CONSOLE_SHOW_ERROR,
@@ -15,14 +13,12 @@ export interface State {
   mode: string;
   messageText: string;
   consoleText: string;
-  colorscheme: ColorScheme;
 }
 
 export const defaultState = {
   mode: "",
   messageText: "",
   consoleText: "",
-  colorscheme: ColorScheme.System,
 };
 
 // eslint-disable-next-line max-lines-per-function
@@ -53,11 +49,6 @@ export default function reducer(
       };
     case CONSOLE_SET_CONSOLE_TEXT:
       return { ...state, consoleText: action.consoleText };
-    case CONSOLE_SET_COLORSCHEME:
-      return {
-        ...state,
-        colorscheme: action.colorscheme,
-      };
     default:
       return state;
   }
-- 
cgit v1.2.3

