Skip to content

Commit 3d60059

Browse files
tom2drumyvaskov
andauthored
Add ENV variable allowing to choose default color schema (blockscout#1882)
* Add ENV variable allowing to choose default color schema Fixes blockscout#1868 * Update values.yaml.gotmpl --------- Co-authored-by: Yan Vaskov <[email protected]>
1 parent 3acc861 commit 3d60059

File tree

16 files changed

+90
-36
lines changed

16 files changed

+90
-36
lines changed

configs/app/ui.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import type { ContractCodeIde } from 'types/client/contract';
22
import { NAVIGATION_LINK_IDS, type NavItemExternal, type NavigationLinkId } from 'types/client/navigation-items';
33
import type { ChainIndicatorId } from 'types/homepage';
44
import type { NetworkExplorer } from 'types/networks';
5+
import type { ColorThemeId } from 'types/settings';
6+
7+
import { COLOR_THEMES } from 'lib/settings/colorTheme';
58

69
import * as views from './ui/views';
710
import { getEnvValue, getExternalAssetFilePath, parseEnvJson } from './utils';
@@ -21,6 +24,11 @@ const hiddenLinks = (() => {
2124
return result;
2225
})();
2326

27+
const defaultColorTheme = (() => {
28+
const envValue = getEnvValue('NEXT_PUBLIC_COLOR_THEME_DEFAULT') as ColorThemeId | undefined;
29+
return COLOR_THEMES.find((theme) => theme.id === envValue);
30+
})();
31+
2432
// eslint-disable-next-line max-len
2533
const HOMEPAGE_PLATE_BACKGROUND_DEFAULT = 'radial-gradient(103.03% 103.03% at 0% 0%, rgba(183, 148, 244, 0.8) 0%, rgba(0, 163, 196, 0.8) 100%), var(--chakra-colors-blue-400)';
2634

@@ -70,6 +78,9 @@ const UI = Object.freeze({
7078
items: parseEnvJson<Array<ContractCodeIde>>(getEnvValue('NEXT_PUBLIC_CONTRACT_CODE_IDES')) || [],
7179
},
7280
hasContractAuditReports: getEnvValue('NEXT_PUBLIC_HAS_CONTRACT_AUDIT_REPORTS') === 'true' ? true : false,
81+
colorTheme: {
82+
'default': defaultColorTheme,
83+
},
7384
});
7485

7586
export default UI;

deploy/tools/envs-validator/schema.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import type { CustomLink, CustomLinksGroup } from '../../../types/footerLinks';
2828
import { CHAIN_INDICATOR_IDS } from '../../../types/homepage';
2929
import type { ChainIndicatorId } from '../../../types/homepage';
3030
import { type NetworkVerificationType, type NetworkExplorer, type FeaturedNetwork, NETWORK_GROUPS } from '../../../types/networks';
31+
import { COLOR_THEME_IDS } from '../../../types/settings';
3132
import type { AddressViewId } from '../../../types/views/address';
3233
import { ADDRESS_VIEWS_IDS, IDENTICON_TYPES } from '../../../types/views/address';
3334
import { BLOCK_FIELDS_IDS } from '../../../types/views/block';
@@ -582,6 +583,7 @@ const schema = yup
582583
NEXT_PUBLIC_HIDE_INDEXING_ALERT_BLOCKS: yup.boolean(),
583584
NEXT_PUBLIC_HIDE_INDEXING_ALERT_INT_TXS: yup.boolean(),
584585
NEXT_PUBLIC_MAINTENANCE_ALERT_MESSAGE: yup.string(),
586+
NEXT_PUBLIC_COLOR_THEME_DEFAULT: yup.string().oneOf(COLOR_THEME_IDS),
585587

586588
// 5. Features configuration
587589
NEXT_PUBLIC_API_SPEC_URL: yup.string().test(urlTest),

deploy/tools/envs-validator/test/.env.base

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ NEXT_PUBLIC_APP_PORT=3000
2121
NEXT_PUBLIC_APP_PROTOCOL=http
2222
NEXT_PUBLIC_BRIDGED_TOKENS_CHAINS=[{'id':'1','title':'Ethereum','short_title':'ETH','base_url':'https://example.com'}]
2323
NEXT_PUBLIC_BRIDGED_TOKENS_BRIDGES=[{'type':'omni','title':'OmniBridge','short_title':'OMNI'}]
24+
NEXT_PUBLIC_COLOR_THEME_DEFAULT=dim
2425
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.blockscout.com/?address={hash}&blockscout={domain}','icon_url':'https://example.com/icon.svg'}]
2526
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://example.com
2627
NEXT_PUBLIC_DATA_AVAILABILITY_ENABLED=true

