Wire `Assets` into React components (#675)

Summary:
This commit takes the next step toward #643 by exposing `Assets` to our
React components at top level. Components will be expected to pass them
down as appropriate; this commit does not add any actual uses.

Test Plan:
Apply the following patch:

```diff
diff --git a/src/app/Page.js b/src/app/Page.js
index 24c2602..7ac2641 100644
--- a/src/app/Page.js
+++ b/src/app/Page.js
@@ -24,6 +24,10 @@ export default class Page extends React.Component<{|
                 <Link to="/" className={css(style.navLink, style.navLinkTitle)}>
                   SourceCred
                 </Link>
+                <img
+                  alt="fav"
+                  src={this.props.assets.resolve("/favicon.png")}
+                />
               </li>
               {routeData.map(({navTitle, path}) =>
                 NullUtil.map(navTitle, (navTitle) => (
```

Then, observe that the favicon loads correctly and updates across page
loads and refreshes in the following situations:
  - under `yarn start`;
  - after building the static site and serving from root;
  - after building the static site and serving from another gateway.

wchargin-branch: use-withAssets
This commit is contained in:
William Chargin 2018-08-15 16:54:53 -07:00 committed by GitHub
parent c4ecb979b3
commit 19af47a664
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 36 additions and 12 deletions

View File

@ -4,7 +4,9 @@ import {StyleSheet, css} from "aphrodite/no-important";
import React, {type Node} from "react";
import {Link} from "react-router";
export default class HomePage extends React.Component<{||}> {
import type {Assets} from "./assets";
export default class HomePage extends React.Component<{|+assets: Assets|}> {
render() {
const urls = {
numpyFunding:

View File

@ -3,12 +3,17 @@
import React, {type Node} from "react";
import {Link} from "react-router";
import {StyleSheet, css} from "aphrodite/no-important";
import type {Assets} from "./assets";
import GithubLogo from "./GithubLogo";
import TwitterLogo from "./TwitterLogo";
import {routeData} from "./routeData";
import * as NullUtil from "../util/null";
export default class Page extends React.Component<{|+children: Node|}> {
export default class Page extends React.Component<{|
+assets: Assets,
+children: Node,
|}> {
render() {
return (
<div>

View File

@ -5,22 +5,28 @@ import {IndexRoute, Route} from "react-router";
import Page from "./Page";
import ExternalRedirect from "./ExternalRedirect";
import withAssets from "./withAssets";
import {routeData} from "./routeData";
export function createRoutes() {
return (
<Route path="/" component={Page}>
<Route path="/" component={withAssets(Page)}>
{routeData.map(({path, contents}) => {
switch (contents.type) {
case "PAGE":
if (path === "/") {
return <IndexRoute key={path} component={contents.component()} />;
return (
<IndexRoute
key={path}
component={withAssets(contents.component())}
/>
);
} else {
return (
<Route
key={path}
path={path}
component={contents.component()}
component={withAssets(contents.component())}
/>
);
}

View File

@ -2,6 +2,7 @@
import React from "react";
import type {Assets} from "../assets";
import type {LocalStore} from "../localStore";
import CheckedLocalStore from "../checkedLocalStore";
import BrowserLocalStore from "../browserLocalStore";
@ -17,7 +18,7 @@ import {
initialState,
} from "./state";
export default class AppPage extends React.Component<{||}> {
export default class AppPage extends React.Component<{|+assets: Assets|}> {
static _LOCAL_STORE = new CheckedLocalStore(
new BrowserLocalStore({
version: "2",
@ -27,11 +28,11 @@ export default class AppPage extends React.Component<{||}> {
render() {
const App = createApp(createStateTransitionMachine);
return <App localStore={AppPage._LOCAL_STORE} />;
return <App assets={this.props.assets} localStore={AppPage._LOCAL_STORE} />;
}
}
type Props = {|+localStore: LocalStore|};
type Props = {|+assets: Assets, +localStore: LocalStore|};
type State = {|
appState: AppState,
|};

View File

@ -5,6 +5,7 @@ import {shallow} from "enzyme";
import {Graph} from "../../core/graph";
import {makeRepo} from "../../core/repo";
import {Assets} from "../assets";
import testLocalStore from "../testLocalStore";
import {DynamicAdapterSet, StaticAdapterSet} from "../adapters/adapterSet";
@ -35,7 +36,9 @@ describe("app/credExplorer/App", () => {
};
}
const App = createApp(createMockSTM);
const el = shallow(<App localStore={localStore} />);
const el = shallow(
<App assets={new Assets(null)} localStore={localStore} />
);
if (setState == null || getState == null) {
throw new Error("Initialization problems");
}

View File

@ -7,11 +7,18 @@
// inline syntax.
/*::
import type {Assets} from "./assets";
type RouteDatum = {|
+path: string,
+contents:
| {|+type: "PAGE", +component: () => React$ComponentType<{||}>|}
| {|+type: "EXTERNAL_REDIRECT", +redirectTo: string|},
| {|
+type: "PAGE",
+component: () => React$ComponentType<{|+assets: Assets|}>,
|}
| {|
+type: "EXTERNAL_REDIRECT",
+redirectTo: string,
|},
+title: string,
+navTitle: ?string,
|};

View File

@ -72,7 +72,7 @@ export default function render(
function renderRedirect(redirectTo: string) {
const component = (
<Page>
<Page assets={assets}>
<ExternalRedirect redirectTo={redirectTo} />
</Page>
);