Skip to content

Commit

Permalink
fix(app): dark mode page flash in app router (#598)
Browse files Browse the repository at this point in the history
  • Loading branch information
yudhomax authored Nov 1, 2024
1 parent 6e25ac1 commit c79b108
Show file tree
Hide file tree
Showing 18 changed files with 114 additions and 53 deletions.
4 changes: 2 additions & 2 deletions apps/app/src/components/app/Address/Contract/VerifiedData.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useState, useEffect, useRef } from 'react';
import { useTheme } from 'next-themes';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import { oneLight } from 'react-syntax-highlighter/dist/cjs/styles/prism';
Expand All @@ -13,6 +12,7 @@ import { VerifierData } from '@/utils/types';
import ErrorMessage from '@/components/common/ErrorMessage';
import FaInbox from '@/components/Icons/FaInbox';
import { verifierConfig } from '@/utils/app/config';
import { useThemeStore } from '@/stores/theme';

type VerifiedDataProps = {
verifierData: VerifierData;
Expand Down Expand Up @@ -49,7 +49,7 @@ const VerifiedData: React.FC<VerifiedDataProps> = ({
{},
);

const { theme } = useTheme();
const theme = useThemeStore((store) => store.theme);

useEffect(() => {
const fetchCode = async () => {
Expand Down
4 changes: 2 additions & 2 deletions apps/app/src/components/app/Advertise/ThemeImage.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use client';
import { useTheme } from 'next-themes';
import { useThemeStore } from '@/stores/theme';
import Image from 'next/legacy/image';

export default function ThemeImage() {
const { theme } = useTheme();
const theme = useThemeStore((store) => store.theme);

return (
<Image
Expand Down
4 changes: 2 additions & 2 deletions apps/app/src/components/app/Apis/ApiActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { dollarFormat, dollarNonCentFormat } from '@/utils/libs';
import Link from 'next/link';
import { useState } from 'react';
import Skeleton from '../skeleton/common/Skeleton';
import { useTheme } from 'next-themes';
import { toast } from 'react-toastify';
import LoadingCircular from '@/components/common/LoadingCircular';
import { useThemeStore } from '@/stores/theme';

const ApiActions = ({
status,
Expand All @@ -22,7 +22,7 @@ const ApiActions = ({
planDetails: any;
getContactDetails: any;
}) => {
const { theme } = useTheme();
const theme = useThemeStore((store) => store.theme);
const [interval, setInterval] = useState(true);

const [subject, _setSubject] = useState('API');
Expand Down
4 changes: 2 additions & 2 deletions apps/app/src/components/app/Charts/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import SwitchButton from '../SwitchButton';
import { yoctoToNear } from '@/utils/libs';
import { ChartConfig, ChartStat, ChartTypeInfo } from '@/utils/types';
import { Tooltip } from '@reach/tooltip';
import { useTheme } from 'next-themes';
import Skeleton from '../skeleton/common/Skeleton';
import Image from 'next/legacy/image';
import { useTranslations } from 'next-intl';
import { Link } from '@/i18n/routing';
import { useConfig } from '@/hooks/app/useConfig';
import { useThemeStore } from '@/stores/theme';

interface Props {
chartTypes?: string;
Expand All @@ -24,7 +24,7 @@ interface Props {
const Chart = (props: Props) => {
const { chartTypes, poweredBy, chartsData } = props;
const t = useTranslations();
const { theme } = useTheme();
const theme = useThemeStore((store) => store.theme);
const [chartConfig, setChartConfig] = useState<ChartConfig | null>(null);
const [chartInfo, setChartInfo] = useState<ChartTypeInfo>({
title: '',
Expand Down
4 changes: 2 additions & 2 deletions apps/app/src/components/app/Charts/TpsChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import SwitchButton from '../SwitchButton';
import Question from '../Icons/Question';
import { chartDataInfo } from '@/utils/types';
import { Tooltip } from '@reach/tooltip';
import { useTheme } from 'next-themes';
import Image from 'next/image';
import Skeleton from '../skeleton/common/Skeleton';
import { useTranslations } from 'next-intl';
import { Link } from '@/i18n/routing';
import { useConfig } from '@/hooks/app/useConfig';
import { useThemeStore } from '@/stores/theme';

interface Props {
chartTypes: string;
Expand All @@ -21,7 +21,7 @@ interface Props {
}
const TpsChart = (props: Props) => {
const { chartTypes, poweredBy, data } = props;
const { theme } = useTheme();
const theme = useThemeStore((store) => store.theme);
const t = useTranslations();
const { networkId } = useConfig();

Expand Down
4 changes: 2 additions & 2 deletions apps/app/src/components/app/Contact/FormContact.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { Turnstile } from '@marsidev/react-turnstile';
import type { TurnstileInstance } from '@marsidev/react-turnstile';
import { useTheme } from 'next-themes';
import { useTranslations } from 'next-intl';
import LoadingCircular from '@/components/common/LoadingCircular';
import { useThemeStore } from '@/stores/theme';

interface Props {
selectValue?: string;
Expand All @@ -16,7 +16,7 @@ interface Props {
const siteKey = process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY;

const FormContact = ({ selectValue, getContactDetails }: Props) => {
const { theme } = useTheme();
const theme = useThemeStore((store) => store.theme);
const t = useTranslations('contact');

const [loading, setLoading] = useState(false);
Expand Down
4 changes: 2 additions & 2 deletions apps/app/src/components/app/Layouts/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
'use client';
import Image from 'next/legacy/image';
import Arrow from '../Icons/Arrow';
import { useTheme } from 'next-themes';
import { useTranslations } from 'next-intl';
import { Link } from '@/i18n/routing';
import { useThemeStore } from '@/stores/theme';

const Footer = () => {
const { theme } = useTheme();
const theme = useThemeStore((store) => store.theme);
const currentDate = new Date();
const t = useTranslations();

Expand Down
17 changes: 11 additions & 6 deletions apps/app/src/components/app/Layouts/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import ActiveLink from '../ActiveLink';
import Skeleton from '@/components/skeleton/common/Skeleton';
import { dollarFormat, nanoToMilli } from '@/utils/libs';
import User from '../Icons/User';
import { useTheme } from 'next-themes';
import { BlocksInfo, Stats } from '@/utils/types';
import { Link, routing, usePathname } from '@/i18n/routing';
import { useTranslations } from 'next-intl';
import Search from '../common/Search';
import { useConfig } from '@/hooks/app/useConfig';
import { useThemeStore } from '@/stores/theme';

const menus = [
{
Expand Down Expand Up @@ -165,7 +165,8 @@ const Header = ({
const t = useTranslations();
const { networkId } = useConfig();
const pathname = usePathname();
const { theme, setTheme } = useTheme();
const theme = useThemeStore((store) => store.theme);

const status = useMemo(() => {
if (block?.block_timestamp) {
const timestamp = nanoToMilli(block?.block_timestamp);
Expand All @@ -180,6 +181,12 @@ const Header = ({
return true;
}, [block]);

const toggleTheme = () => {
localStorage.setItem('theme', theme === 'light' ? 'dark' : 'light');
document.documentElement.classList.toggle('dark');
document.documentElement.classList.toggle('light');
};

const showSearch = pathname !== '/';
const userLoading = false;

Expand Down Expand Up @@ -300,7 +307,7 @@ const Header = ({
<div className="flex md:!hidden items-center justify-center ml-auto p-3 md:p-4">
<button
className="py-2 h-6 w-[36px] bg-gray-100 dark:bg-black-200 rounded mx-4 flex items-center justify-center"
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
onClick={toggleTheme}
>
<Image
src={`/images/${theme === 'dark' ? 'moon.svg' : 'sun.svg'}`}
Expand Down Expand Up @@ -667,9 +674,7 @@ const Header = ({
>
<div
className="py-2 px-3 h-9 w-[38px] bg-gray-100 dark:bg-black-200 rounded cursor-pointer"
onClick={() =>
setTheme(theme === 'light' ? 'dark' : 'light')
}
onClick={toggleTheme}
>
<Image
src={`/images/${
Expand Down
42 changes: 27 additions & 15 deletions apps/app/src/components/app/Layouts/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { getRequest } from '@/utils/app/api';
import LayoutActions from './LayoutActions';
import { NextIntlClientProvider } from 'next-intl';
import { getMessages } from 'next-intl/server';
import { ThemeProvider } from 'next-themes';
import { Manrope } from 'next/font/google';
import Script from 'next/script';
import { PublicEnvProvider } from 'next-runtime-env';
Expand Down Expand Up @@ -85,7 +84,11 @@ const Layout = async ({ children }: LayoutProps) => {
};

return (
<html className={manrope.className} suppressHydrationWarning lang="en">
<html
className={`${manrope.className} light`}
suppressHydrationWarning
lang="en"
>
<head>
<link
rel="apple-touch-icon"
Expand Down Expand Up @@ -116,7 +119,6 @@ const Layout = async ({ children }: LayoutProps) => {
style={{ display: 'none', visibility: 'hidden' }}
/>
</noscript>

<Script id="gtm" strategy="afterInteractive">
{`
(function(w,d,s,l,i){
Expand All @@ -131,19 +133,29 @@ const Layout = async ({ children }: LayoutProps) => {
})(window,document,'script','dataLayer','${process.env.NEXT_PUBLIC_GTM_ID}');
`}
</Script>
<script
dangerouslySetInnerHTML={{
__html: `(function initTheme() {
var theme = localStorage.getItem('theme') || 'light'
if (theme === 'dark') {
document.documentElement.classList.remove('light');
document.documentElement.classList.add('dark');
}
})();`,
}}
id="theme-script"
/>
<PublicEnvProvider>
<ThemeProvider attribute="class" enableSystem={false}>
<NextIntlClientProvider messages={messages}>
<ToastContainer />
<LayoutActions
stats={stats}
blocks={blocks}
handleFilterAndKeyword={handleFilterAndKeyword}
>
{children}
</LayoutActions>
</NextIntlClientProvider>
</ThemeProvider>
<NextIntlClientProvider messages={messages}>
<ToastContainer />
<LayoutActions
stats={stats}
blocks={blocks}
handleFilterAndKeyword={handleFilterAndKeyword}
>
{children}
</LayoutActions>
</NextIntlClientProvider>
</PublicEnvProvider>
</body>
</html>
Expand Down
6 changes: 4 additions & 2 deletions apps/app/src/components/app/Layouts/LayoutActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import Header from './Header';
import Footer from './Footer';
import { ReactNode } from 'react';
import NextTopLoader from 'nextjs-toploader';
import { useTheme } from 'next-themes';
import { useThemeStore } from '@/stores/theme';
import { useTheme } from '@/hooks/app/useTheme';

interface LayoutProps {
children: ReactNode;
Expand All @@ -22,7 +23,8 @@ const LayoutActions = ({
handleFilterAndKeyword,
}: LayoutProps) => {
const pathname = usePathname();
const theme: any = useTheme();
useTheme();
const theme = useThemeStore((store) => store.theme);
const className =
pathname === '/404'
? 'bg-white dark:bg-black-300'
Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/components/app/Layouts/RpcMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const RpcMenu = () => {
<li className="relative group flex h-8 justify-end max-md:mb-2">
<span className="border rounded-md bg-gray-100 dark:bg-black-200 text-nearblue-600 dark:text-neargray-10 hover:text-green-500 dark:hover:text-green-250 ">
<div className="absolute max-md:hidden left-2.5 top-2 md:flex items-center pointer-events-none">
<Rpc className="h-3.5 dark:filter dark:invert" />
<Rpc className="h-3.5 dark:text-neargray-10" />
</div>
<button
className={`h-full max-md:!w-24 md:w-28 pl-3 pr-6 md:!px-7 py-1 truncate cursor-pointer focus:outline-none appearance-none`}
Expand Down
4 changes: 2 additions & 2 deletions apps/app/src/components/app/NodeExplorer/Delegators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { useEffect, useRef, useState } from 'react';
import { Tooltip } from '@reach/tooltip';
import useRpc from '@/hooks/useRpc';
import Image from 'next/image';
import { useTheme } from 'next-themes';
import { debounce } from 'lodash';
import Skeleton from '../skeleton/common/Skeleton';
import Table from '../common/Table';
Expand All @@ -16,6 +15,7 @@ import { useRpcStore } from '@/stores/rpc';
import { Link } from '@/i18n/routing';
import { useSearchParams } from 'next/navigation';
import { useConfig } from '@/hooks/app/useConfig';
import { useThemeStore } from '@/stores/theme';

interface Props {
accountId: string;
Expand All @@ -33,7 +33,7 @@ const Delegators = ({ accountId }: Props) => {
const { networkId } = useConfig();
const searchParams = useSearchParams();
const page = searchParams?.get('page');
const { theme }: any = useTheme();
const theme = useThemeStore((store) => store.theme);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(true);
const [currentEpochInfo, setCurrentEpochInfo] =
Expand Down
4 changes: 2 additions & 2 deletions apps/app/src/components/app/NodeExplorer/NodeListActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import ErrorMessage from '../common/ErrorMessage';
import FaInbox from '../Icons/FaInbox';
import { Tooltip } from '@reach/tooltip';
import { ValidatorEpochData } from 'nb-types';
import { useTheme } from 'next-themes';
import Table from '../common/Table';
import Big from 'big.js';
import Image from 'next/image';
import { Link } from '@/i18n/routing';
import { useThemeStore } from '@/stores/theme';

const NodeListActions = ({ data, totalSupply, latestBlock, error }: any) => {
const { theme } = useTheme();
const theme = useThemeStore((store) => store.theme);
const [page, setPage] = useState(1);
const [totalCount, setTotalCount] = useState<number>(0);
const [expanded, setExpanded] = useState<number[]>([]);
Expand Down
13 changes: 6 additions & 7 deletions apps/app/src/components/app/Transactions/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import Skeleton from '../skeleton/common/Skeleton';
import { gasPrice } from '@/utils/near';
import { useEffect, useMemo, useState } from 'react';
import { ChartConfigType, ChartInfo, StatusInfo } from '@/utils/types';
import { useTheme } from 'next-themes';
import { Tooltip } from '@reach/tooltip';
import Image from 'next/image';
import { useTranslations } from 'next-intl';
import { Link } from '@/i18n/routing';
import { useConfig } from '@/hooks/app/useConfig';
import { useThemeStore } from '@/stores/theme';

interface Props {
stats: StatusInfo;
Expand All @@ -24,10 +24,9 @@ interface Props {

const Overview = ({ stats, chartsDetails, error }: Props) => {
const t = useTranslations();
const { theme, systemTheme } = useTheme();
const theme = useThemeStore((store) => store.theme);
const [mounted, setMounted] = useState(false);
const [chartConfig, setChartConfig] = useState<ChartConfigType>(null);
const currentTheme = theme === 'system' ? systemTheme : theme;
const { networkId } = useConfig();

const LoadingSkeleton = () => {
Expand Down Expand Up @@ -166,7 +165,7 @@ const Overview = ({ stats, chartsDetails, error }: Props) => {
labels: {
step: 7,
style: {
color: currentTheme === 'dark' ? '#e0e0e0' : '#333333',
color: theme === 'dark' ? '#e0e0e0' : '#333333',
},
},
categories: chartData.categories,
Expand All @@ -178,7 +177,7 @@ const Overview = ({ stats, chartsDetails, error }: Props) => {
},
labels: {
style: {
color: currentTheme === 'dark' ? '#e0e0e0' : '#333333',
color: theme === 'dark' ? '#e0e0e0' : '#333333',
},
},
},
Expand Down Expand Up @@ -216,15 +215,15 @@ const Overview = ({ stats, chartsDetails, error }: Props) => {
}

fetchData();
}, [chartData, currentTheme, mounted]);
}, [chartData, theme, mounted]);

const iframeSrc = chartConfig
? `
<html>
<head>
<style>
body, html{
background-color: ${currentTheme === 'dark' ? '#0D0D0D' : '#ffff'};
background-color: ${theme === 'dark' ? '#0D0D0D' : '#ffff'};
}
</style>
<script src="https://code.highcharts.com/highcharts.js"></script>
Expand Down
Loading

0 comments on commit c79b108

Please sign in to comment.