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:
committed by
Facebook Github Bot
parent
e874e032c6
commit
263b47f82f
@@ -171,7 +171,10 @@ class TitleBar extends React.Component<Props, StateFromProps> {
|
|||||||
{isAutoUpdaterEnabled() ? (
|
{isAutoUpdaterEnabled() ? (
|
||||||
<AutoUpdateVersion version={this.props.version} />
|
<AutoUpdateVersion version={this.props.version} />
|
||||||
) : (
|
) : (
|
||||||
<UpdateIndicator launcherMsg={this.props.launcherMsg} />
|
<UpdateIndicator
|
||||||
|
launcherMsg={this.props.launcherMsg}
|
||||||
|
version={this.props.version}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{config.bugReportButtonVisible && (
|
{config.bugReportButtonVisible && (
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -7,7 +7,15 @@
|
|||||||
|
|
||||||
import {LauncherMsg} from '../reducers/application';
|
import {LauncherMsg} from '../reducers/application';
|
||||||
import {colors, FlexRow, Glyph, styled} from 'flipper';
|
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 React from 'react';
|
||||||
|
import {shell} from 'electron';
|
||||||
|
|
||||||
const Container = styled(FlexRow)({
|
const Container = styled(FlexRow)({
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
@@ -16,6 +24,11 @@ const Container = styled(FlexRow)({
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
launcherMsg: LauncherMsg;
|
launcherMsg: LauncherMsg;
|
||||||
|
version: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
versionCheckResult: VersionCheckResult;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getSeverityColor(severity: 'warning' | 'error'): string {
|
function getSeverityColor(severity: 'warning' | 'error'): string {
|
||||||
@@ -27,8 +40,12 @@ function getSeverityColor(severity: 'warning' | 'error'): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class UpdateIndicator extends React.Component<Props> {
|
export default class UpdateIndicator extends React.PureComponent<Props, State> {
|
||||||
render() {
|
state = {
|
||||||
|
versionCheckResult: {kind: 'up-to-date'} as VersionCheckResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
renderMessage(): React.ReactNode {
|
||||||
if (this.props.launcherMsg.message.length == 0) {
|
if (this.props.launcherMsg.message.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -44,4 +61,56 @@ export default class UpdateIndicator extends React.Component<Props> {
|
|||||||
</Container>
|
</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()}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
80
src/utils/publicVersionChecker.tsx
Normal file
80
src/utils/publicVersionChecker.tsx
Normal 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}.`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user