diff --git a/website/src/website/components/Loader.tsx b/website/src/website/components/Loader.tsx new file mode 100644 index 0000000000..236aa75cc2 --- /dev/null +++ b/website/src/website/components/Loader.tsx @@ -0,0 +1,40 @@ +import * as React from "react"; +export class Loader extends React.Component< + { children: (value: T) => React.ReactChild; loader: () => Promise }, + { value: T | undefined; hasValue: boolean } +> { + constructor(props: any) { + super(props); + this.state = { value: undefined, hasValue: false }; + if (!this.state.value) { + this.props.loader().then((value) => { + this.setState({ + hasValue: true, + value, + }); + }); + } + } + + render() { + if (!this.state.hasValue) { + return null; + } + return this.props.children(this.state.value!); + } +} + +/** + * Decorates a component so that it only gets mounted when monaco is loaded. + */ +export function withLoader( + loader: () => Promise +): ( + Component: React.FunctionComponent | React.ComponentClass +) => any { + return (Component) => { + return (props: any) => ( + {() => } + ); + }; +} diff --git a/website/src/website/components/monaco/MonacoLoader.tsx b/website/src/website/components/monaco/MonacoLoader.tsx index 446654177f..61ea1c46c7 100644 --- a/website/src/website/components/monaco/MonacoLoader.tsx +++ b/website/src/website/components/monaco/MonacoLoader.tsx @@ -26,6 +26,7 @@ export class MonacoLoader extends React.Component< return this.props.children(this.state.monaco); } } + /** * Decorates a component so that it only gets mounted when monaco is loaded. */ diff --git a/website/src/website/pages/playground/PlaygroundModel.ts b/website/src/website/pages/playground/PlaygroundModel.ts index c21bfa313a..7096c30626 100644 --- a/website/src/website/pages/playground/PlaygroundModel.ts +++ b/website/src/website/pages/playground/PlaygroundModel.ts @@ -666,6 +666,20 @@ class Source { sourceStr: string | undefined, sourceLanguagesStr: string | undefined ): Source { + if (sourceStr === "latest-dev") { + // The versions are already loaded + const versions = getNpmVersionsSync(undefined); + const version = versions.find((v) => v.indexOf("-dev-") !== -1); + return new Source(version, undefined, sourceLanguagesStr); + } + if (sourceStr === "latest") { + return new Source( + monacoEditorVersion, + undefined, + sourceLanguagesStr + ); + } + if (sourceStr && sourceStr.startsWith("v")) { return new Source( sourceStr.substring(1), diff --git a/website/src/website/pages/playground/PlaygroundPage.tsx b/website/src/website/pages/playground/PlaygroundPage.tsx index 49a06f826b..fc6f6fbf96 100644 --- a/website/src/website/pages/playground/PlaygroundPage.tsx +++ b/website/src/website/pages/playground/PlaygroundPage.tsx @@ -3,7 +3,18 @@ import * as React from "react"; import { hotComponent } from "../../utils/hotComponent"; import { PlaygroundModel } from "./PlaygroundModel"; import { PlaygroundPageContent } from "./PlaygroundPageContent"; +import { withLoader } from "../../components/Loader"; +import { getNpmVersions } from "./getNpmVersionsSync"; +@withLoader(async () => { + if ( + new URLSearchParams(window.location.search).get("source") === + "latest-dev" + ) { + // So that the source class can resolve that value + await getNpmVersions(); + } +}) @hotComponent(module) @observer export class PlaygroundPage extends React.Component { diff --git a/website/src/website/pages/playground/getNpmVersionsSync.ts b/website/src/website/pages/playground/getNpmVersionsSync.ts index f1489039f0..7837b5f312 100644 --- a/website/src/website/pages/playground/getNpmVersionsSync.ts +++ b/website/src/website/pages/playground/getNpmVersionsSync.ts @@ -6,7 +6,7 @@ export function getNpmVersionsSync( currentVersion: string | undefined ): string[] { if (!npmVersionsObservable) { - npmVersionsObservable = new ObservablePromise(getNpmVersions()); + npmVersionsObservable = new ObservablePromise(loadNpmVersions()); } return ( npmVersionsObservable.value || (currentVersion ? [currentVersion] : []) @@ -16,6 +16,11 @@ export function getNpmVersionsSync( let npmVersionsPromise: Promise | undefined; export async function getNpmVersions(): Promise { + getNpmVersionsSync(undefined); + return npmVersionsPromise!; +} + +async function loadNpmVersions(): Promise { if (npmVersionsPromise === undefined) { npmVersionsPromise = _getNpmVersions(); }