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
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f5f9608098
commit
eab4f0d3d3
@@ -189,6 +189,7 @@ export type FlipperServerCommands = {
|
|||||||
category: keyof FlipperDoctor.Healthchecks,
|
category: keyof FlipperDoctor.Healthchecks,
|
||||||
name: string,
|
name: string,
|
||||||
) => Promise<FlipperDoctor.HealthcheckResult>;
|
) => Promise<FlipperDoctor.HealthcheckResult>;
|
||||||
|
'open-file': (path: string) => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"invariant": "^2.2.4",
|
"invariant": "^2.2.4",
|
||||||
"js-base64": "^3.7.2",
|
"js-base64": "^3.7.2",
|
||||||
"lodash.memoize": "^4.1.2",
|
"lodash.memoize": "^4.1.2",
|
||||||
|
"open": "^8.3.0",
|
||||||
"openssl-wrapper": "^0.3.4",
|
"openssl-wrapper": "^0.3.4",
|
||||||
"promisify-child-process": "^4.1.1",
|
"promisify-child-process": "^4.1.1",
|
||||||
"rsocket-core": "^0.0.27",
|
"rsocket-core": "^0.0.27",
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import {saveLauncherSettings} from './utils/launcherSettings';
|
|||||||
import {KeytarManager} from './utils/keytar';
|
import {KeytarManager} from './utils/keytar';
|
||||||
import {PluginManager} from './plugins/PluginManager';
|
import {PluginManager} from './plugins/PluginManager';
|
||||||
import {runHealthcheck, getHealthChecks} from './utils/runHealthchecks';
|
import {runHealthcheck, getHealthChecks} from './utils/runHealthchecks';
|
||||||
|
import {openFile} from './utils/openFile';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FlipperServer takes care of all incoming device & client connections.
|
* 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),
|
'plugin-source': (path) => this.pluginManager.loadSource(path),
|
||||||
'doctor-get-healthchecks': getHealthChecks,
|
'doctor-get-healthchecks': getHealthChecks,
|
||||||
'doctor-run-healthcheck': runHealthcheck,
|
'doctor-run-healthcheck': runHealthcheck,
|
||||||
|
'open-file': openFile,
|
||||||
};
|
};
|
||||||
|
|
||||||
registerDevice(device: ServerDevice) {
|
registerDevice(device: ServerDevice) {
|
||||||
|
|||||||
32
desktop/flipper-server-core/src/utils/openFile.tsx
Normal file
32
desktop/flipper-server-core/src/utils/openFile.tsx
Normal file
@@ -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);
|
||||||
|
}
|
||||||
@@ -39,7 +39,6 @@
|
|||||||
"js-base64": "^3.7.2",
|
"js-base64": "^3.7.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"lodash.memoize": "^4.1.2",
|
"lodash.memoize": "^4.1.2",
|
||||||
"open": "^8.4.0",
|
|
||||||
"openssl-wrapper": "^0.3.4",
|
"openssl-wrapper": "^0.3.4",
|
||||||
"p-filter": "^2.1.0",
|
"p-filter": "^2.1.0",
|
||||||
"p-map": "^4.0.0",
|
"p-map": "^4.0.0",
|
||||||
|
|||||||
@@ -10,40 +10,13 @@
|
|||||||
import {Button as AntButton, message} from 'antd';
|
import {Button as AntButton, message} from 'antd';
|
||||||
import React, {useState, useEffect, useCallback} from 'react';
|
import React, {useState, useEffect, useCallback} from 'react';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
|
||||||
import open from 'open';
|
|
||||||
import {capture, getCaptureLocation, getFileName} from '../utils/screenshot';
|
import {capture, getCaptureLocation, getFileName} from '../utils/screenshot';
|
||||||
import {CameraOutlined, VideoCameraOutlined} from '@ant-design/icons';
|
import {CameraOutlined, VideoCameraOutlined} from '@ant-design/icons';
|
||||||
import {useStore} from '../utils/useStore';
|
import {useStore} from '../utils/useStore';
|
||||||
|
import {getRenderHostInstance} from '../RenderHost';
|
||||||
|
|
||||||
async function openFile(path: string | null) {
|
async function openFile(path: string) {
|
||||||
if (!path) {
|
getRenderHostInstance().flipperServer.exec('open-file', 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}.`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ScreenCaptureButtons() {
|
export default function ScreenCaptureButtons() {
|
||||||
@@ -92,7 +65,11 @@ export default function ScreenCaptureButtons() {
|
|||||||
} else {
|
} else {
|
||||||
return selectedDevice
|
return selectedDevice
|
||||||
.stopScreenCapture()
|
.stopScreenCapture()
|
||||||
.then(openFile)
|
.then((f) => {
|
||||||
|
if (f) {
|
||||||
|
return openFile(f);
|
||||||
|
}
|
||||||
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error('Failed to start recording', e);
|
console.error('Failed to start recording', e);
|
||||||
message.error('Failed to start recording' + e);
|
message.error('Failed to start recording' + e);
|
||||||
|
|||||||
@@ -22,20 +22,20 @@ export default (store: Store, logger: Logger) => {
|
|||||||
const renderHost = getRenderHostInstance();
|
const renderHost = getRenderHostInstance();
|
||||||
|
|
||||||
const onFocus = () => {
|
const onFocus = () => {
|
||||||
setImmediate(() => {
|
setTimeout(() => {
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: 'windowIsFocused',
|
type: 'windowIsFocused',
|
||||||
payload: {isFocused: true, time: Date.now()},
|
payload: {isFocused: true, time: Date.now()},
|
||||||
});
|
});
|
||||||
});
|
}, 1);
|
||||||
};
|
};
|
||||||
const onBlur = () => {
|
const onBlur = () => {
|
||||||
setImmediate(() => {
|
setTimeout(() => {
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: 'windowIsFocused',
|
type: 'windowIsFocused',
|
||||||
payload: {isFocused: false, time: Date.now()},
|
payload: {isFocused: false, time: Date.now()},
|
||||||
});
|
});
|
||||||
});
|
}, 1);
|
||||||
};
|
};
|
||||||
window.addEventListener('focus', onFocus);
|
window.addEventListener('focus', onFocus);
|
||||||
window.addEventListener('blur', onBlur);
|
window.addEventListener('blur', onBlur);
|
||||||
|
|||||||
@@ -235,8 +235,7 @@ RootElement.displayName = 'SandyAppRootElement';
|
|||||||
|
|
||||||
function registerStartupTime(logger: Logger) {
|
function registerStartupTime(logger: Logger) {
|
||||||
// track time since launch
|
// track time since launch
|
||||||
const [s, ns] = process.hrtime();
|
const launchEndTime = performance.now();
|
||||||
const launchEndTime = s * 1e3 + ns / 1e6;
|
|
||||||
const renderHost = getRenderHostInstance();
|
const renderHost = getRenderHostInstance();
|
||||||
renderHost.onIpcEvent('getLaunchTime', (launchStartTime: number) => {
|
renderHost.onIpcEvent('getLaunchTime', (launchStartTime: number) => {
|
||||||
logger.track('performance', 'launchTime', launchEndTime - launchStartTime);
|
logger.track('performance', 'launchTime', launchEndTime - launchStartTime);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
top: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
@@ -63,12 +63,10 @@
|
|||||||
(function() {
|
(function() {
|
||||||
// FIXME: needed to make Metro work
|
// FIXME: needed to make Metro work
|
||||||
window.global = window;
|
window.global = window;
|
||||||
// global.electronRequire = function(path) {
|
global.electronRequire = function(path) {
|
||||||
// // debugger;
|
console.error("[decapitate] Tried to electronRequire: " + path);
|
||||||
// // throw(new Error("Tried to require: " + path));
|
return {};
|
||||||
// console.error("Tried to require " + path);
|
};
|
||||||
// return {};
|
|
||||||
// };
|
|
||||||
|
|
||||||
let suppressErrors = false;
|
let suppressErrors = false;
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,10 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const [s, ns] = process.hrtime();
|
import {performance} from 'perf_hooks';
|
||||||
let launchStartTime: number | undefined = s * 1e3 + ns / 1e6;
|
let launchStartTime: number | undefined = performance.now();
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import {
|
import {
|
||||||
app,
|
app,
|
||||||
BrowserWindow,
|
BrowserWindow,
|
||||||
|
|||||||
@@ -10207,7 +10207,7 @@ open@^7.4.2:
|
|||||||
is-docker "^2.0.0"
|
is-docker "^2.0.0"
|
||||||
is-wsl "^2.1.1"
|
is-wsl "^2.1.1"
|
||||||
|
|
||||||
open@^8.4.0:
|
open@^8.3.0:
|
||||||
version "8.4.0"
|
version "8.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8"
|
resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8"
|
||||||
integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==
|
integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==
|
||||||
|
|||||||
Reference in New Issue
Block a user