Refactor Stella plugin
Summary: 1. Replace old FileSelector with the new FileSelector 2. Remove showOpenDialog from FlipperLib Reviewed By: mweststrate Differential Revision: D32667103 fbshipit-source-id: be8da034c2695f83b397b6c7d35bc6aee78d66e5
This commit is contained in:
committed by
Facebook GitHub Bot
parent
b82c41eedd
commit
225a2a7e34
@@ -144,6 +144,7 @@ export function initializeElectron() {
|
|||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
name: fileName,
|
name: fileName,
|
||||||
|
path: filePath,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -43,17 +43,6 @@ export interface FlipperLib {
|
|||||||
DetailsSidebarImplementation?(
|
DetailsSidebarImplementation?(
|
||||||
props: DetailSidebarProps,
|
props: DetailSidebarProps,
|
||||||
): React.ReactElement | null;
|
): React.ReactElement | null;
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* Will be removed in subsequent commits
|
|
||||||
*/
|
|
||||||
showOpenDialog?(options: {
|
|
||||||
defaultPath?: string;
|
|
||||||
filter?: {
|
|
||||||
extensions: string[];
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
}): Promise<string | undefined>;
|
|
||||||
/**
|
/**
|
||||||
* @returns
|
* @returns
|
||||||
* Imported file data.
|
* Imported file data.
|
||||||
|
|||||||
@@ -16,10 +16,9 @@ import {
|
|||||||
LoadingIndicator,
|
LoadingIndicator,
|
||||||
} from '../../ui';
|
} from '../../ui';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import {default as FileSelector} from '../../ui/components/FileSelector';
|
|
||||||
import React, {useState} from 'react';
|
import React, {useState} from 'react';
|
||||||
import {installPluginFromFile} from 'flipper-plugin-lib';
|
import {installPluginFromFile} from 'flipper-plugin-lib';
|
||||||
import {Toolbar} from 'flipper-plugin';
|
import {Toolbar, FileSelector} from 'flipper-plugin';
|
||||||
|
|
||||||
const CenteredGlyph = styled(Glyph)({
|
const CenteredGlyph = styled(Glyph)({
|
||||||
margin: 'auto',
|
margin: 'auto',
|
||||||
@@ -80,10 +79,16 @@ export default function PluginPackageInstaller({
|
|||||||
return (
|
return (
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<FileSelector
|
<FileSelector
|
||||||
placeholderText="Specify path to a Flipper package or just drag and drop it here..."
|
label="Select a Flipper package or just drag and drop it here..."
|
||||||
onPathChanged={(e) => {
|
onChange={(newFile) => {
|
||||||
setPath(e.path);
|
if (newFile) {
|
||||||
setIsPathValid(e.isValid);
|
// TODO: Fix me before implementing Browser Flipper. "path" is only availbale in Electron!
|
||||||
|
setPath(newFile.path!);
|
||||||
|
setIsPathValid(true);
|
||||||
|
} else {
|
||||||
|
setPath('');
|
||||||
|
setIsPathValid(false);
|
||||||
|
}
|
||||||
setError(undefined);
|
setError(undefined);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -275,38 +275,80 @@ exports[`load PluginInstaller list 1`] = `
|
|||||||
class="css-1lxv8hi-Container-Horizontal-SandyToolbarContainer e1ecpah20"
|
class="css-1lxv8hi-Container-Horizontal-SandyToolbarContainer e1ecpah20"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="css-1spj5hr-View-FlexBox-FlexRow-Container ev83mp62"
|
class="ant-row ant-row-no-wrap ant-row-middle"
|
||||||
|
style="margin-left: -4px; margin-right: -4px;"
|
||||||
>
|
>
|
||||||
<input
|
|
||||||
class="css-sli06x-Input-FileInputBox ev83mp60"
|
|
||||||
placeholder="Specify path to a Flipper package or just drag and drop it here..."
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<div
|
<div
|
||||||
class="css-ccdckn-View-FlexBox-FlexRow-GlyphContainer ev83mp61"
|
class="ant-col"
|
||||||
|
style="padding-left: 4px; padding-right: 4px; flex-basis: auto; min-width: 0;"
|
||||||
>
|
>
|
||||||
<img
|
<input
|
||||||
alt="dots-3-circle"
|
class="ant-input"
|
||||||
class="ev83mp63 css-6iptsk-ColoredIconBlack-CenteredGlyph ekc8qeh1"
|
placeholder="Select a Flipper package or just drag and drop it here..."
|
||||||
size="16"
|
type="text"
|
||||||
src="https://facebook.com/assets/?name=dots-3-circle&variant=outline&size=16&set=facebook_icons&density=1x"
|
value=""
|
||||||
title="Open file selection dialog"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="css-ccdckn-View-FlexBox-FlexRow-GlyphContainer ev83mp61"
|
class="ant-col"
|
||||||
|
style="padding-left: 4px; padding-right: 4px; flex: 0 0 auto;"
|
||||||
>
|
>
|
||||||
<div
|
<button
|
||||||
class="css-auhar3-TooltipContainer e1m67rki0"
|
class="ant-btn ant-btn-icon-only"
|
||||||
|
disabled=""
|
||||||
|
title="Reset"
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
<div
|
<span
|
||||||
class="ev83mp63 css-1qsl9s4-ColoredIconCustom-CenteredGlyph ekc8qeh0"
|
aria-label="close"
|
||||||
color="#D79651"
|
class="anticon anticon-close"
|
||||||
size="16"
|
role="img"
|
||||||
src="https://facebook.com/assets/?name=caution-triangle&variant=filled&size=16&set=facebook_icons&density=1x"
|
>
|
||||||
/>
|
<svg
|
||||||
</div>
|
aria-hidden="true"
|
||||||
|
data-icon="close"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-col"
|
||||||
|
style="padding-left: 4px; padding-right: 4px; flex: 0 0 auto;"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-btn-icon-only"
|
||||||
|
title="Select a Flipper package or just drag and drop it here..."
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="upload"
|
||||||
|
class="anticon anticon-upload"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="upload"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M400 317.7h73.9V656c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V317.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 163a8 8 0 00-12.6 0l-112 141.7c-4.1 5.3-.4 13 6.3 13zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -609,38 +651,80 @@ exports[`load PluginInstaller list with one plugin installed 1`] = `
|
|||||||
class="css-1lxv8hi-Container-Horizontal-SandyToolbarContainer e1ecpah20"
|
class="css-1lxv8hi-Container-Horizontal-SandyToolbarContainer e1ecpah20"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="css-1spj5hr-View-FlexBox-FlexRow-Container ev83mp62"
|
class="ant-row ant-row-no-wrap ant-row-middle"
|
||||||
|
style="margin-left: -4px; margin-right: -4px;"
|
||||||
>
|
>
|
||||||
<input
|
|
||||||
class="css-sli06x-Input-FileInputBox ev83mp60"
|
|
||||||
placeholder="Specify path to a Flipper package or just drag and drop it here..."
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<div
|
<div
|
||||||
class="css-ccdckn-View-FlexBox-FlexRow-GlyphContainer ev83mp61"
|
class="ant-col"
|
||||||
|
style="padding-left: 4px; padding-right: 4px; flex-basis: auto; min-width: 0;"
|
||||||
>
|
>
|
||||||
<img
|
<input
|
||||||
alt="dots-3-circle"
|
class="ant-input"
|
||||||
class="ev83mp63 css-6iptsk-ColoredIconBlack-CenteredGlyph ekc8qeh1"
|
placeholder="Select a Flipper package or just drag and drop it here..."
|
||||||
size="16"
|
type="text"
|
||||||
src="https://facebook.com/assets/?name=dots-3-circle&variant=outline&size=16&set=facebook_icons&density=1x"
|
value=""
|
||||||
title="Open file selection dialog"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="css-ccdckn-View-FlexBox-FlexRow-GlyphContainer ev83mp61"
|
class="ant-col"
|
||||||
|
style="padding-left: 4px; padding-right: 4px; flex: 0 0 auto;"
|
||||||
>
|
>
|
||||||
<div
|
<button
|
||||||
class="css-auhar3-TooltipContainer e1m67rki0"
|
class="ant-btn ant-btn-icon-only"
|
||||||
|
disabled=""
|
||||||
|
title="Reset"
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
<div
|
<span
|
||||||
class="ev83mp63 css-1qsl9s4-ColoredIconCustom-CenteredGlyph ekc8qeh0"
|
aria-label="close"
|
||||||
color="#D79651"
|
class="anticon anticon-close"
|
||||||
size="16"
|
role="img"
|
||||||
src="https://facebook.com/assets/?name=caution-triangle&variant=filled&size=16&set=facebook_icons&density=1x"
|
>
|
||||||
/>
|
<svg
|
||||||
</div>
|
aria-hidden="true"
|
||||||
|
data-icon="close"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-col"
|
||||||
|
style="padding-left: 4px; padding-right: 4px; flex: 0 0 auto;"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-btn-icon-only"
|
||||||
|
title="Select a Flipper package or just drag and drop it here..."
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="upload"
|
||||||
|
class="anticon anticon-upload"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="upload"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M400 317.7h73.9V656c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V317.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 163a8 8 0 00-12.6 0l-112 141.7c-4.1 5.3-.4 13 6.3 13zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ export {
|
|||||||
} from 'flipper-plugin';
|
} from 'flipper-plugin';
|
||||||
export {ElementFramework} from './ui/components/elements-inspector/ElementFramework';
|
export {ElementFramework} from './ui/components/elements-inspector/ElementFramework';
|
||||||
export {InspectorSidebar} from './ui/components/elements-inspector/sidebar';
|
export {InspectorSidebar} from './ui/components/elements-inspector/sidebar';
|
||||||
export {default as FileSelector} from './ui/components/FileSelector';
|
|
||||||
export {getFlipperMediaCDN, appendAccessTokenToUrl} from './fb-stubs/user';
|
export {getFlipperMediaCDN, appendAccessTokenToUrl} from './fb-stubs/user';
|
||||||
export {Rect} from './utils/geometry';
|
export {Rect} from './utils/geometry';
|
||||||
export {Logger} from 'flipper-common';
|
export {Logger} from 'flipper-common';
|
||||||
|
|||||||
@@ -1,121 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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, {useState} from 'react';
|
|
||||||
import FlexRow from './FlexRow';
|
|
||||||
import Glyph from './Glyph';
|
|
||||||
import Input from './Input';
|
|
||||||
import styled from '@emotion/styled';
|
|
||||||
import {colors} from './colors';
|
|
||||||
import fs from 'fs';
|
|
||||||
import {Tooltip} from '..';
|
|
||||||
import {getFlipperLib} from 'flipper-plugin';
|
|
||||||
|
|
||||||
const CenteredGlyph = styled(Glyph)({
|
|
||||||
margin: 'auto',
|
|
||||||
marginLeft: 4,
|
|
||||||
});
|
|
||||||
|
|
||||||
const Container = styled(FlexRow)({
|
|
||||||
width: '100%',
|
|
||||||
marginRight: 4,
|
|
||||||
});
|
|
||||||
|
|
||||||
const GlyphContainer = styled(FlexRow)({
|
|
||||||
width: 20,
|
|
||||||
});
|
|
||||||
|
|
||||||
const FileInputBox = styled(Input)<{isValid: boolean}>(({isValid}) => ({
|
|
||||||
flexGrow: 1,
|
|
||||||
color: isValid ? undefined : colors.red,
|
|
||||||
'&::-webkit-input-placeholder': {
|
|
||||||
color: colors.placeholder,
|
|
||||||
fontWeight: 300,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
onPathChanged: (evtArgs: {path: string; isValid: boolean}) => void;
|
|
||||||
placeholderText: string;
|
|
||||||
defaultPath: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultProps: Props = {
|
|
||||||
onPathChanged: (_) => {},
|
|
||||||
placeholderText: '',
|
|
||||||
defaultPath: '/',
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Should we render null in browsers for FileSelector?
|
|
||||||
// Do we even need it after decapitation? Every plugin should be using FlipperLib.exportFile which shows a save dialog every time.
|
|
||||||
export default function FileSelector({
|
|
||||||
onPathChanged,
|
|
||||||
placeholderText,
|
|
||||||
defaultPath,
|
|
||||||
}: Props) {
|
|
||||||
const [value, setValue] = useState('');
|
|
||||||
const [isValid, setIsValid] = useState(false);
|
|
||||||
const onChange = (path: string) => {
|
|
||||||
setValue(path);
|
|
||||||
let isNewPathValid = false;
|
|
||||||
try {
|
|
||||||
isNewPathValid = fs.statSync(path).isFile();
|
|
||||||
} catch {
|
|
||||||
isNewPathValid = false;
|
|
||||||
}
|
|
||||||
setIsValid(isNewPathValid);
|
|
||||||
onPathChanged({path, isValid: isNewPathValid});
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<Container>
|
|
||||||
<FileInputBox
|
|
||||||
placeholder={placeholderText}
|
|
||||||
value={value}
|
|
||||||
isValid
|
|
||||||
onDrop={(e) => {
|
|
||||||
if (e.dataTransfer.files.length) {
|
|
||||||
onChange(e.dataTransfer.files[0].path);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onChange={(e) => {
|
|
||||||
onChange(e.target.value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<GlyphContainer
|
|
||||||
onClick={() =>
|
|
||||||
getFlipperLib()
|
|
||||||
.showOpenDialog?.({defaultPath})
|
|
||||||
.then((path) => {
|
|
||||||
if (path) {
|
|
||||||
onChange(path);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}>
|
|
||||||
<CenteredGlyph
|
|
||||||
name="dots-3-circle"
|
|
||||||
variant="outline"
|
|
||||||
title="Open file selection dialog"
|
|
||||||
/>
|
|
||||||
</GlyphContainer>
|
|
||||||
<GlyphContainer>
|
|
||||||
{isValid ? null : (
|
|
||||||
<Tooltip title="The specified path is invalid or such file does not exist">
|
|
||||||
<CenteredGlyph
|
|
||||||
name="caution-triangle"
|
|
||||||
color={colors.yellow}
|
|
||||||
size={16}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
</GlyphContainer>
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileSelector.defaultProps = defaultProps;
|
|
||||||
@@ -62,7 +62,6 @@ export function initializeFlipperLibImplementation(
|
|||||||
DetailsSidebarImplementation: DetailSidebarImpl,
|
DetailsSidebarImplementation: DetailSidebarImpl,
|
||||||
importFile: renderHost.importFile,
|
importFile: renderHost.importFile,
|
||||||
exportFile: renderHost.exportFile,
|
exportFile: renderHost.exportFile,
|
||||||
showOpenDialog: renderHost.showOpenDialog,
|
|
||||||
paths: {
|
paths: {
|
||||||
appPath: renderHost.paths.appPath,
|
appPath: renderHost.paths.appPath,
|
||||||
homePath: renderHost.paths.homePath,
|
homePath: renderHost.paths.homePath,
|
||||||
|
|||||||
@@ -38,3 +38,18 @@ afterEach(cleanup);
|
|||||||
console.debug = function () {
|
console.debug = function () {
|
||||||
// Intentional noop, we don't want debug statements in Jest runs
|
// Intentional noop, we don't want debug statements in Jest runs
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
|
||||||
|
Object.defineProperty(window, 'matchMedia', {
|
||||||
|
writable: true,
|
||||||
|
value: jest.fn().mockImplementation((query) => ({
|
||||||
|
matches: false,
|
||||||
|
media: query,
|
||||||
|
onchange: null,
|
||||||
|
addListener: jest.fn(), // deprecated
|
||||||
|
removeListener: jest.fn(), // deprecated
|
||||||
|
addEventListener: jest.fn(),
|
||||||
|
removeEventListener: jest.fn(),
|
||||||
|
dispatchEvent: jest.fn(),
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user