deploy/values/review/values.yaml.gotmpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ frontend:
9494
NEXT_PUBLIC_AD_ADBUTLER_CONFIG_MOBILE: "{ \"id\": \"632018\", \"width\": \"320\", \"height\": \"100\" }"
9595
NEXT_PUBLIC_DATA_AVAILABILITY_ENABLED: true
9696
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED: true
97+
NEXT_PUBLIC_COLOR_THEME_DEFAULT: "dim"
9798
envFromSecret:
9899
NEXT_PUBLIC_SENTRY_DSN: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_SENTRY_DSN
99100
SENTRY_CSP_REPORT_URI: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/SENTRY_CSP_REPORT_URI

docs/ENVS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ Settings for meta tags, OG tags and SEO
275275
| NEXT_PUBLIC_HIDE_INDEXING_ALERT_BLOCKS | `boolean` | Set to `true` to hide indexing alert in the page header about indexing chain's blocks | - | `false` | `true` |
276276
| NEXT_PUBLIC_HIDE_INDEXING_ALERT_INT_TXS | `boolean` | Set to `true` to hide indexing alert in the page footer about indexing block's internal transactions | - | `false` | `true` |
277277
| NEXT_PUBLIC_MAINTENANCE_ALERT_MESSAGE | `string` | Used for displaying custom announcements or alerts in the header of the site. Could be a regular string or a HTML code. | - | - | `Hello world! 🤪` |
278+
| NEXT_PUBLIC_COLOR_THEME_DEFAULT | `'light' \| 'dim' \| 'midnight' \| 'dark'` | Preferred color theme of the app | - | - | `midnight` |
278279

279280
#### Network explorer configuration properties
280281

