Files
flipper/desktop/app/src/chrome/MetroButton.tsx
Michel Weststrate 4463e7ede2 Restore metro functionality [4/n]
Summary: Restored Metro functionality; progress reports, metro logs, RN/Hermes debugging, reload / dev menu button

Reviewed By: passy

Differential Revision: D31055958

fbshipit-source-id: c243035c343c14718a9afe275c8f5f36a1aa3a94
2021-09-22 09:03:32 -07:00

95 lines
2.5 KiB
TypeScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import React, {useCallback, useEffect, useState} from 'react';
import {MetroReportableEvent} from '../server/devices/metro/MetroDevice';
import {useStore} from '../utils/useStore';
import {Button as AntButton} from 'antd';
import {MenuOutlined, ReloadOutlined} from '@ant-design/icons';
import {theme} from 'flipper-plugin';
import BaseDevice from '../devices/BaseDevice';
export default function MetroButton() {
const device = useStore((state) =>
state.connections.devices.find(
(device) => device.os === 'Metro' && device.connected.get(),
),
) as BaseDevice | undefined;
const sendCommand = useCallback(
(command: string) => {
device?.sendMetroCommand(command);
},
[device],
);
const [progress, setProgress] = useState(1);
const [_hasBuildError, setHasBuildError] = useState(false);
useEffect(() => {
if (!device) {
return;
}
function metroEventListener(event: MetroReportableEvent) {
if (event.type === 'bundle_build_started') {
setHasBuildError(false);
setProgress(0);
} else if (event.type === 'bundle_build_failed') {
setHasBuildError(true);
setProgress(1);
} else if (event.type === 'bundle_build_done') {
setHasBuildError(false);
setProgress(1);
} else if (event.type === 'bundle_transform_progressed') {
setProgress(event.transformedFileCount / event.totalFileCount);
}
}
const handle = device.addLogListener((l) => {
if (l.tag !== 'client_log') {
try {
metroEventListener(JSON.parse(l.message));
} catch (e) {
console.warn('Failed to parse metro message: ', l, e);
}
}
});
return () => {
device.removeLogListener(handle);
};
}, [device]);
if (!device) {
return null;
}
return (
<>
<AntButton
icon={<ReloadOutlined />}
title="Reload React Native App"
type="ghost"
onClick={() => {
sendCommand('reload');
}}
loading={progress < 1}
style={{color: _hasBuildError ? theme.errorColor : undefined}}
/>
<AntButton
icon={<MenuOutlined />}
title="Open the React Native Dev Menu on the device"
type="ghost"
onClick={() => {
sendCommand('devMenu');
}}
/>
</>
);
}