From eab4f0d3d32ecdde5d262ca945949482231b10a5 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Wed, 8 Dec 2021 04:25:28 -0800 Subject: [PATCH] Bits & pieces Summary: Added a command to let a file be opened by the OS, and some other small bits and pieces to make Flipper browser compatible. Reviewed By: lblasa Differential Revision: D32721748 fbshipit-source-id: a4ad1c2f662f4651ddf6c20c57e5af1e123914a8 --- desktop/flipper-common/src/server-types.tsx | 1 + desktop/flipper-server-core/package.json | 1 + .../src/FlipperServerImpl.tsx | 2 + .../src/utils/openFile.tsx | 32 +++++++++++++++ desktop/flipper-ui-core/package.json | 1 - .../src/chrome/ScreenCaptureButtons.tsx | 39 ++++--------------- .../src/dispatcher/application.tsx | 8 ++-- .../src/sandy-chrome/SandyApp.tsx | 3 +- desktop/static/index.web.dev.html | 12 +++--- desktop/static/main.ts | 5 ++- desktop/yarn.lock | 2 +- 11 files changed, 58 insertions(+), 48 deletions(-) create mode 100644 desktop/flipper-server-core/src/utils/openFile.tsx diff --git a/desktop/flipper-common/src/server-types.tsx b/desktop/flipper-common/src/server-types.tsx index 102977aa0..4ee8be43a 100644 --- a/desktop/flipper-common/src/server-types.tsx +++ b/desktop/flipper-common/src/server-types.tsx @@ -189,6 +189,7 @@ export type FlipperServerCommands = { category: keyof FlipperDoctor.Healthchecks, name: string, ) => Promise; + 'open-file': (path: string) => Promise; }; /** diff --git a/desktop/flipper-server-core/package.json b/desktop/flipper-server-core/package.json index cb38914c6..3905029d7 100644 --- a/desktop/flipper-server-core/package.json +++ b/desktop/flipper-server-core/package.json @@ -24,6 +24,7 @@ "invariant": "^2.2.4", "js-base64": "^3.7.2", "lodash.memoize": "^4.1.2", + "open": "^8.3.0", "openssl-wrapper": "^0.3.4", "promisify-child-process": "^4.1.1", "rsocket-core": "^0.0.27", diff --git a/desktop/flipper-server-core/src/FlipperServerImpl.tsx b/desktop/flipper-server-core/src/FlipperServerImpl.tsx index 8ee9b61a0..07524258f 100644 --- a/desktop/flipper-server-core/src/FlipperServerImpl.tsx +++ b/desktop/flipper-server-core/src/FlipperServerImpl.tsx @@ -36,6 +36,7 @@ import {saveLauncherSettings} from './utils/launcherSettings'; import {KeytarManager} from './utils/keytar'; import {PluginManager} from './plugins/PluginManager'; import {runHealthcheck, getHealthChecks} from './utils/runHealthchecks'; +import {openFile} from './utils/openFile'; /** * FlipperServer takes care of all incoming device & client connections. @@ -272,6 +273,7 @@ export class FlipperServerImpl implements FlipperServer { 'plugin-source': (path) => this.pluginManager.loadSource(path), 'doctor-get-healthchecks': getHealthChecks, 'doctor-run-healthcheck': runHealthcheck, + 'open-file': openFile, }; registerDevice(device: ServerDevice) { diff --git a/desktop/flipper-server-core/src/utils/openFile.tsx b/desktop/flipper-server-core/src/utils/openFile.tsx new file mode 100644 index 000000000..7e71ff5fe --- /dev/null +++ b/desktop/flipper-server-core/src/utils/openFile.tsx @@ -0,0 +1,32 @@ +/** + * 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 fs from 'fs-extra'; +import open from 'open'; + +export async function openFile(path: string | null) { + if (!path) { + return; + } + + let fileStat; + try { + fileStat = await fs.stat(path); + } catch (err) { + throw new Error(`Couldn't open file: ${path}: ${err}`); + } + + // Rather randomly chosen. Some FSs still reserve 8 bytes for empty files. + // If this doesn't reliably catch "corrupt" files, you might want to increase this. + if (fileStat.size <= 8) { + throw new Error('File seems to be (almost) empty: ' + path); + } + + await open(path); +} diff --git a/desktop/flipper-ui-core/package.json b/desktop/flipper-ui-core/package.json index de9416d5b..f6f325559 100644 --- a/desktop/flipper-ui-core/package.json +++ b/desktop/flipper-ui-core/package.json @@ -39,7 +39,6 @@ "js-base64": "^3.7.2", "lodash": "^4.17.21", "lodash.memoize": "^4.1.2", - "open": "^8.4.0", "openssl-wrapper": "^0.3.4", "p-filter": "^2.1.0", "p-map": "^4.0.0", diff --git a/desktop/flipper-ui-core/src/chrome/ScreenCaptureButtons.tsx b/desktop/flipper-ui-core/src/chrome/ScreenCaptureButtons.tsx index 3ba3c4333..db303421e 100644 --- a/desktop/flipper-ui-core/src/chrome/ScreenCaptureButtons.tsx +++ b/desktop/flipper-ui-core/src/chrome/ScreenCaptureButtons.tsx @@ -10,40 +10,13 @@ import {Button as AntButton, message} from 'antd'; import React, {useState, useEffect, useCallback} from 'react'; import path from 'path'; -import fs from 'fs-extra'; -import open from 'open'; import {capture, getCaptureLocation, getFileName} from '../utils/screenshot'; import {CameraOutlined, VideoCameraOutlined} from '@ant-design/icons'; import {useStore} from '../utils/useStore'; +import {getRenderHostInstance} from '../RenderHost'; -async function openFile(path: string | null) { - if (!path) { - return; - } - - let fileStat; - try { - fileStat = await fs.stat(path); - } catch (err) { - message.error(`Couldn't open captured file: ${path}: ${err}`); - return; - } - - // Rather randomly chosen. Some FSs still reserve 8 bytes for empty files. - // If this doesn't reliably catch "corrupt" files, you might want to increase this. - if (fileStat.size <= 8) { - message.error( - 'Screencap file retrieved from device appears to be corrupt. Your device may not support screen recording. Sometimes restarting your device can help.', - 0, - ); - return; - } - - try { - await open(path); - } catch (e) { - console.warn(`Opening ${path} failed with error ${e}.`); - } +async function openFile(path: string) { + getRenderHostInstance().flipperServer.exec('open-file', path); } export default function ScreenCaptureButtons() { @@ -92,7 +65,11 @@ export default function ScreenCaptureButtons() { } else { return selectedDevice .stopScreenCapture() - .then(openFile) + .then((f) => { + if (f) { + return openFile(f); + } + }) .catch((e) => { console.error('Failed to start recording', e); message.error('Failed to start recording' + e); diff --git a/desktop/flipper-ui-core/src/dispatcher/application.tsx b/desktop/flipper-ui-core/src/dispatcher/application.tsx index f860e7c2a..96b462aca 100644 --- a/desktop/flipper-ui-core/src/dispatcher/application.tsx +++ b/desktop/flipper-ui-core/src/dispatcher/application.tsx @@ -22,20 +22,20 @@ export default (store: Store, logger: Logger) => { const renderHost = getRenderHostInstance(); const onFocus = () => { - setImmediate(() => { + setTimeout(() => { store.dispatch({ type: 'windowIsFocused', payload: {isFocused: true, time: Date.now()}, }); - }); + }, 1); }; const onBlur = () => { - setImmediate(() => { + setTimeout(() => { store.dispatch({ type: 'windowIsFocused', payload: {isFocused: false, time: Date.now()}, }); - }); + }, 1); }; window.addEventListener('focus', onFocus); window.addEventListener('blur', onBlur); diff --git a/desktop/flipper-ui-core/src/sandy-chrome/SandyApp.tsx b/desktop/flipper-ui-core/src/sandy-chrome/SandyApp.tsx index 1f3ac8823..9f1b32d5d 100644 --- a/desktop/flipper-ui-core/src/sandy-chrome/SandyApp.tsx +++ b/desktop/flipper-ui-core/src/sandy-chrome/SandyApp.tsx @@ -235,8 +235,7 @@ RootElement.displayName = 'SandyAppRootElement'; function registerStartupTime(logger: Logger) { // track time since launch - const [s, ns] = process.hrtime(); - const launchEndTime = s * 1e3 + ns / 1e6; + const launchEndTime = performance.now(); const renderHost = getRenderHostInstance(); renderHost.onIpcEvent('getLaunchTime', (launchStartTime: number) => { logger.track('performance', 'launchTime', launchEndTime - launchStartTime); diff --git a/desktop/static/index.web.dev.html b/desktop/static/index.web.dev.html index 49abfe4f0..1be12bf67 100644 --- a/desktop/static/index.web.dev.html +++ b/desktop/static/index.web.dev.html @@ -38,7 +38,7 @@ font-family: monospace; font-size: 12px; z-index: 10; - top: 0; + bottom: 0; left: 0; position: absolute; } @@ -63,12 +63,10 @@ (function() { // FIXME: needed to make Metro work window.global = window; - // global.electronRequire = function(path) { - // // debugger; - // // throw(new Error("Tried to require: " + path)); - // console.error("Tried to require " + path); - // return {}; - // }; + global.electronRequire = function(path) { + console.error("[decapitate] Tried to electronRequire: " + path); + return {}; + }; let suppressErrors = false; diff --git a/desktop/static/main.ts b/desktop/static/main.ts index b77b2030c..0badb7021 100644 --- a/desktop/static/main.ts +++ b/desktop/static/main.ts @@ -7,9 +7,10 @@ * @format */ -const [s, ns] = process.hrtime(); -let launchStartTime: number | undefined = s * 1e3 + ns / 1e6; +import {performance} from 'perf_hooks'; +let launchStartTime: number | undefined = performance.now(); +// eslint-disable-next-line no-restricted-imports import { app, BrowserWindow, diff --git a/desktop/yarn.lock b/desktop/yarn.lock index 8bae2302d..07eca7d35 100644 --- a/desktop/yarn.lock +++ b/desktop/yarn.lock @@ -10207,7 +10207,7 @@ open@^7.4.2: is-docker "^2.0.0" is-wsl "^2.1.1" -open@^8.4.0: +open@^8.3.0: version "8.4.0" resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==