lib/contexts/chakra.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ import {
66
import type { ChakraProviderProps } from '@chakra-ui/react';
77
import React from 'react';
88

9+
import theme from 'theme';
10+
911
interface Props extends ChakraProviderProps {
1012
cookies?: string;
1113
}
1214

13-
export function ChakraProvider({ cookies, theme, children }: Props) {
15+
export function ChakraProvider({ cookies, children }: Props) {
1416
const colorModeManager =
1517
typeof cookies === 'string' ?
1618
cookieStorageManagerSSR(typeof document !== 'undefined' ? document.cookie : cookies) :

lib/settings/colorTheme.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import type { ColorMode } from '@chakra-ui/react';
2+
3+
import type { ColorThemeId } from 'types/settings';
4+
5+
interface ColorTheme {
6+
id: ColorThemeId;
7+
label: string;
8+
colorMode: ColorMode;
9+
hex: string;
10+
sampleBg: string;
11+
}
12+
13+
export const COLOR_THEMES: Array<ColorTheme> = [
14+
{
15+
id: 'light',
16+
label: 'Light',
17+
colorMode: 'light',
18+
hex: '#FFFFFF',
19+
sampleBg: 'linear-gradient(154deg, #EFEFEF 50%, rgba(255, 255, 255, 0.00) 330.86%)',
20+
},
21+
{
22+
id: 'dim',
23+
label: 'Dim',
24+
colorMode: 'dark',
25+
hex: '#232B37',
26+
sampleBg: 'linear-gradient(152deg, #232B37 50%, rgba(255, 255, 255, 0.00) 290.71%)',
27+
},
28+
{
29+
id: 'midnight',
30+
label: 'Midnight',
31+
colorMode: 'dark',
32+
hex: '#1B2E48',
33+
sampleBg: 'linear-gradient(148deg, #1B3F71 50%, rgba(255, 255, 255, 0.00) 312.35%)',
34+
},
35+
{
36+
id: 'dark',
37+
label: 'Dark',
38+
colorMode: 'dark',
39+
hex: '#101112',
40+
sampleBg: 'linear-gradient(161deg, #000 9.37%, #383838 92.52%)',
41+
},
42+
];

ui/snippets/topBar/settings/utils.ts renamed to lib/settings/identIcon.ts

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,5 @@
11
import type { IdenticonType } from 'types/views/address';
22

3-
export const COLOR_THEMES = [
4-
{
5-
label: 'Light',
6-
colorMode: 'light',
7-
hex: '#FFFFFF',
8-
sampleBg: 'linear-gradient(154deg, #EFEFEF 50%, rgba(255, 255, 255, 0.00) 330.86%)',
9-
},
10-
{
11-
label: 'Dim',
12-
colorMode: 'dark',
13-
hex: '#232B37',
14-
sampleBg: 'linear-gradient(152deg, #232B37 50%, rgba(255, 255, 255, 0.00) 290.71%)',
15-
},
16-
{
17-
label: 'Midnight',
18-
colorMode: 'dark',
19-
hex: '#1B2E48',
20-
sampleBg: 'linear-gradient(148deg, #1B3F71 50%, rgba(255, 255, 255, 0.00) 312.35%)',
21-
},
22-
{
23-
label: 'Dark',
24-
colorMode: 'dark',
25-
hex: '#101112',
26-
sampleBg: 'linear-gradient(161deg, #000 9.37%, #383838 92.52%)',
27-
},
28-
];
29-
30-
export type ColorTheme = typeof COLOR_THEMES[number];
31-
323
export const IDENTICONS: Array<{ label: string; id: IdenticonType; sampleBg: string }> = [
334
{
345
label: 'GitHub',

middleware.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@ export function middleware(req: NextRequest) {
1919
return accountResponse;
2020
}
2121

22-
const end = Date.now();
2322
const res = NextResponse.next();
23+
24+
middlewares.colorTheme(req, res);
25+
26+
const end = Date.now();
27+
2428
res.headers.append('Content-Security-Policy', cspPolicy);
2529
res.headers.append('Server-Timing', `middleware;dur=${ end - start }`);
2630
res.headers.append('Docker-ID', process.env.HOSTNAME || '');

nextjs/middlewares/colorTheme.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { NextRequest, NextResponse } from 'next/server';
2+
3+
import appConfig from 'configs/app';
4+
import * as cookiesLib from 'lib/cookies';
5+
6+
export default function colorThemeMiddleware(req: NextRequest, res: NextResponse) {
7+
const colorModeCookie = req.cookies.get(cookiesLib.NAMES.COLOR_MODE);
8+
9+
if (!colorModeCookie) {
10+
if (appConfig.UI.colorTheme.default) {
11+
res.cookies.set(cookiesLib.NAMES.COLOR_MODE, appConfig.UI.colorTheme.default.colorMode, { path: '/' });
12+
res.cookies.set(cookiesLib.NAMES.COLOR_MODE_HEX, appConfig.UI.colorTheme.default.hex, { path: '/' });
13+
}
14+
}
15+
}

nextjs/middlewares/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { account } from './account';
2+
export { default as colorTheme } from './colorTheme';

pages/_app.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { growthBook } from 'lib/growthbook/init';
1818
import useLoadFeatures from 'lib/growthbook/useLoadFeatures';
1919
import useNotifyOnNavigation from 'lib/hooks/useNotifyOnNavigation';
2020
import { SocketProvider } from 'lib/socket/context';
21-
import theme from 'theme';
2221
import AppErrorBoundary from 'ui/shared/AppError/AppErrorBoundary';
2322
import GoogleAnalytics from 'ui/shared/GoogleAnalytics';
2423
import Layout from 'ui/shared/layout/Layout';
@@ -57,7 +56,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
5756
const getLayout = Component.getLayout ?? ((page) => <Layout>{ page }</Layout>);
5857

5958
return (
60-
<ChakraProvider theme={ theme } cookies={ pageProps.cookies }>
59+
<ChakraProvider cookies={ pageProps.cookies }>
6160
<AppErrorBoundary
6261
{ ...ERROR_SCREEN_STYLES }
6362
onError={ handleError }

theme/config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { type ThemeConfig } from '@chakra-ui/react';
22

3+
import appConfig from 'configs/app';
4+
35
const config: ThemeConfig = {
4-
initialColorMode: 'system',
6+
initialColorMode: appConfig.UI.colorTheme.default?.colorMode ?? 'system',
57
useSystemColorMode: false,
68
disableTransitionOnChange: false,
79
};

types/settings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const COLOR_THEME_IDS = [ 'light', 'dim', 'midnight', 'dark' ] as const;
2+
export type ColorThemeId = typeof COLOR_THEME_IDS[number];

ui/snippets/topBar/settings/SettingsColorTheme.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { Box, Flex, useColorMode } from '@chakra-ui/react';
22
import React from 'react';
33

44
import * as cookies from 'lib/cookies';
5+
import { COLOR_THEMES } from 'lib/settings/colorTheme';
56

67
import SettingsSample from './SettingsSample';
7-
import { COLOR_THEMES } from './utils';
88

99
const SettingsColorTheme = () => {
1010
const { setColorMode } = useColorMode();

ui/snippets/topBar/settings/SettingsIdentIcon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import React from 'react';
33

44
import config from 'configs/app';
55
import * as cookies from 'lib/cookies';
6+
import { IDENTICONS } from 'lib/settings/identIcon';
67

78
import SettingsSample from './SettingsSample';
8-
import { IDENTICONS } from './utils';
99

1010
const SettingsIdentIcon = () => {
1111
const [ activeId, setActiveId ] = React.useState<string>();

0 commit comments

Comments
 (0)