From bc80975e6ba57f3ba6c21fa7e00d0effe03ceb48 Mon Sep 17 00:00:00 2001 From: Victor Oliva Date: Sat, 9 Nov 2024 13:51:47 +0700 Subject: [PATCH] add light theme support, underline links to block detail --- src/ThemeProvider.tsx | 44 +++++++++++++++++++++ src/codec-components/ViewCodec/CStruct.tsx | 2 +- src/components/JsonDisplay.tsx | 45 ++++++++++++---------- src/main.tsx | 13 ++++--- src/pages/Explorer/BlockPopover.tsx | 2 +- src/pages/Explorer/Detail/BlockDetail.tsx | 2 +- src/pages/Explorer/EventPopover.tsx | 2 +- src/pages/Explorer/events.state.ts | 2 +- 8 files changed, 82 insertions(+), 30 deletions(-) create mode 100644 src/ThemeProvider.tsx diff --git a/src/ThemeProvider.tsx b/src/ThemeProvider.tsx new file mode 100644 index 0000000..189cc1c --- /dev/null +++ b/src/ThemeProvider.tsx @@ -0,0 +1,44 @@ +import { state, useStateObservable } from "@react-rxjs/core" +import { + createContext, + FC, + PropsWithChildren, + useContext, + useLayoutEffect, +} from "react" +import { fromEvent, map } from "rxjs" + +const getCurrentMedia = (): "light" | "dark" => + window.matchMedia + ? window.matchMedia("(prefers-color-scheme: dark)") + ? "dark" + : "light" + : "dark" + +const defaultTheme = getCurrentMedia() + +const ThemeContext = createContext<"light" | "dark">(defaultTheme) + +export const useTheme = () => useContext(ThemeContext) + +const theme$ = state( + fromEvent( + window.matchMedia("(prefers-color-scheme: dark)"), + "change", + ).pipe(map((evt) => (evt.matches ? "dark" : "light"))), + defaultTheme, +) + +export const ThemeProvider: FC = ({ children }) => { + const theme = useStateObservable(theme$) + + useLayoutEffect(() => { + if (theme === "dark") { + document.body.classList.add("dark") + } else { + document.body.classList.remove("dark") + } + }, [theme]) + + return {children} +} diff --git a/src/codec-components/ViewCodec/CStruct.tsx b/src/codec-components/ViewCodec/CStruct.tsx index 293988b..d659fe6 100644 --- a/src/codec-components/ViewCodec/CStruct.tsx +++ b/src/codec-components/ViewCodec/CStruct.tsx @@ -110,7 +110,7 @@ export const CStruct: ViewStruct = ({
    {Object.entries(innerComponents).map(([name, jsx]) => ( diff --git a/src/components/JsonDisplay.tsx b/src/components/JsonDisplay.tsx index 2191c82..7a03183 100644 --- a/src/components/JsonDisplay.tsx +++ b/src/components/JsonDisplay.tsx @@ -5,26 +5,31 @@ import ReactJson from "react18-json-view" import "react18-json-view/src/dark.css" import "react18-json-view/src/style.css" import "./jsonDisplay.css" +import { useTheme } from "@/ThemeProvider" export const JsonDisplay: FC<{ src: unknown -}> = ({ src }) => ( - (v instanceof Binary ? bytesToString(v) : v)} - customizeCopy={(v) => - JSON.stringify( - v, - (_, v) => - typeof v === "bigint" - ? `${v}n` - : v instanceof Binary - ? bytesToString(v) - : v, - 2, - ) - } - /> -) +}> = ({ src }) => { + const theme = useTheme() + + return ( + (v instanceof Binary ? bytesToString(v) : v)} + customizeCopy={(v) => + JSON.stringify( + v, + (_, v) => + typeof v === "bigint" + ? `${v}n` + : v instanceof Binary + ? bytesToString(v) + : v, + 2, + ) + } + /> + ) +} diff --git a/src/main.tsx b/src/main.tsx index 92fbe7b..2a7b6cb 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -9,16 +9,19 @@ import { TooltipProvider } from "./components/Tooltip.tsx" import "./index.css" import { explorer$ } from "./pages/Explorer" import { transactions$ } from "./pages/Transactions" +import { ThemeProvider } from "./ThemeProvider.tsx" createRoot(document.getElementById("root")!).render( - - - - - + + + + + + + , diff --git a/src/pages/Explorer/BlockPopover.tsx b/src/pages/Explorer/BlockPopover.tsx index 2046e69..f65494b 100644 --- a/src/pages/Explorer/BlockPopover.tsx +++ b/src/pages/Explorer/BlockPopover.tsx @@ -57,7 +57,7 @@ export const BlockPopover: FC<{ hash: string }> = ({ hash }) => { Block {hash.slice(0, 18)}… diff --git a/src/pages/Explorer/Detail/BlockDetail.tsx b/src/pages/Explorer/Detail/BlockDetail.tsx index 3eb79cc..8e1a1e8 100644 --- a/src/pages/Explorer/Detail/BlockDetail.tsx +++ b/src/pages/Explorer/Detail/BlockDetail.tsx @@ -266,7 +266,7 @@ const BlockLink: FC<{ hash: string }> = ({ hash }) => { return ( {} diff --git a/src/pages/Explorer/EventPopover.tsx b/src/pages/Explorer/EventPopover.tsx index 8c15cdc..3d68267 100644 --- a/src/pages/Explorer/EventPopover.tsx +++ b/src/pages/Explorer/EventPopover.tsx @@ -13,7 +13,7 @@ export const EventPopover: FC<{ event: EventInfo }> = ({ event }) => { Event{" "} {eventKey(event)} diff --git a/src/pages/Explorer/events.state.ts b/src/pages/Explorer/events.state.ts index 8305722..e54d8f0 100644 --- a/src/pages/Explorer/events.state.ts +++ b/src/pages/Explorer/events.state.ts @@ -2,7 +2,7 @@ import { groupBy } from "@/lib/groupBy" import type { SystemEvent } from "@polkadot-api/observable-client" import { state } from "@react-rxjs/core" import { combineKeys } from "@react-rxjs/utils" -import { filter, map, takeWhile, tap } from "rxjs" +import { filter, map, takeWhile } from "rxjs" import { blockInfo$, BlockState, recordedBlocks$ } from "./block.state" import { MAX_LENGTH } from "./BlockTable"