Add x-platform update indicator

Summary: Use the new multi-platform update endpoint to indicate when new updates are available for Linux or Windows.

Reviewed By: danielbuechele

Differential Revision: D16939899

fbshipit-source-id: 11c1dc0d4fd19362a1163c613a7b7116c5edf996
This commit is contained in:
Pascal Hartig
2019-08-22 02:31:27 -07:00
committed by Facebook Github Bot
parent e874e032c6
commit 263b47f82f
3 changed files with 155 additions and 3 deletions

View File

@@ -171,7 +171,10 @@ class TitleBar extends React.Component<Props, StateFromProps> {
{isAutoUpdaterEnabled() ? (
<AutoUpdateVersion version={this.props.version} />
) : (
<UpdateIndicator launcherMsg={this.props.launcherMsg} />
<UpdateIndicator
launcherMsg={this.props.launcherMsg}
version={this.props.version}
/>
)}
{config.bugReportButtonVisible && (
<Button

View File

@@ -7,7 +7,15 @@
import {LauncherMsg} from '../reducers/application';
import {colors, FlexRow, Glyph, styled} from 'flipper';
import Tooltip from '../ui/components/Tooltip';
import isProduction from '../utils/isProduction';
import {
checkForUpdate,
VersionCheckResult,
} from '../utils/publicVersionChecker';
import {reportPlatformFailures} from '../utils/metrics';
import React from 'react';
import {shell} from 'electron';
const Container = styled(FlexRow)({
alignItems: 'center',
@@ -16,6 +24,11 @@ const Container = styled(FlexRow)({
type Props = {
launcherMsg: LauncherMsg;
version: string;
};
type State = {
versionCheckResult: VersionCheckResult;
};
function getSeverityColor(severity: 'warning' | 'error'): string {
@@ -27,8 +40,12 @@ function getSeverityColor(severity: 'warning' | 'error'): string {
}
}
export default class UpdateIndicator extends React.Component<Props> {
render() {
export default class UpdateIndicator extends React.PureComponent<Props, State> {
state = {
versionCheckResult: {kind: 'up-to-date'} as VersionCheckResult,
};
renderMessage(): React.ReactNode {
if (this.props.launcherMsg.message.length == 0) {
return null;
}
@@ -44,4 +61,56 @@ export default class UpdateIndicator extends React.Component<Props> {
</Container>
);
}
renderUpdateIndicator(): React.ReactNode {
const result = this.state.versionCheckResult;
if (result.kind !== 'update-available') {
return null;
}
const container = (
<Container>
<span onClick={() => shell.openExternal(result.url)}>
<Glyph
color={getSeverityColor(this.props.launcherMsg.severity)}
name="caution-triangle"
/>
</span>
</Container>
);
return (
<Tooltip
options={{position: 'toLeft'}}
title={`Update to Flipper v${
result.version
} available. Click to download.`}
children={container}
/>
);
}
componentDidMount() {
if (isProduction()) {
reportPlatformFailures(
checkForUpdate(this.props.version).then(res => {
if (res.kind === 'error') {
console.warn('Version check failure: ', res.msg);
throw new Error(res.msg);
}
this.setState({versionCheckResult: res});
}),
'publicVersionCheck',
);
}
}
render(): React.ReactNode {
return (
<>
{this.renderMessage()}
{this.renderUpdateIndicator()}
</>
);
}
}

View File

@@ -0,0 +1,80 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import os from 'os';
import config from '../fb-stubs/config';
const getPlatformSpecifier = (): string => {
switch (os.platform()) {
case 'win32':
return 'windows';
case 'linux':
return 'linux';
case 'darwin':
return 'mac';
default:
throw new Error('Unsupported platform.');
}
};
/**
* @param resp A parsed JSON object retrieved from the update server.
*/
const parseResponse = (resp: any): VersionCheckResult => {
const version = resp.version;
const platforms = resp.platforms;
if (!version || !platforms) {
return {kind: 'error', msg: 'Incomplete response.'};
}
const platformSpecifier = getPlatformSpecifier();
const platform = platforms[platformSpecifier];
if (!platform) {
return {kind: 'error', msg: `Unsupported platform: ${platformSpecifier}.`};
}
return {
kind: 'update-available',
url: platform,
version,
};
};
export type VersionCheckResult =
| {
kind: 'update-available';
url: string;
version: string;
}
| {
kind: 'up-to-date';
}
| {
kind: 'error';
msg: string;
};
export async function checkForUpdate(
currentVersion: string,
): Promise<VersionCheckResult> {
return fetch(`${config.updateServer}?version=${currentVersion}`).then(
(res: Response) => {
switch (res.status) {
case 204:
return {kind: 'up-to-date'};
case 200:
return res.json().then(parseResponse);
default:
return {
kind: 'error',
msg: `Server responded with ${res.statusText}.`,
};
}
},
);
}