Compare commits
3
Commits
fix-dropdowns
...
node
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebf421ebed | ||
|
|
41409f578e | ||
|
|
f32fce2f80 |
+11
-3
@@ -4,7 +4,7 @@ export type Files = Map<string, string>;
|
||||
|
||||
export type FileTransform = (files: Files) => Promise<Files>;
|
||||
|
||||
export enum ElectronVersionState {
|
||||
export enum VersionState {
|
||||
ready = 'ready',
|
||||
downloading = 'downloading',
|
||||
unknown = 'unknown'
|
||||
@@ -14,12 +14,20 @@ export enum ElectronVersionSource {
|
||||
remote = 'remote',
|
||||
local = 'local'
|
||||
}
|
||||
export interface NpmVersion {
|
||||
|
||||
export interface Version {
|
||||
version: string;
|
||||
}
|
||||
|
||||
export interface NpmVersion extends Version {
|
||||
name?: string;
|
||||
localPath?: string;
|
||||
}
|
||||
|
||||
export interface NodeVersion extends Version {
|
||||
state: VersionState;
|
||||
}
|
||||
|
||||
export interface EditorValues {
|
||||
main: string;
|
||||
renderer: string;
|
||||
@@ -29,7 +37,7 @@ export interface EditorValues {
|
||||
}
|
||||
|
||||
export interface ElectronVersion extends NpmVersion {
|
||||
state: ElectronVersionState;
|
||||
state: VersionState;
|
||||
source: ElectronVersionSource;
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -3,9 +3,9 @@ import { ItemPredicate, ItemRenderer, Select } from '@blueprintjs/select';
|
||||
import { observer } from 'mobx-react';
|
||||
import * as React from 'react';
|
||||
|
||||
import { ElectronVersion, ElectronVersionSource, ElectronVersionState } from '../../interfaces';
|
||||
import { ElectronVersion, ElectronVersionSource, VersionState } from '../../interfaces';
|
||||
import { highlightText } from '../../utils/highlight-text';
|
||||
import { sortedElectronMap } from '../../utils/sorted-electron-map';
|
||||
import { sortedElectronMap } from '../../utils/sorted-map';
|
||||
import { AppState } from '../state';
|
||||
import { getReleaseChannel } from '../versions';
|
||||
|
||||
@@ -24,11 +24,11 @@ export function getItemLabel({ source, state, name }: ElectronVersion): string {
|
||||
if (source === ElectronVersionSource.local) {
|
||||
label = name || 'Local';
|
||||
} else {
|
||||
if (state === ElectronVersionState.unknown) {
|
||||
if (state === VersionState.unknown) {
|
||||
label = `Not downloaded`;
|
||||
} else if (state === ElectronVersionState.ready) {
|
||||
} else if (state === VersionState.ready) {
|
||||
label = `Downloaded`;
|
||||
} else if (state === ElectronVersionState.downloading) {
|
||||
} else if (state === VersionState.downloading) {
|
||||
label = `Downloading`;
|
||||
}
|
||||
}
|
||||
@@ -127,7 +127,7 @@ export const getVersionsFromAppState = (appState: AppState) => {
|
||||
* @extends {React.Component<VersionChooserProps, VersionChooserState>}
|
||||
*/
|
||||
@observer
|
||||
export class VersionChooser extends React.Component<VersionChooserProps, VersionChooserState> {
|
||||
export class ElectronVersionChooser extends React.Component<VersionChooserProps, VersionChooserState> {
|
||||
constructor(props: VersionChooserProps) {
|
||||
super(props);
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
import { Button, ButtonGroup, MenuItem } from '@blueprintjs/core';
|
||||
import { ItemPredicate, ItemRenderer, Select } from '@blueprintjs/select';
|
||||
import { observer } from 'mobx-react';
|
||||
import * as React from 'react';
|
||||
|
||||
import { ElectronVersion, NodeVersion, VersionState } from '../../interfaces';
|
||||
import { highlightText } from '../../utils/highlight-text';
|
||||
import { sortedNodeMap } from '../../utils/sorted-map';
|
||||
import { AppState } from '../state';
|
||||
|
||||
const ElectronVersionSelect = Select.ofType<NodeVersion>();
|
||||
|
||||
/**
|
||||
* Helper method: Returns the <Select /> label for an Electron
|
||||
* version.
|
||||
*
|
||||
* @param {ElectronVersion} { source, state }
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getItemLabel({ state }: NodeVersion): string {
|
||||
let label = '';
|
||||
|
||||
if (state === VersionState.unknown) {
|
||||
label = `Not downloaded`;
|
||||
} else if (state === VersionState.ready) {
|
||||
label = `Downloaded`;
|
||||
} else if (state === VersionState.downloading) {
|
||||
label = `Downloading`;
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method: Returns the <Select /> icon for an Electron
|
||||
* version.
|
||||
*
|
||||
* @param {ElectronVersion} { state }
|
||||
* @returns
|
||||
*/
|
||||
export function getItemIcon({ state }: NodeVersion) {
|
||||
return state === 'ready'
|
||||
? 'saved'
|
||||
: state === 'downloading' ? 'cloud-download' : 'cloud';
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method: Returns the <Select /> predicate for an Electron
|
||||
* version.
|
||||
*
|
||||
* @param {string} query
|
||||
* @param {ElectronVersion} { version }
|
||||
* @returns
|
||||
*/
|
||||
export const filterItem: ItemPredicate<NodeVersion> = (query, { version }) => {
|
||||
return version.toLowerCase().includes(query.toLowerCase());
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper method: Returns the <Select /> <MenuItem /> for Electron
|
||||
* versions.
|
||||
*
|
||||
* @param {ElectronVersion} item
|
||||
* @param {IItemRendererProps} { handleClick, modifiers, query }
|
||||
* @returns
|
||||
*/
|
||||
export const renderItem: ItemRenderer<NodeVersion> = (item, { handleClick, modifiers, query }) => {
|
||||
if (!modifiers.matchesPredicate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
active={modifiers.active}
|
||||
disabled={modifiers.disabled}
|
||||
text={highlightText(item.version, query)}
|
||||
key={item.version}
|
||||
onClick={handleClick}
|
||||
label={getItemLabel(item)}
|
||||
icon={getItemIcon(item)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export interface VersionChooserState {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface VersionChooserProps {
|
||||
appState: AppState;
|
||||
}
|
||||
|
||||
|
||||
export const getVersionsFromAppState = (appState: AppState) => {
|
||||
const { nodeVersions } = appState;
|
||||
|
||||
return sortedNodeMap<NodeVersion>(nodeVersions, (_key, item) => item)
|
||||
.filter((item) => !!item);
|
||||
};
|
||||
|
||||
/**
|
||||
* A dropdown allowing the selection of Electron versions. The actual
|
||||
* download is managed in the state.
|
||||
*
|
||||
* @class VersionChooser
|
||||
* @extends {React.Component<VersionChooserProps, VersionChooserState>}
|
||||
*/
|
||||
@observer
|
||||
export class NodeVersionChooser extends React.Component<VersionChooserProps, VersionChooserState> {
|
||||
constructor(props: VersionChooserProps) {
|
||||
super(props);
|
||||
|
||||
this.onItemSelect = this.onItemSelect.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle change, which usually means that we'd like update
|
||||
* the selection version.
|
||||
*
|
||||
* @param {React.ChangeEvent<HTMLSelectElement>} event
|
||||
*/
|
||||
public onItemSelect({ version }: ElectronVersion) {
|
||||
this.props.appState.setNodeVersion(version);
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { currentNodeVersion, Bisector } = this.props.appState;
|
||||
const { version } = currentNodeVersion;
|
||||
|
||||
return (
|
||||
<ButtonGroup>
|
||||
<ElectronVersionSelect
|
||||
filterable={true}
|
||||
items={getVersionsFromAppState(this.props.appState)}
|
||||
itemRenderer={renderItem}
|
||||
itemPredicate={filterItem}
|
||||
onItemSelect={this.onItemSelect}
|
||||
noResults={<MenuItem disabled={true} text='No results.' />}
|
||||
disabled={!!Bisector}
|
||||
>
|
||||
<Button
|
||||
className='version-chooser'
|
||||
text={`Node v${version}`}
|
||||
icon={getItemIcon(currentNodeVersion)}
|
||||
disabled={!!Bisector}
|
||||
/>
|
||||
</ElectronVersionSelect>
|
||||
</ButtonGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import { Button, IButtonProps, Spinner } from '@blueprintjs/core';
|
||||
import { observer } from 'mobx-react';
|
||||
import * as React from 'react';
|
||||
|
||||
import { ElectronVersionState } from '../../interfaces';
|
||||
import { VersionState } from '../../interfaces';
|
||||
import { AppState } from '../state';
|
||||
|
||||
export interface RunnerState {
|
||||
@@ -27,11 +27,11 @@ export class Runner extends React.Component<RunnerProps, RunnerState> {
|
||||
const state = currentElectronVersion && currentElectronVersion.state;
|
||||
const props: IButtonProps = { className: 'button-run' };
|
||||
|
||||
if (state === ElectronVersionState.downloading) {
|
||||
if (state === VersionState.downloading) {
|
||||
props.text = 'Downloading';
|
||||
props.disabled = true;
|
||||
props.icon = <Spinner size={16} />;
|
||||
} else if (state === ElectronVersionState.ready) {
|
||||
} else if (state === VersionState.ready) {
|
||||
if (isRunning) {
|
||||
props.active = true;
|
||||
props.text = 'Stop';
|
||||
|
||||
@@ -6,9 +6,10 @@ import { AppState } from '../state';
|
||||
import { AddressBar } from './commands-address-bar';
|
||||
import { BisectHandler } from './commands-bisect';
|
||||
import { EditorDropdown } from './commands-editors';
|
||||
import { ElectronVersionChooser } from './commands-electron-chooser';
|
||||
import { NodeVersionChooser } from './commands-node-chooser';
|
||||
import { PublishButton } from './commands-publish-button';
|
||||
import { Runner } from './commands-runner';
|
||||
import { VersionChooser } from './commands-version-chooser';
|
||||
|
||||
export interface CommandsProps {
|
||||
appState: AppState;
|
||||
@@ -35,7 +36,7 @@ export class Commands extends React.Component<CommandsProps, {}> {
|
||||
<div className='commands'>
|
||||
<div>
|
||||
<ControlGroup fill={true} vertical={false}>
|
||||
<VersionChooser appState={appState} />
|
||||
{this.getVersionChooser()}
|
||||
<Runner appState={appState} />
|
||||
</ControlGroup>
|
||||
{
|
||||
@@ -54,6 +55,12 @@ export class Commands extends React.Component<CommandsProps, {}> {
|
||||
text='Console'
|
||||
onClick={appState.toggleConsole}
|
||||
/>
|
||||
<Button
|
||||
active={appState.isNodeMode}
|
||||
icon='ninja'
|
||||
text='Node.js Mode'
|
||||
onClick={appState.toggleNodeMode}
|
||||
/>
|
||||
<EditorDropdown appState={appState} />
|
||||
</ControlGroup>
|
||||
</div>
|
||||
@@ -64,4 +71,14 @@ export class Commands extends React.Component<CommandsProps, {}> {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public getVersionChooser() {
|
||||
const { appState } = this.props;
|
||||
|
||||
if (appState.isNodeMode) {
|
||||
return <NodeVersionChooser appState={appState} />;
|
||||
} else {
|
||||
return <ElectronVersionChooser appState={appState} />;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import * as React from 'react';
|
||||
import { ElectronVersion } from '../../interfaces';
|
||||
import { Bisector } from '../bisect';
|
||||
import { AppState } from '../state';
|
||||
import { filterItem, getItemIcon, getVersionsFromAppState, renderItem } from './commands-version-chooser';
|
||||
import { filterItem, getItemIcon, getVersionsFromAppState, renderItem } from './commands-electron-chooser';
|
||||
|
||||
const ElectronVersionSelect = Select.ofType<ElectronVersion>();
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ import {
|
||||
import { observer } from 'mobx-react';
|
||||
import * as React from 'react';
|
||||
|
||||
import { ElectronVersion, ElectronVersionSource, ElectronVersionState } from '../../interfaces';
|
||||
import { ElectronVersion, ElectronVersionSource, VersionState } from '../../interfaces';
|
||||
import { normalizeVersion } from '../../utils/normalize-version';
|
||||
import { sortedElectronMap } from '../../utils/sorted-electron-map';
|
||||
import { sortedElectronMap } from '../../utils/sorted-map';
|
||||
import { AppState } from '../state';
|
||||
import { ElectronReleaseChannel, getReleaseChannel } from '../versions';
|
||||
|
||||
@@ -69,7 +69,7 @@ export class ElectronSettings extends React.Component<ElectronSettingsProps, Ele
|
||||
if (!checked) {
|
||||
appState.statesToShow = appState.statesToShow.filter((s) => s !== id);
|
||||
} else {
|
||||
appState.statesToShow.push(id as ElectronVersionState);
|
||||
appState.statesToShow.push(id as VersionState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ export class ElectronSettings extends React.Component<ElectronSettingsProps, Ele
|
||||
*/
|
||||
private renderVersionStateOptions(): JSX.Element {
|
||||
const { appState } = this.props;
|
||||
const getIsChecked = (state: ElectronVersionState) => {
|
||||
const getIsChecked = (state: VersionState) => {
|
||||
return appState.statesToShow.includes(state);
|
||||
};
|
||||
|
||||
@@ -211,21 +211,21 @@ export class ElectronSettings extends React.Component<ElectronSettingsProps, Ele
|
||||
label='Include Electron versions that are:'
|
||||
>
|
||||
<Checkbox
|
||||
checked={getIsChecked(ElectronVersionState.downloading)}
|
||||
checked={getIsChecked(VersionState.downloading)}
|
||||
label='Downloading'
|
||||
id='downloading'
|
||||
onChange={this.handleStateChange}
|
||||
inline={true}
|
||||
/>
|
||||
<Checkbox
|
||||
checked={getIsChecked(ElectronVersionState.ready)}
|
||||
checked={getIsChecked(VersionState.ready)}
|
||||
label='Downloaded'
|
||||
id='ready'
|
||||
onChange={this.handleStateChange}
|
||||
inline={true}
|
||||
/>
|
||||
<Checkbox
|
||||
checked={getIsChecked(ElectronVersionState.unknown)}
|
||||
checked={getIsChecked(VersionState.unknown)}
|
||||
label='Not Downloaded'
|
||||
id='unknown'
|
||||
onChange={this.handleStateChange}
|
||||
@@ -350,10 +350,10 @@ export class ElectronSettings extends React.Component<ElectronSettingsProps, Ele
|
||||
let icon: IconName = 'box';
|
||||
let humanState = 'Downloaded';
|
||||
|
||||
if (state === ElectronVersionState.downloading) {
|
||||
if (state === VersionState.downloading) {
|
||||
icon = 'cloud-download';
|
||||
humanState = 'Downloading';
|
||||
} else if (state === ElectronVersionState.unknown) {
|
||||
} else if (state === VersionState.unknown) {
|
||||
icon = 'cloud';
|
||||
humanState = 'Not downloaded';
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { when } from 'mobx';
|
||||
import { EditorId, EditorValues } from '../interfaces';
|
||||
import { INDEX_HTML_NAME, MAIN_JS_NAME, PRELOAD_JS_NAME, RENDERER_JS_NAME } from '../shared-constants';
|
||||
import { getOctokit } from '../utils/octokit';
|
||||
import { sortedElectronMap } from '../utils/sorted-electron-map';
|
||||
import { sortedElectronMap } from '../utils/sorted-map';
|
||||
import { ELECTRON_ORG, ELECTRON_REPO } from './constants';
|
||||
import { getContent } from './content';
|
||||
import { AppState } from './state';
|
||||
|
||||
+71
-10
@@ -8,11 +8,12 @@ import {
|
||||
EditorId,
|
||||
ElectronVersion,
|
||||
ElectronVersionSource,
|
||||
ElectronVersionState,
|
||||
MosaicId,
|
||||
NodeVersion,
|
||||
NpmVersion,
|
||||
OutputEntry,
|
||||
OutputOptions,
|
||||
VersionState,
|
||||
WarningDialogTexts
|
||||
} from '../interfaces';
|
||||
import { IpcEvents } from '../ipc-events';
|
||||
@@ -34,14 +35,16 @@ import { activateTheme } from './themes';
|
||||
import {
|
||||
addLocalVersion,
|
||||
ElectronReleaseChannel,
|
||||
getAllElectronVersions,
|
||||
getDefaultVersion,
|
||||
getElectronVersions,
|
||||
getUpdatedElectronVersions,
|
||||
getUpdatedNodeVersions,
|
||||
saveLocalVersions
|
||||
} from './versions';
|
||||
|
||||
const knownVersions = getElectronVersions();
|
||||
const knownVersions = getAllElectronVersions();
|
||||
const defaultVersion = getDefaultVersion(knownVersions);
|
||||
const defaultNodeVersion = '12.0.0';
|
||||
|
||||
/**
|
||||
* Editors exist outside of React's world. To make things *a lot*
|
||||
@@ -66,6 +69,7 @@ window.ElectronFiddle = window.ElectronFiddle || {
|
||||
export class AppState {
|
||||
// -- Persisted settings ------------------
|
||||
@observable public version: string = defaultVersion;
|
||||
@observable public nodeVersion: string = defaultNodeVersion;
|
||||
@observable public theme: string | null = localStorage.getItem('theme');
|
||||
@observable public gitHubAvatarUrl: string | null = localStorage.getItem('gitHubAvatarUrl');
|
||||
@observable public gitHubName: string | null = localStorage.getItem('gitHubName');
|
||||
@@ -75,9 +79,9 @@ export class AppState {
|
||||
@observable public versionsToShow: Array<ElectronReleaseChannel> =
|
||||
this.retrieve('versionsToShow') as Array<ElectronReleaseChannel>
|
||||
|| [ElectronReleaseChannel.stable, ElectronReleaseChannel.beta];
|
||||
@observable public statesToShow: Array<ElectronVersionState> =
|
||||
this.retrieve('statesToShow') as Array<ElectronVersionState>
|
||||
|| [ElectronVersionState.downloading, ElectronVersionState.ready, ElectronVersionState.unknown];
|
||||
@observable public statesToShow: Array<VersionState> =
|
||||
this.retrieve('statesToShow') as Array<VersionState>
|
||||
|| [VersionState.downloading, VersionState.ready, VersionState.unknown];
|
||||
@observable public isKeepingUserDataDirs: boolean = !!this.retrieve('isKeepingUserDataDirs');
|
||||
@observable public isEnablingElectronLogging: boolean = !!this.retrieve('isEnablingElectronLogging');
|
||||
@observable public isClearingConsoleOnRun: boolean = !!this.retrieve('isClearingConsoleOnRun');
|
||||
@@ -85,6 +89,7 @@ export class AppState {
|
||||
// -- Various session-only state ------------------
|
||||
@observable public gistId: string = '';
|
||||
@observable public versions: Record<string, ElectronVersion> = arrayToStringMap(knownVersions);
|
||||
@observable public nodeVersions: Record<string, NodeVersion> = arrayToStringMap([] as Array<NodeVersion>);
|
||||
@observable public output: Array<OutputEntry> = [];
|
||||
@observable public localPath: string | undefined;
|
||||
@observable public warningDialogTexts = { label: '', ok: 'Okay', cancel: 'Cancel' };
|
||||
@@ -113,6 +118,7 @@ export class AppState {
|
||||
@observable public isBisectDialogShowing: boolean = false;
|
||||
@observable public isAddVersionDialogShowing: boolean = false;
|
||||
@observable public isThemeDialogShowing: boolean = false;
|
||||
@observable public isNodeMode: boolean = false;
|
||||
@observable public isTourShowing: boolean = !localStorage.getItem('hasShownTour');
|
||||
|
||||
// -- Editor Values stored when we close the editor ------------------
|
||||
@@ -130,11 +136,13 @@ export class AppState {
|
||||
this.pushOutput = this.pushOutput.bind(this);
|
||||
this.removeVersion = this.removeVersion.bind(this);
|
||||
this.setVersion = this.setVersion.bind(this);
|
||||
this.setNodeVersion = this.setNodeVersion.bind(this);
|
||||
this.showTour = this.showTour.bind(this);
|
||||
this.signOutGitHub = this.signOutGitHub.bind(this);
|
||||
this.toggleBisectCommands = this.toggleBisectCommands.bind(this);
|
||||
this.toggleAuthDialog = this.toggleAuthDialog.bind(this);
|
||||
this.toggleConsole = this.toggleConsole.bind(this);
|
||||
this.toggleNodeMode = this.toggleNodeMode.bind(this);
|
||||
this.clearConsole = this.clearConsole.bind(this);
|
||||
this.toggleSettings = this.toggleSettings.bind(this);
|
||||
this.toggleBisectDialog = this.toggleBisectDialog.bind(this);
|
||||
@@ -196,6 +204,7 @@ export class AppState {
|
||||
|
||||
// Update our known versions
|
||||
this.updateElectronVersions();
|
||||
this.updateNodeVersions();
|
||||
|
||||
// Make sure the console isn't all empty and sad
|
||||
this.pushOutput('Console ready 🔬');
|
||||
@@ -213,6 +222,18 @@ export class AppState {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current NodeVersion or the first
|
||||
* one that can be found.
|
||||
*/
|
||||
@computed get currentNodeVersion(): NodeVersion {
|
||||
if (this.nodeVersions[this.nodeVersion]) {
|
||||
return this.nodeVersions[this.nodeVersion];
|
||||
} else {
|
||||
return this.nodeVersions[defaultNodeVersion];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Electron versions: First, fetch them from GitHub,
|
||||
* then update their respective downloaded state.
|
||||
@@ -233,6 +254,21 @@ export class AppState {
|
||||
this.isUpdatingElectronVersions = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Node versions: First, fetch them from Node.js,
|
||||
* then update their respective downloaded state.
|
||||
*
|
||||
* Fails silently.
|
||||
*/
|
||||
@action public async updateNodeVersions() {
|
||||
try {
|
||||
const nodeVersions = await getUpdatedNodeVersions();
|
||||
this.nodeVersions = arrayToStringMap(nodeVersions);
|
||||
} catch (error) {
|
||||
console.warn(`State: Could not update Node.js versions`, error);
|
||||
}
|
||||
}
|
||||
|
||||
@action public async getName() {
|
||||
if (!this.name) {
|
||||
this.name = await getName(this);
|
||||
@@ -245,6 +281,10 @@ export class AppState {
|
||||
this.isConsoleShowing = !this.isConsoleShowing;
|
||||
}
|
||||
|
||||
@action public toggleNodeMode() {
|
||||
this.isNodeMode = !this.isNodeMode;
|
||||
}
|
||||
|
||||
@action public clearConsole() {
|
||||
this.output = [];
|
||||
}
|
||||
@@ -332,7 +372,7 @@ export class AppState {
|
||||
@action public addLocalVersion(input: NpmVersion) {
|
||||
addLocalVersion(input);
|
||||
|
||||
this.versions = arrayToStringMap(getElectronVersions());
|
||||
this.versions = arrayToStringMap(getAllElectronVersions());
|
||||
this.updateDownloadedVersionState();
|
||||
}
|
||||
|
||||
@@ -368,7 +408,7 @@ export class AppState {
|
||||
saveLocalVersions(versionsAsArray);
|
||||
} else {
|
||||
await this.binaryManager.remove(version);
|
||||
updatedVersions[version].state = ElectronVersionState.unknown;
|
||||
updatedVersions[version].state = VersionState.unknown;
|
||||
}
|
||||
|
||||
this.versions = updatedVersions;
|
||||
@@ -394,7 +434,7 @@ export class AppState {
|
||||
console.log(`State: Instructing BinaryManager to fetch v${version}`);
|
||||
const updatedVersions = { ...this.versions };
|
||||
updatedVersions[version] = updatedVersions[version] || {};
|
||||
updatedVersions[version].state = ElectronVersionState.downloading;
|
||||
updatedVersions[version].state = VersionState.downloading;
|
||||
this.versions = updatedVersions;
|
||||
|
||||
await this.binaryManager.setup(version);
|
||||
@@ -404,6 +444,27 @@ export class AppState {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a version of Node.js (and download fi necessary)
|
||||
*
|
||||
* @param {string} input
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
@action public async setNodeVersion(input: string) {
|
||||
const version = normalizeVersion(input);
|
||||
|
||||
if (!this.nodeVersions[version]) {
|
||||
console.warn(`State: Called setNodeVersion() with ${version}, which does not exist.`);
|
||||
this.setVersion(this.nodeVersions[0].version);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`State: Switching to Node ${version}`);
|
||||
|
||||
this.nodeVersion = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a version of Electron (and download it if necessary).
|
||||
*
|
||||
@@ -465,7 +526,7 @@ export class AppState {
|
||||
|
||||
(downloadedVersions || []).forEach((version) => {
|
||||
if (updatedVersions[version]) {
|
||||
updatedVersions[version].state = ElectronVersionState.ready;
|
||||
updatedVersions[version].state = VersionState.ready;
|
||||
}
|
||||
});
|
||||
console.log(`State: Updated version state`, updatedVersions);
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
} from 'electron';
|
||||
import { autorun } from 'mobx';
|
||||
|
||||
import { ElectronVersion, ElectronVersionState } from '../interfaces';
|
||||
import { ElectronVersion, VersionState } from '../interfaces';
|
||||
import { getNiceGreeting } from '../utils/nice-greeting';
|
||||
import { sortedElectronMap } from '../utils/sorted-electron-map';
|
||||
import { sortedElectronMap } from '../utils/sorted-map';
|
||||
import { AppState } from './state';
|
||||
|
||||
const { TouchBar } = remote;
|
||||
@@ -26,7 +26,7 @@ const {
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getItemIcon(
|
||||
{ state }: Partial<ElectronVersion> = { state: ElectronVersionState.unknown }
|
||||
{ state }: Partial<ElectronVersion> = { state: VersionState.unknown }
|
||||
) {
|
||||
return state === 'ready'
|
||||
? '💾'
|
||||
|
||||
+62
-16
@@ -1,4 +1,4 @@
|
||||
import { ElectronVersion, ElectronVersionSource, ElectronVersionState, NpmVersion } from '../interfaces';
|
||||
import { ElectronVersion, ElectronVersionSource, NodeVersion, NpmVersion, VersionState } from '../interfaces';
|
||||
import { normalizeVersion } from '../utils/normalize-version';
|
||||
|
||||
export const enum ElectronReleaseChannel {
|
||||
@@ -82,7 +82,7 @@ export const enum VersionKeys {
|
||||
* @param {() => Array<NpmVersion>} fallbackMethod
|
||||
* @returns {Array<NpmVersion>}
|
||||
*/
|
||||
function getVersions(
|
||||
function getElectronVersions(
|
||||
key: VersionKeys, fallbackMethod: () => Array<NpmVersion>
|
||||
): Array<NpmVersion> {
|
||||
const fromLs = window.localStorage.getItem(key);
|
||||
@@ -117,7 +117,7 @@ function getVersions(
|
||||
* @param {VersionKeys} key
|
||||
* @param {Array<NpmVersion} versions
|
||||
*/
|
||||
function saveVersions(key: VersionKeys, versions: Array<NpmVersion>) {
|
||||
function saveElectronVersions(key: VersionKeys, versions: Array<NpmVersion>) {
|
||||
const stringified = JSON.stringify(versions);
|
||||
window.localStorage.setItem(key, stringified);
|
||||
}
|
||||
@@ -127,12 +127,12 @@ function saveVersions(key: VersionKeys, versions: Array<NpmVersion>) {
|
||||
*
|
||||
* @returns {Array<NpmVersion>}
|
||||
*/
|
||||
export function getElectronVersions(): Array<ElectronVersion> {
|
||||
export function getAllElectronVersions(): Array<ElectronVersion> {
|
||||
const known: Array<ElectronVersion> = getKnownVersions().map((version) => {
|
||||
return {
|
||||
...version,
|
||||
source: ElectronVersionSource.remote,
|
||||
state: ElectronVersionState.unknown
|
||||
state: VersionState.unknown
|
||||
};
|
||||
});
|
||||
|
||||
@@ -140,11 +140,11 @@ export function getElectronVersions(): Array<ElectronVersion> {
|
||||
return {
|
||||
...version,
|
||||
source: ElectronVersionSource.local,
|
||||
state: ElectronVersionState.ready
|
||||
state: VersionState.ready
|
||||
};
|
||||
});
|
||||
|
||||
return [ ...known, ...local ];
|
||||
return [...known, ...local];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,7 +171,7 @@ export function addLocalVersion(input: NpmVersion): Array<NpmVersion> {
|
||||
* @returns {Array<NpmVersion>}
|
||||
*/
|
||||
export function getLocalVersions(): Array<NpmVersion> {
|
||||
const versions = getVersions(VersionKeys.local, () => []);
|
||||
const versions = getElectronVersions(VersionKeys.local, () => []);
|
||||
|
||||
return versions;
|
||||
}
|
||||
@@ -190,7 +190,7 @@ export function saveLocalVersions(versions: Array<NpmVersion | ElectronVersion>)
|
||||
return true;
|
||||
});
|
||||
|
||||
return saveVersions(VersionKeys.local, filteredVersions);
|
||||
return saveElectronVersions(VersionKeys.local, filteredVersions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,7 +200,7 @@ export function saveLocalVersions(versions: Array<NpmVersion | ElectronVersion>)
|
||||
* @returns {Array<NpmVersion>}
|
||||
*/
|
||||
export function getKnownVersions(): Array<NpmVersion> {
|
||||
return getVersions(VersionKeys.known, () => require('../../static/releases.json'));
|
||||
return getElectronVersions(VersionKeys.known, () => require('../../static/releases.json'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,7 +209,7 @@ export function getKnownVersions(): Array<NpmVersion> {
|
||||
* @param {Array<NpmVersion>} versions
|
||||
*/
|
||||
export function saveKnownVersions(versions: Array<NpmVersion>) {
|
||||
return saveVersions(VersionKeys.known, versions);
|
||||
return saveElectronVersions(VersionKeys.known, versions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,20 +222,66 @@ export function saveKnownVersions(versions: Array<NpmVersion>) {
|
||||
export async function getUpdatedElectronVersions(
|
||||
): Promise<Array<ElectronVersion>> {
|
||||
try {
|
||||
await fetchVersions();
|
||||
await fetchElectronVersions();
|
||||
} catch (error) {
|
||||
console.warn(`Versions: Failed to fetch versions`, { error });
|
||||
console.warn(`Versions: Failed to fetch Electron versions`, { error });
|
||||
}
|
||||
|
||||
return getElectronVersions();
|
||||
return getAllElectronVersions();
|
||||
}
|
||||
|
||||
export async function getUpdatedNodeVersions(): Promise<Array<NodeVersion>> {
|
||||
try {
|
||||
return await fetchNodeVersions();
|
||||
} catch (error) {
|
||||
console.warn(`Versions: Failed to fetch Node.js versions`, { error });
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the latest known versions directly from npm.
|
||||
* Fetch the latest known Node.js versions directly from Node.js.
|
||||
*
|
||||
* @returns {Promise<Array<NpmVersion>>}
|
||||
*
|
||||
* let entry = {
|
||||
* "headers": 1,
|
||||
* "linux-arm64": 2,
|
||||
* "linux-x64": 6,
|
||||
* "osx-x64-tar": 8,
|
||||
* "win-x64-zip": 14,
|
||||
* "win-x86-zip": 18
|
||||
* }
|
||||
*
|
||||
* nodejs.org/dist/${version}/node-${version}-${files[entry]}.file-ext
|
||||
* ^ for windows, take the plat and extend with the file extension in the identifier above
|
||||
*/
|
||||
export async function fetchNodeVersions() {
|
||||
const channels = [
|
||||
`https://nodejs.org/dist/index.json`
|
||||
];
|
||||
|
||||
let output: Array<NodeVersion> = [];
|
||||
|
||||
for (const channelUrl of channels) {
|
||||
const response = await window.fetch(channelUrl);
|
||||
const versions = await response.json();
|
||||
|
||||
output = versions.map((input: any) => ({
|
||||
version: normalizeVersion(input.version)
|
||||
}));
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the latest known Electron versions directly from npm.
|
||||
*
|
||||
* @returns {Promise<Array<NpmVersion>>}
|
||||
*/
|
||||
export async function fetchVersions() {
|
||||
export async function fetchElectronVersions() {
|
||||
const channels = [
|
||||
`https://registry.npmjs.org/electron`, // stable, beta
|
||||
`https://registry.npmjs.org/electron-nightly` // nightly
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ElectronVersion } from '../interfaces';
|
||||
import { Version } from '../interfaces';
|
||||
import { normalizeVersion } from './normalize-version';
|
||||
|
||||
/**
|
||||
@@ -8,9 +8,9 @@ import { normalizeVersion } from './normalize-version';
|
||||
* @param {Array<ElectronVersion>} input
|
||||
* @returns {Record<string, ElectronVersion>}
|
||||
*/
|
||||
export function arrayToStringMap(
|
||||
input: Array<ElectronVersion>
|
||||
): Record<string, ElectronVersion> {
|
||||
export function arrayToStringMap<T extends Version>(
|
||||
input: Array<T>
|
||||
): Record<string, T> {
|
||||
const output = {};
|
||||
|
||||
input.forEach((version) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as semver from 'semver';
|
||||
|
||||
import { ElectronVersion } from '../interfaces';
|
||||
import { ElectronVersion, NodeVersion } from '../interfaces';
|
||||
|
||||
/**
|
||||
* Sorts Electron versions and returns the result of a
|
||||
@@ -13,6 +13,28 @@ import { ElectronVersion } from '../interfaces';
|
||||
export function sortedElectronMap<T>(
|
||||
versions: Record<string, ElectronVersion>,
|
||||
mapFn: (key: string, version: ElectronVersion) => T
|
||||
) {
|
||||
return sortedMap<ElectronVersion, T>(versions, mapFn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts Node versions and returns the result of a
|
||||
* map function.
|
||||
*
|
||||
* @param {Record<string, NodeVersion>} versions
|
||||
* @param {(key: string, version: NodeVersion) => void} mapFn
|
||||
* @returns {Array<T>}
|
||||
*/
|
||||
export function sortedNodeMap<T>(
|
||||
versions: Record<string, NodeVersion>,
|
||||
mapFn: (key: string, version: NodeVersion) => T
|
||||
) {
|
||||
return sortedMap<NodeVersion, T>(versions, mapFn);
|
||||
}
|
||||
|
||||
function sortedMap<T1, T2>(
|
||||
versions: Record<string, T1>,
|
||||
mapFn: (key: string, version: T1) => T2
|
||||
) {
|
||||
return Object.keys(versions)
|
||||
.sort((a, b) => {
|
||||
@@ -30,5 +52,5 @@ export function sortedElectronMap<T>(
|
||||
|
||||
return semver.gt(a, b, true) ? -1 : 1;
|
||||
})
|
||||
.map((key) => mapFn(key, versions[key])) as Array<T>;
|
||||
.map((key) => mapFn(key, versions[key])) as Array<T2>;
|
||||
}
|
||||
Reference in New Issue
Block a user