Check Flipper version when handling deeplinks

Summary: Check if Flipper is up to date before handling deeplink.

Reviewed By: nikoant

Differential Revision: D29846236

fbshipit-source-id: 011d05958346c3d18c76cf0ae63c3cb087f5933c
This commit is contained in:
Michel Weststrate
2021-08-10 13:23:05 -07:00
committed by Facebook GitHub Bot
parent b757bff9f6
commit 4b892e7373
4 changed files with 84 additions and 37 deletions

View File

@@ -49,32 +49,7 @@ export default function UpdateIndicator() {
placement: 'bottomLeft', placement: 'bottomLeft',
key: 'flipperupdatecheck', key: 'flipperupdatecheck',
message: 'Update available', message: 'Update available',
description: ( description: getUpdateAvailableMessage(versionCheckResult),
<>
Flipper version {versionCheckResult.version} is now available.
{fbConfig.isFBBuild ? (
fbConfig.getReleaseChannel() === ReleaseChannel.INSIDERS ? (
<> Restart Flipper to update to the latest version.</>
) : (
<>
{' '}
Run <code>arc pull</code> (optionally with{' '}
<code>--latest</code>) in <code>~/fbsource</code> and
restart Flipper to update to the latest version.
</>
)
) : (
<>
{' '}
Click to{' '}
<Typography.Link href={versionCheckResult.url}>
download
</Typography.Link>
.
</>
)}
</>
),
duration: null, // no auto close duration: null, // no auto close
}); });
break; break;
@@ -127,3 +102,35 @@ export default function UpdateIndicator() {
return null; return null;
} }
export function getUpdateAvailableMessage(versionCheckResult: {
url: string;
version: string;
}): React.ReactNode {
return (
<>
Flipper version {versionCheckResult.version} is now available.
{fbConfig.isFBBuild ? (
fbConfig.getReleaseChannel() === ReleaseChannel.INSIDERS ? (
<> Restart Flipper to update to the latest version.</>
) : (
<>
{' '}
Run <code>arc pull</code> (optionally with <code>--latest</code>) in{' '}
<code>~/fbsource</code> and restart Flipper to update to the latest
version.
</>
)
) : (
<>
{' '}
Click to{' '}
<Typography.Link href={versionCheckResult.url}>
download
</Typography.Link>
.
</>
)}
</>
);
}

View File

