Skip to content

Commit b534765

Browse files
committed
move config to context to make it easier to change values at runtime
1 parent b63f146 commit b534765

File tree

13 files changed

+132
-62
lines changed

13 files changed

+132
-62
lines changed

src/Attribution.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import React from 'react';
22
import {Box, Text, Grommet} from 'grommet';
3-
import config from './config';
3+
import ConfigContext from './ConfigContext';
44

55
export default function Attribution() {
6-
if (config.hideAttribution) {
6+
const {config: hideAttribution} = React.useContext(ConfigContext);
7+
if (hideAttribution) {
78
return null;
89
}
910
return (

src/ConfigContext.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// @flow
2+
3+
import React from 'react';
4+
import config from './config';
5+
import type {Config} from './config';
6+
7+
const ConfigContext = React.createContext<{
8+
config: Config,
9+
updateConfig: ($Shape<Config>) => void,
10+
}>({
11+
config,
12+
updateConfig: (config) => {
13+
console.warn('updateConfig not implemented');
14+
},
15+
});
16+
17+
export default ConfigContext;

src/ErrorBox.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
import React from 'react';
44
import {Box, Text} from 'grommet';
55
import {StatusCritical} from 'grommet-icons/icons/StatusCritical';
6-
import config from './config';
6+
import ConfigContext from './ConfigContext';
77

88
const ErrorBox = ({error}: {error: any}) => {
9+
const {config} = React.useContext(ConfigContext);
910
console.error('error', error);
1011
const relayError = error?.source?.errors?.[0]?.message;
1112
return (

src/Head.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import React from 'react';
44
import NextHead from 'next/head';
5-
import config from './config';
5+
import ConfigContext from './ConfigContext';
66

77
function Head() {
8+
const {config} = React.useContext(ConfigContext);
89
return (
910
<NextHead>
1011
<title>{config.title}</title>

src/Header.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import React from 'react';
33
import {Box, Heading} from 'grommet';
44
import Avatar from './Avatar';
55
import Link from 'next/link';
6-
import config from './config';
6+
import ConfigContext from './ConfigContext';
77
import {PostBox} from './Post';
88
import {useRouter} from 'next/router';
99

1010
function Header({gitHub, adminLinks}) {
11+
const {config} = React.useContext(ConfigContext);
1112
const {pathname} = useRouter();
1213

1314
return (

src/MarkdownRenderer.js

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ import {ResponsiveContext} from 'grommet/contexts/ResponsiveContext';
1616
import emoji from './emoji';
1717
import {fetchTokenInfo, defaultThemeColors} from './lib/codeHighlight';
1818
import {isPromise} from 'relay-runtime';
19-
import Config from './config';
2019
import Tippy from '@tippyjs/react';
2120
import {slugify} from './Post';
21+
import ConfigContext from './ConfigContext';
2222

2323
import type {TokenInfo} from './lib/codeHighlight';
2424
import type {StatelessFunctionalComponent, Node} from 'react';
@@ -33,12 +33,10 @@ type Props = {|
3333
}>,
3434
|};
3535

36-
class CodeBlock extends React.PureComponent<
37-
{
38-
value: string,
39-
language: string,
40-
theme: string,
41-
},
36+
type CodeBlockProps = {|value: string, language: string, theme: string|};
37+
38+
export class CodeBlock extends React.PureComponent<
39+
CodeBlockProps,
4240
{
4341
tokenInfo: TokenInfo | Promise<TokenInfo>,
4442
},
@@ -51,18 +49,48 @@ class CodeBlock extends React.PureComponent<
5149
}),
5250
};
5351

54-
componentDidMount() {
55-
const {tokenInfo} = this.state;
52+
_updateTokenInfo = (tokenInfo: TokenInfo | Promise<TokenInfo>) => {
5653
if (isPromise(tokenInfo)) {
5754
tokenInfo
58-
.then((res) => this.setState({tokenInfo: res}))
55+
.then((res) => {
56+
this.setState((prevState) => {
57+
if (prevState.tokenInfo === tokenInfo) {
58+
return {tokenInfo: res};
59+
} else {
60+
return prevState;
61+
}
62+
});
63+
})
5964
.catch((e) => {
6065
console.error('Error fetching token info', e);
6166
});
6267
}
68+
};
69+
70+
componentDidMount() {
71+
this._updateTokenInfo(this.state.tokenInfo);
72+
}
73+
74+
componentDidUpdate(prevProps: CodeBlockProps) {
75+
if (
76+
this.props.value !== prevProps.value ||
77+
this.props.language !== prevProps.language ||
78+
this.props.theme !== prevProps.theme
79+
) {
80+
const tokenInfo = fetchTokenInfo({
81+
code: this.props.value,
82+
language: this.props.language,
83+
theme: this.props.theme,
84+
});
85+
this.setState({
86+
tokenInfo,
87+
});
88+
this._updateTokenInfo(tokenInfo);
89+
}
6390
}
91+
6492
render() {
65-
const {language, value} = this.props;
93+
const {language, value, theme} = this.props;
6694
const {tokenInfo} = this.state;
6795

6896
if (!isPromise(tokenInfo)) {
@@ -105,10 +133,8 @@ class CodeBlock extends React.PureComponent<
105133
overflowX: 'auto',
106134
padding: '1em',
107135
borderRadius: 4,
108-
color:
109-
defaultThemeColors[Config.codeTheme]?.foregroundColor || '#fff',
110-
background:
111-
defaultThemeColors[Config.codeTheme]?.backgroundColor || '#000',
136+
color: defaultThemeColors[theme]?.foregroundColor || '#fff',
137+
background: defaultThemeColors[theme]?.backgroundColor || '#000',
112138
}}>
113139
<code className={`language-${language}`}>{value}</code>
114140
</pre>
@@ -257,6 +283,18 @@ function Link(props) {
257283
return <Anchor {...props} />;
258284
}
259285

286+
function Code(props) {
287+
const {config} = React.useContext(ConfigContext);
288+
if (props.language === 'backmatter') {
289+
return null;
290+
}
291+
return (
292+
<Box margin={{vertical: 'small'}}>
293+
<CodeBlock theme={config.codeTheme} {...props} />
294+
</Box>
295+
);
296+
}
297+
260298
function flatten(text, child) {
261299
return typeof child === 'string'
262300
? text + child
@@ -305,16 +343,7 @@ const defaultRenderers = ({
305343
</code>
306344
);
307345
},
308-
code(props) {
309-
if (props.language === 'backmatter') {
310-
return null;
311-
}
312-
return (
313-
<Box margin={{vertical: 'small'}}>
314-
<CodeBlock theme={Config.codeTheme} {...props} />
315-
</Box>
316-
);
317-
},
346+
code: Code,
318347
image: Image,
319348
paragraph: ParagraphWrapper,
320349
heading(props) {

src/PostRoot.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Comments from './Comments';
1010
import Post from './Post';
1111
import ErrorBox from './ErrorBox';
1212
import Head from 'next/head';
13-
import config from './config';
13+
import ConfigContext from './ConfigContext';
1414
import Attribution from './Attribution';
1515
import parseMarkdown from './lib/parseMarkdown';
1616
import {useRouter} from 'next/router';
@@ -93,6 +93,7 @@ function buildDescription(body) {
9393
}
9494

9595
export const PostRoot = ({issueNumber}: {issueNumber: number}) => {
96+
const {config} = React.useContext(ConfigContext);
9697
const {basePath} = useRouter();
9798
const data: ?PostRoot_PostQueryResponse = useLazyLoadQuery<PostRoot_PostQuery>(
9899
query,

src/Posts.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import LoadingSpinner from './loadingSpinner';
99
import {Box} from 'grommet/components/Box';
1010
import {useInView} from 'react-intersection-observer';
1111
import Welcome from './Welcome';
12-
import config from './config';
1312
import 'intersection-observer';
1413

1514
type Props = {|

src/Welcome.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
import React from 'react';
44
import {PostBox} from './Post';
55
import {Box, Heading} from 'grommet';
6-
import config from './config';
6+
import ConfigContext from './ConfigContext';
77
import {newIssueUrl} from './issueUrls';
88

99
export default function Welcome() {
10+
const {config} = React.useContext(ConfigContext);
1011
return (
1112
<PostBox key="intro">
1213
<Box pad="medium">

src/lib/codeHighlight.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// @flow
22

33
import parseMarkdown from './parseMarkdown';
4-
import Config from '../config';
54

65
type Tokens = Array<{
76
text: string,
@@ -118,15 +117,18 @@ function findCodeNodes(roots: Array<any>) {
118117

119118
export async function tokenInfosFromMarkdowns({
120119
markdowns,
120+
theme,
121121
}: {
122122
markdowns: Array<string>,
123-
}): Array<{
124-
code: string,
125-
language: ?string,
126123
theme: string,
127-
tokenInfo: TokenInfo,
128-
}> {
129-
const theme = Config.codeTheme;
124+
}): Promise<
125+
Array<{
126+
code: string,
127+
language: ?string,
128+
theme: string,
129+
tokenInfo: TokenInfo,
130+
}>,
131+
> {
130132
const nodes = findCodeNodes(markdowns.map(parseMarkdown));
131133
return await Promise.all(
132134
nodes.map(async (node) => {

0 commit comments

Comments
 (0)