Make getFlipperLib generally available, and use it to decouple opening links from Electron
Summary: This stack reduces our direct dependency on Electron, for example by exposing our own API to open links. Also exposing `getFlipperLib` as API from `flipper-plugin`, so that these utility methods are available outside plugin contexts as well. Reviewed By: timur-valiev Differential Revision: D29661689 fbshipit-source-id: 0c0523326eeb0d9d8fbe3e03c4609327bb53596b
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2b236c6114
commit
5dbd3bd414
@@ -26,11 +26,7 @@ import {processMessagesLater} from './utils/messageQueue';
|
|||||||
import {emitBytesReceived} from './dispatcher/tracking';
|
import {emitBytesReceived} from './dispatcher/tracking';
|
||||||
import {debounce} from 'lodash';
|
import {debounce} from 'lodash';
|
||||||
import {batch} from 'react-redux';
|
import {batch} from 'react-redux';
|
||||||
import {
|
import {createState, _SandyPluginInstance, getFlipperLib} from 'flipper-plugin';
|
||||||
createState,
|
|
||||||
_SandyPluginInstance,
|
|
||||||
_getFlipperLibImplementation,
|
|
||||||
} from 'flipper-plugin';
|
|
||||||
import {freeze} from 'immer';
|
import {freeze} from 'immer';
|
||||||
import GK from './fb-stubs/GK';
|
import GK from './fb-stubs/GK';
|
||||||
import {message} from 'antd';
|
import {message} from 'antd';
|
||||||
@@ -224,7 +220,7 @@ export default class Client extends EventEmitter {
|
|||||||
this.sandyPluginStates.set(
|
this.sandyPluginStates.set(
|
||||||
plugin.id,
|
plugin.id,
|
||||||
new _SandyPluginInstance(
|
new _SandyPluginInstance(
|
||||||
_getFlipperLibImplementation(),
|
getFlipperLib(),
|
||||||
plugin,
|
plugin,
|
||||||
this,
|
this,
|
||||||
getPluginKey(this.id, {serial: this.query.device_id}, plugin.id),
|
getPluginKey(this.id, {serial: this.query.device_id}, plugin.id),
|
||||||
@@ -260,7 +256,7 @@ export default class Client extends EventEmitter {
|
|||||||
this.sandyPluginStates.set(
|
this.sandyPluginStates.set(
|
||||||
plugin.id,
|
plugin.id,
|
||||||
new _SandyPluginInstance(
|
new _SandyPluginInstance(
|
||||||
_getFlipperLibImplementation(),
|
getFlipperLib(),
|
||||||
plugin,
|
plugin,
|
||||||
this,
|
this,
|
||||||
getPluginKey(this.id, {serial: this.query.device_id}, plugin.id),
|
getPluginKey(this.id, {serial: this.query.device_id}, plugin.id),
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import {
|
|||||||
NormalizedMenuEntry,
|
NormalizedMenuEntry,
|
||||||
_buildInMenuEntries,
|
_buildInMenuEntries,
|
||||||
_wrapInteractionHandler,
|
_wrapInteractionHandler,
|
||||||
|
getFlipperLib,
|
||||||
} from 'flipper-plugin';
|
} from 'flipper-plugin';
|
||||||
import {StyleGuide} from './sandy-chrome/StyleGuide';
|
import {StyleGuide} from './sandy-chrome/StyleGuide';
|
||||||
import {showEmulatorLauncher} from './sandy-chrome/appinspect/LaunchEmulator';
|
import {showEmulatorLauncher} from './sandy-chrome/appinspect/LaunchEmulator';
|
||||||
@@ -373,19 +374,21 @@ function getTemplate(
|
|||||||
{
|
{
|
||||||
label: 'Getting started',
|
label: 'Getting started',
|
||||||
click: function () {
|
click: function () {
|
||||||
shell.openExternal('https://fbflipper.com/docs/getting-started/index');
|
getFlipperLib().openLink(
|
||||||
|
'https://fbflipper.com/docs/getting-started/index',
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Create plugins',
|
label: 'Create plugins',
|
||||||
click: function () {
|
click: function () {
|
||||||
shell.openExternal('https://fbflipper.com/docs/tutorial/intro');
|
getFlipperLib().openLink('https://fbflipper.com/docs/tutorial/intro');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Report problems',
|
label: 'Report problems',
|
||||||
click: function () {
|
click: function () {
|
||||||
shell.openExternal(constants.FEEDBACK_GROUP_LINK);
|
getFlipperLib().openLink(constants.FEEDBACK_GROUP_LINK);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import {
|
|||||||
import {PluginDefinition, DevicePluginMap, ClientPluginMap} from './plugin';
|
import {PluginDefinition, DevicePluginMap, ClientPluginMap} from './plugin';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import React, {Component, Fragment} from 'react';
|
import React, {Component, Fragment} from 'react';
|
||||||
import {clipboard} from 'electron';
|
|
||||||
import {
|
import {
|
||||||
PluginNotification,
|
PluginNotification,
|
||||||
updatePluginBlocklist,
|
updatePluginBlocklist,
|
||||||
@@ -35,6 +34,7 @@ import {State as StoreState} from './reducers/index';
|
|||||||
import textContent from './utils/textContent';
|
import textContent from './utils/textContent';
|
||||||
import createPaste from './fb-stubs/createPaste';
|
import createPaste from './fb-stubs/createPaste';
|
||||||
import {getPluginTitle} from './utils/pluginUtils';
|
import {getPluginTitle} from './utils/pluginUtils';
|
||||||
|
import {getFlipperLib} from 'flipper-plugin';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
onClear: () => void;
|
onClear: () => void;
|
||||||
@@ -459,7 +459,7 @@ class NotificationItem extends Component<
|
|||||||
createPaste(this.getContent());
|
createPaste(this.getContent());
|
||||||
};
|
};
|
||||||
|
|
||||||
copy = () => clipboard.writeText(this.getContent());
|
copy = () => getFlipperLib().writeTextToClipboard(this.getContent());
|
||||||
|
|
||||||
getContent = (): string =>
|
getContent = (): string =>
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import runHealthchecks, {
|
|||||||
HealthcheckSettings,
|
HealthcheckSettings,
|
||||||
HealthcheckEventsHandler,
|
HealthcheckEventsHandler,
|
||||||
} from '../utils/runHealthchecks';
|
} from '../utils/runHealthchecks';
|
||||||
import {shell} from 'electron';
|
import {getFlipperLib} from 'flipper-plugin';
|
||||||
import {reportUsage} from '../utils/metrics';
|
import {reportUsage} from '../utils/metrics';
|
||||||
|
|
||||||
type StateFromProps = {
|
type StateFromProps = {
|
||||||
@@ -295,7 +295,7 @@ class DoctorSheet extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openHelpUrl(helpUrl?: string): void {
|
openHelpUrl(helpUrl?: string): void {
|
||||||
helpUrl && shell.openExternal(helpUrl);
|
helpUrl && getFlipperLib().openLink(helpUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
async runHealthchecks(): Promise<void> {
|
async runHealthchecks(): Promise<void> {
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import {
|
|||||||
EXPORT_FLIPPER_TRACE_EVENT,
|
EXPORT_FLIPPER_TRACE_EVENT,
|
||||||
displayFetchMetadataErrors,
|
displayFetchMetadataErrors,
|
||||||
} from '../utils/exportData';
|
} from '../utils/exportData';
|
||||||
import {clipboard} from 'electron';
|
|
||||||
import ShareSheetErrorList from './ShareSheetErrorList';
|
import ShareSheetErrorList from './ShareSheetErrorList';
|
||||||
import {reportPlatformFailures} from '../utils/metrics';
|
import {reportPlatformFailures} from '../utils/metrics';
|
||||||
import CancellableExportStatus from './CancellableExportStatus';
|
import CancellableExportStatus from './CancellableExportStatus';
|
||||||
@@ -36,6 +35,7 @@ import ShareSheetPendingDialog from './ShareSheetPendingDialog';
|
|||||||
import {getInstance as getLogger} from '../fb-stubs/Logger';
|
import {getInstance as getLogger} from '../fb-stubs/Logger';
|
||||||
import {resetSupportFormV2State} from '../reducers/supportForm';
|
import {resetSupportFormV2State} from '../reducers/supportForm';
|
||||||
import {MiddlewareAPI} from '../reducers/index';
|
import {MiddlewareAPI} from '../reducers/index';
|
||||||
|
import {getFlipperLib} from 'flipper-plugin';
|
||||||
|
|
||||||
export const SHARE_FLIPPER_TRACE_EVENT = 'share-flipper-link';
|
export const SHARE_FLIPPER_TRACE_EVENT = 'share-flipper-link';
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ export default class ShareSheetExportUrl extends Component<Props, State> {
|
|||||||
if (flipperUrl) {
|
if (flipperUrl) {
|
||||||
this.store.dispatch(setExportURL(flipperUrl));
|
this.store.dispatch(setExportURL(flipperUrl));
|
||||||
if (this.state.runInBackground) {
|
if (this.state.runInBackground) {
|
||||||
clipboard.writeText(String(flipperUrl));
|
getFlipperLib().writeTextToClipboard(String(flipperUrl));
|
||||||
new Notification('Shareable Flipper Export created', {
|
new Notification('Shareable Flipper Export created', {
|
||||||
body: 'URL copied to clipboard',
|
body: 'URL copied to clipboard',
|
||||||
requireInteraction: true,
|
requireInteraction: true,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
DeviceLogListener,
|
DeviceLogListener,
|
||||||
Idler,
|
Idler,
|
||||||
createState,
|
createState,
|
||||||
_getFlipperLibImplementation,
|
getFlipperLib,
|
||||||
} from 'flipper-plugin';
|
} from 'flipper-plugin';
|
||||||
import {PluginDefinition, DevicePluginMap} from '../plugin';
|
import {PluginDefinition, DevicePluginMap} from '../plugin';
|
||||||
import {DeviceSpec, OS as PluginOS, PluginDetails} from 'flipper-plugin-lib';
|
import {DeviceSpec, OS as PluginOS, PluginDetails} from 'flipper-plugin-lib';
|
||||||
@@ -245,7 +245,7 @@ export default class BaseDevice {
|
|||||||
this.sandyPluginStates.set(
|
this.sandyPluginStates.set(
|
||||||
plugin.id,
|
plugin.id,
|
||||||
new _SandyDevicePluginInstance(
|
new _SandyDevicePluginInstance(
|
||||||
_getFlipperLibImplementation(),
|
getFlipperLib(),
|
||||||
plugin,
|
plugin,
|
||||||
this,
|
this,
|
||||||
// break circular dep, one of those days again...
|
// break circular dep, one of those days again...
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ import {
|
|||||||
_LoggerContext,
|
_LoggerContext,
|
||||||
Layout,
|
Layout,
|
||||||
theme,
|
theme,
|
||||||
|
getFlipperLib,
|
||||||
} from 'flipper-plugin';
|
} from 'flipper-plugin';
|
||||||
import isProduction from './utils/isProduction';
|
import isProduction from './utils/isProduction';
|
||||||
import {Button, Input, Result, Typography} from 'antd';
|
import {Button, Input, Result, Typography} from 'antd';
|
||||||
import constants from './fb-stubs/constants';
|
import constants from './fb-stubs/constants';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import {CopyOutlined} from '@ant-design/icons';
|
import {CopyOutlined} from '@ant-design/icons';
|
||||||
import {clipboard} from 'electron/common';
|
|
||||||
import {getVersionString} from './utils/versionString';
|
import {getVersionString} from './utils/versionString';
|
||||||
import {PersistGate} from 'redux-persist/integration/react';
|
import {PersistGate} from 'redux-persist/integration/react';
|
||||||
import {ipcRenderer} from 'electron';
|
import {ipcRenderer} from 'electron';
|
||||||
@@ -107,7 +107,7 @@ class AppFrame extends React.Component<
|
|||||||
key="copy_error"
|
key="copy_error"
|
||||||
icon={<CopyOutlined />}
|
icon={<CopyOutlined />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
clipboard.writeText(this.getError());
|
getFlipperLib().writeTextToClipboard(this.getError());
|
||||||
}}>
|
}}>
|
||||||
Copy error
|
Copy error
|
||||||
</Button>,
|
</Button>,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const {Text, Title} = Typography;
|
|||||||
import constants from '../fb-stubs/constants';
|
import constants from '../fb-stubs/constants';
|
||||||
import isProduction from '../utils/isProduction';
|
import isProduction from '../utils/isProduction';
|
||||||
import {getAppVersion} from '../utils/info';
|
import {getAppVersion} from '../utils/info';
|
||||||
import {shell} from 'electron';
|
import {getFlipperLib} from 'flipper-plugin';
|
||||||
|
|
||||||
const RowContainer = styled(FlexRow)({
|
const RowContainer = styled(FlexRow)({
|
||||||
alignItems: 'flex-start',
|
alignItems: 'flex-start',
|
||||||
@@ -89,7 +89,7 @@ function WelcomeFooter({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const openExternal = (url: string) => () => shell && shell.openExternal(url);
|
const openExternal = (url: string) => () => getFlipperLib().openLink(url);
|
||||||
|
|
||||||
export default function WelcomeScreen({
|
export default function WelcomeScreen({
|
||||||
visible,
|
visible,
|
||||||
|
|||||||
@@ -8,14 +8,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {useState, useCallback, useMemo} from 'react';
|
import React, {useState, useCallback, useMemo} from 'react';
|
||||||
import electron, {MenuItemConstructorOptions} from 'electron';
|
import {MenuItemConstructorOptions} from 'electron';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import {Button as AntdButton, Dropdown, Menu} from 'antd';
|
import {Button as AntdButton, Dropdown, Menu} from 'antd';
|
||||||
|
|
||||||
import Glyph, {IconSize} from './Glyph';
|
import Glyph, {IconSize} from './Glyph';
|
||||||
import type {ButtonProps} from 'antd/lib/button';
|
import type {ButtonProps} from 'antd/lib/button';
|
||||||
import {DownOutlined, CheckOutlined} from '@ant-design/icons';
|
import {DownOutlined, CheckOutlined} from '@ant-design/icons';
|
||||||
import {theme} from 'flipper-plugin';
|
import {theme, getFlipperLib} from 'flipper-plugin';
|
||||||
|
|
||||||
type ButtonType = 'primary' | 'success' | 'warning' | 'danger';
|
type ButtonType = 'primary' | 'success' | 'warning' | 'danger';
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ function SandyButton({
|
|||||||
}
|
}
|
||||||
onClick?.(e);
|
onClick?.(e);
|
||||||
if (href != null) {
|
if (href != null) {
|
||||||
electron.shell.openExternal(href); // TODO: decouple from Electron
|
getFlipperLib().openLink(href);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[disabled, onClick, href],
|
[disabled, onClick, href],
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {shell} from 'electron';
|
import {getFlipperLib} from 'flipper-plugin';
|
||||||
import {Typography} from 'antd';
|
import {Typography} from 'antd';
|
||||||
|
|
||||||
const AntOriginalLink = Typography.Link;
|
const AntOriginalLink = Typography.Link;
|
||||||
@@ -15,7 +15,7 @@ const AntOriginalLink = Typography.Link;
|
|||||||
// used by patch for Typography.Link in AntD
|
// used by patch for Typography.Link in AntD
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.flipperOpenLink = function openLinkExternal(url: string) {
|
global.flipperOpenLink = function openLinkExternal(url: string) {
|
||||||
shell.openExternal(url);
|
getFlipperLib().openLink(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AntOriginalLink;
|
export default AntOriginalLink;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import React, {CSSProperties, ReactNode} from 'react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
import {colors} from './colors';
|
import {colors} from './colors';
|
||||||
import {shell} from 'electron';
|
import {getFlipperLib} from 'flipper-plugin';
|
||||||
|
|
||||||
const Container = styled.div({
|
const Container = styled.div({
|
||||||
padding: 10,
|
padding: 10,
|
||||||
@@ -73,7 +73,9 @@ const Link = styled.span({
|
|||||||
});
|
});
|
||||||
function LinkReference(props: {href: string; children: Array<ReactNode>}) {
|
function LinkReference(props: {href: string; children: Array<ReactNode>}) {
|
||||||
return (
|
return (
|
||||||
<Link onClick={() => shell.openExternal(props.href)}>{props.children}</Link>
|
<Link onClick={() => getFlipperLib().openLink(props.href)}>
|
||||||
|
{props.children}
|
||||||
|
</Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import type {Store} from '../reducers';
|
|||||||
import createPaste from '../fb-stubs/createPaste';
|
import createPaste from '../fb-stubs/createPaste';
|
||||||
import GK from '../fb-stubs/GK';
|
import GK from '../fb-stubs/GK';
|
||||||
import type BaseDevice from '../devices/BaseDevice';
|
import type BaseDevice from '../devices/BaseDevice';
|
||||||
import {clipboard} from 'electron';
|
import {clipboard, shell} from 'electron';
|
||||||
import constants from '../fb-stubs/constants';
|
import constants from '../fb-stubs/constants';
|
||||||
import {addNotification} from '../reducers/notifications';
|
import {addNotification} from '../reducers/notifications';
|
||||||
import {deconstructPluginKey} from './clientUtils';
|
import {deconstructPluginKey} from './clientUtils';
|
||||||
@@ -50,6 +50,9 @@ export function initializeFlipperLibImplementation(
|
|||||||
writeTextToClipboard(text: string) {
|
writeTextToClipboard(text: string) {
|
||||||
clipboard.writeText(text);
|
clipboard.writeText(text);
|
||||||
},
|
},
|
||||||
|
openLink(url: string) {
|
||||||
|
shell.openExternal(url);
|
||||||
|
},
|
||||||
showNotification(pluginId, notification) {
|
showNotification(pluginId, notification) {
|
||||||
const parts = deconstructPluginKey(pluginId);
|
const parts = deconstructPluginKey(pluginId);
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
|
|||||||
@@ -7,13 +7,15 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {getFlipperLib} from 'flipper-plugin';
|
||||||
import {getPreferredEditorUriScheme} from '../fb-stubs/user';
|
import {getPreferredEditorUriScheme} from '../fb-stubs/user';
|
||||||
import {shell} from 'electron';
|
|
||||||
|
|
||||||
let preferredEditorUriScheme: string | undefined = undefined;
|
let preferredEditorUriScheme: string | undefined = undefined;
|
||||||
|
|
||||||
export function callVSCode(plugin: string, command: string, params?: string) {
|
export function callVSCode(plugin: string, command: string, params?: string) {
|
||||||
getVSCodeUrl(plugin, command, params).then((url) => shell.openExternal(url));
|
getVSCodeUrl(plugin, command, params).then((url) =>
|
||||||
|
getFlipperLib().openLink(url),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getVSCodeUrl(
|
export async function getVSCodeUrl(
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ test('Correct top level API exposed', () => {
|
|||||||
"createDataSource",
|
"createDataSource",
|
||||||
"createState",
|
"createState",
|
||||||
"createTablePlugin",
|
"createTablePlugin",
|
||||||
|
"getFlipperLib",
|
||||||
"produce",
|
"produce",
|
||||||
"renderReactRoot",
|
"renderReactRoot",
|
||||||
"sleep",
|
"sleep",
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export {createState, useValue, Atom} from './state/atom';
|
|||||||
export {batch} from './state/batch';
|
export {batch} from './state/batch';
|
||||||
export {
|
export {
|
||||||
FlipperLib,
|
FlipperLib,
|
||||||
getFlipperLibImplementation as _getFlipperLibImplementation,
|
getFlipperLib,
|
||||||
setFlipperLibImplementation as _setFlipperLibImplementation,
|
setFlipperLibImplementation as _setFlipperLibImplementation,
|
||||||
} from './plugin/FlipperLib';
|
} from './plugin/FlipperLib';
|
||||||
export {
|
export {
|
||||||
|
|||||||
@@ -30,19 +30,20 @@ export interface FlipperLib {
|
|||||||
deeplink: unknown,
|
deeplink: unknown,
|
||||||
): void;
|
): void;
|
||||||
writeTextToClipboard(text: string): void;
|
writeTextToClipboard(text: string): void;
|
||||||
|
openLink(url: string): void;
|
||||||
showNotification(pluginKey: string, notification: Notification): void;
|
showNotification(pluginKey: string, notification: Notification): void;
|
||||||
DetailsSidebarImplementation?(
|
DetailsSidebarImplementation?(
|
||||||
props: DetailSidebarProps,
|
props: DetailSidebarProps,
|
||||||
): React.ReactElement | null;
|
): React.ReactElement | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let flipperLibInstance: FlipperLib | undefined;
|
export let flipperLibInstance: FlipperLib | undefined;
|
||||||
|
|
||||||
export function tryGetFlipperLibImplementation(): FlipperLib | undefined {
|
export function tryGetFlipperLibImplementation(): FlipperLib | undefined {
|
||||||
return flipperLibInstance;
|
return flipperLibInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFlipperLibImplementation(): FlipperLib {
|
export function getFlipperLib(): FlipperLib {
|
||||||
if (!flipperLibInstance) {
|
if (!flipperLibInstance) {
|
||||||
throw new Error('Flipper lib not instantiated');
|
throw new Error('Flipper lib not instantiated');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -374,6 +374,7 @@ export function createMockFlipperLib(options?: StartPluginOptions): FlipperLib {
|
|||||||
},
|
},
|
||||||
selectPlugin: jest.fn(),
|
selectPlugin: jest.fn(),
|
||||||
writeTextToClipboard: jest.fn(),
|
writeTextToClipboard: jest.fn(),
|
||||||
|
openLink: jest.fn(),
|
||||||
showNotification: jest.fn(),
|
showNotification: jest.fn(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import styled from '@emotion/styled';
|
|||||||
import React, {MouseEvent, KeyboardEvent} from 'react';
|
import React, {MouseEvent, KeyboardEvent} from 'react';
|
||||||
import {theme} from '../theme';
|
import {theme} from '../theme';
|
||||||
import {Layout} from '../Layout';
|
import {Layout} from '../Layout';
|
||||||
import {_getFlipperLibImplementation} from 'flipper-plugin';
|
import {getFlipperLib} from 'flipper-plugin';
|
||||||
import {DownOutlined, RightOutlined} from '@ant-design/icons';
|
import {DownOutlined, RightOutlined} from '@ant-design/icons';
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
@@ -221,7 +221,7 @@ class ElementsRow extends PureComponent<ElementsRowProps, ElementsRowState> {
|
|||||||
{
|
{
|
||||||
label: 'Copy',
|
label: 'Copy',
|
||||||
click: () => {
|
click: () => {
|
||||||
_getFlipperLibImplementation()?.writeTextToClipboard(
|
getFlipperLib()?.writeTextToClipboard(
|
||||||
props.onCopyExpandedTree(props.element, 0),
|
props.onCopyExpandedTree(props.element, 0),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -229,7 +229,7 @@ class ElementsRow extends PureComponent<ElementsRowProps, ElementsRowState> {
|
|||||||
{
|
{
|
||||||
label: 'Copy expanded child elements',
|
label: 'Copy expanded child elements',
|
||||||
click: () =>
|
click: () =>
|
||||||
_getFlipperLibImplementation()?.writeTextToClipboard(
|
getFlipperLib()?.writeTextToClipboard(
|
||||||
props.onCopyExpandedTree(props.element, 255),
|
props.onCopyExpandedTree(props.element, 255),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -253,7 +253,7 @@ class ElementsRow extends PureComponent<ElementsRowProps, ElementsRowState> {
|
|||||||
return {
|
return {
|
||||||
label: `Copy ${o.name}`,
|
label: `Copy ${o.name}`,
|
||||||
click: () => {
|
click: () => {
|
||||||
_getFlipperLibImplementation()?.writeTextToClipboard(o.value);
|
getFlipperLib()?.writeTextToClipboard(o.value);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
@@ -555,9 +555,7 @@ export class Elements extends PureComponent<ElementsProps, ElementsState> {
|
|||||||
) {
|
) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
_getFlipperLibImplementation()?.writeTextToClipboard(
|
getFlipperLib()?.writeTextToClipboard(selectedElement.name);
|
||||||
selectedElement.name,
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {shell} from 'electron';
|
|
||||||
import {styled, colors, FlexRow, Text, GK} from 'flipper';
|
import {styled, colors, FlexRow, Text, GK} from 'flipper';
|
||||||
|
import {Typography} from 'antd';
|
||||||
|
|
||||||
const BannerContainer = styled(FlexRow)({
|
const BannerContainer = styled(FlexRow)({
|
||||||
height: '30px',
|
height: '30px',
|
||||||
@@ -34,14 +34,6 @@ const BannerLink = styled(CustomLink)({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const StyledLink = styled.span({
|
|
||||||
'&:hover': {
|
|
||||||
cursor: 'pointer',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
StyledLink.displayName = 'CustomLink:StyledLink';
|
|
||||||
|
|
||||||
function CustomLink(props: {
|
function CustomLink(props: {
|
||||||
href: string;
|
href: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
@@ -49,12 +41,12 @@ function CustomLink(props: {
|
|||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<StyledLink
|
<Typography.Link
|
||||||
className={props.className}
|
className={props.className}
|
||||||
onClick={() => shell.openExternal(props.href)}
|
href={props.href}
|
||||||
style={props.style}>
|
style={props.style}>
|
||||||
{props.children || props.href}
|
{props.children || props.href}
|
||||||
</StyledLink>
|
</Typography.Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -935,6 +935,13 @@ See `View > Flipper Style Guide` inside the Flipper application for more details
|
|||||||
|
|
||||||
## Utilities
|
## Utilities
|
||||||
|
|
||||||
|
### getFlipperLib
|
||||||
|
|
||||||
|
A set of globally available utilities like opening links, interacting with the clipboard, etc.
|
||||||
|
Example: `getFlipperLib().writeTextToClipboard("hello from Flipper");
|
||||||
|
|
||||||
|
The full set of utilities can be found [here](https://github.com/facebook/flipper/blob/master/desktop/flipper-plugin/src/plugin/FlipperLib.tsx#L20)
|
||||||
|
|
||||||
### createTablePlugin
|
### createTablePlugin
|
||||||
|
|
||||||
Utility to create a plugin that consists of a master table and details JSON view with minimal effort. See the [Showing a table](../tutorial/js-table.mdx) tutorial for an example.
|
Utility to create a plugin that consists of a master table and details JSON view with minimal effort. See the [Showing a table](../tutorial/js-table.mdx) tutorial for an example.
|
||||||
|
|||||||
Reference in New Issue
Block a user