@@ -92,7 +92,10 @@ test('Triggering a deeplink will work', async () => {
jest.runAllTimers(); jest.runAllTimers();
expect(linksSeen).toEqual(['universe']); expect(linksSeen).toEqual(['universe']);
expect(renderer.baseElement).toMatchInlineSnapshot(` expect(renderer.baseElement).toMatchInlineSnapshot(`
<body> <body
class=""
style=""
>
<div> <div>
<div <div
class="css-1x2cmzz-SandySplitContainer e1hsqii10" class="css-1x2cmzz-SandySplitContainer e1hsqii10"

View File

@@ -7,14 +7,17 @@
* @format * @format
*/ */
import React from 'react';
import {Dialog, getFlipperLib} from 'flipper-plugin'; import {Dialog, getFlipperLib} from 'flipper-plugin';
import {getUser} from '../fb-stubs/user'; import {getUser} from '../fb-stubs/user';
import {Store} from '../reducers/index'; import {Store} from '../reducers/index';
// import {checkForUpdate} from '../fb-stubs/checkForUpdate'; import {checkForUpdate} from '../fb-stubs/checkForUpdate';
// import {getAppVersion} from '../utils/info'; import {getAppVersion} from '../utils/info';
import {ACTIVE_SHEET_SIGN_IN, setActiveSheet} from '../reducers/application'; import {ACTIVE_SHEET_SIGN_IN, setActiveSheet} from '../reducers/application';
import {UserNotSignedInError} from '../utils/errors'; import {UserNotSignedInError} from '../utils/errors';
import {selectPlugin} from '../reducers/connections'; import {selectPlugin} from '../reducers/connections';
import {getUpdateAvailableMessage} from '../chrome/UpdateIndicator';
import {Typography} from 'antd';
type OpenPluginParams = { type OpenPluginParams = {
pluginId: string; pluginId: string;
@@ -42,11 +45,12 @@ export function parseOpenPluginParams(query: string): OpenPluginParams {
export async function handleOpenPluginDeeplink(store: Store, query: string) { export async function handleOpenPluginDeeplink(store: Store, query: string) {
const params = parseOpenPluginParams(query); const params = parseOpenPluginParams(query);
const title = `Starting plugin ${params.pluginId}`;
if (!(await verifyLighthouseAndUserLoggedIn(store, params))) { if (!(await verifyLighthouseAndUserLoggedIn(store, title))) {
return; return;
} }
// await verifyFlipperIsUpToDate(); await verifyFlipperIsUpToDate(title);
// await verifyPluginInstalled(); // await verifyPluginInstalled();
// await verifyDevices(); // await verifyDevices();
// await verifyClient(); // await verifyClient();
@@ -57,14 +61,12 @@ export async function handleOpenPluginDeeplink(store: Store, query: string) {
// check if user is connected to VPN and logged in. Returns true if OK, or false if aborted // check if user is connected to VPN and logged in. Returns true if OK, or false if aborted
async function verifyLighthouseAndUserLoggedIn( async function verifyLighthouseAndUserLoggedIn(
store: Store, store: Store,
params: OpenPluginParams, title: string,
): Promise<boolean> { ): Promise<boolean> {
if (!getFlipperLib().isFB || process.env.NODE_ENV === 'test') { if (!getFlipperLib().isFB || process.env.NODE_ENV === 'test') {
return true; // ok, continue return true; // ok, continue
} }
const title = `Starting plugin ${params.pluginId}`;
// repeat until connection succeeded // repeat until connection succeeded
while (true) { while (true) {
const spinnerDialog = Dialog.loading({ const spinnerDialog = Dialog.loading({
@@ -136,6 +138,41 @@ async function waitForLogin(store: Store) {
}); });
} }
async function verifyFlipperIsUpToDate(title: string) {
const currentVersion = getAppVersion();
const handle = Dialog.loading({
title,
message: 'Checking if Flipper is up-to-date',
});
try {
const result = await checkForUpdate(currentVersion);
handle.close();
switch (result.kind) {
case 'error':
// if we can't tell if we're up to date, we don't want to halt the process on that.
console.warn('Failed to verify Flipper version', result);
return;
case 'up-to-date':
return;
case 'update-available':
await Dialog.confirm({
title,
message: (
<Typography.Text>
{getUpdateAvailableMessage(result)}
</Typography.Text>
),
okText: 'Skip',
});
return;
}
} catch (e) {
// if we can't tell if we're up to date, we don't want to halt the process on that.
console.warn('Failed to verify Flipper version', e);
handle.close();
}
}
function openPlugin(store: Store, params: OpenPluginParams) { function openPlugin(store: Store, params: OpenPluginParams) {
store.dispatch( store.dispatch(
selectPlugin({ selectPlugin({

View File

@@ -79,7 +79,7 @@ export const Dialog = {
message, message,
...rest ...rest
}: { }: {
message: string | React.ReactElement; message: React.ReactNode;
} & BaseDialogOptions): DialogResult<true> { } & BaseDialogOptions): DialogResult<true> {
return Dialog.show<true>({ return Dialog.show<true>({
...rest, ...rest,
@@ -94,7 +94,7 @@ export const Dialog = {
onConfirm, onConfirm,
...rest ...rest
}: BaseDialogOptions & { }: BaseDialogOptions & {
message: string | React.ReactElement; message: React.ReactNode;
defaultValue?: string; defaultValue?: string;
onConfirm?: (value: string) => Promise<string>; onConfirm?: (value: string) => Promise<string>;
}): DialogResult<string> { }): DialogResult<string> {
@@ -123,7 +123,7 @@ export const Dialog = {
width, width,
}: { }: {
title?: string; title?: string;
message: string | React.ReactElement; message: React.ReactNode;
width?: number; width?: number;
}) { }) {
let cancel: () => void; let cancel: () => void;