Introduce showNotification API
Summary: Introduced `showNotifcation` to the Sandy API. Reviewed By: jknoxville Differential Revision: D27012001 fbshipit-source-id: d3f237910a478400b0f925f0362af485c96072bb
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2ca52f81d2
commit
4e2383cdb0
@@ -28,7 +28,6 @@ export {
|
||||
FlipperPlugin,
|
||||
FlipperDevicePlugin,
|
||||
callClient,
|
||||
Notification,
|
||||
BaseAction,
|
||||
} from './plugin';
|
||||
export {PluginClient, Props} from './plugin';
|
||||
@@ -42,7 +41,7 @@ export {connect} from 'react-redux';
|
||||
export {selectPlugin, StaticView} from './reducers/connections';
|
||||
export {writeBufferToFile, bufferToBlob} from './utils/screenshot';
|
||||
export {getPluginKey, getPersistedState} from './utils/pluginUtils';
|
||||
export {Idler} from 'flipper-plugin';
|
||||
export {Idler, Notification} from 'flipper-plugin';
|
||||
export {Store, MiddlewareAPI, State as ReduxState} from './reducers/index';
|
||||
export {default as BaseDevice} from './devices/BaseDevice';
|
||||
export {DeviceLogEntry, LogLevel, DeviceLogListener} from 'flipper-plugin';
|
||||
|
||||
@@ -11,7 +11,7 @@ import {KeyboardActions} from './MenuBar';
|
||||
import {Logger} from './fb-interfaces/Logger';
|
||||
import Client from './Client';
|
||||
import {Store} from './reducers/index';
|
||||
import {ReactNode, Component} from 'react';
|
||||
import {Component} from 'react';
|
||||
import BaseDevice from './devices/BaseDevice';
|
||||
import {serialize, deserialize} from './utils/serialization';
|
||||
import {StaticView} from './reducers/connections';
|
||||
@@ -19,7 +19,7 @@ import {State as ReduxState} from './reducers';
|
||||
import {DEFAULT_MAX_QUEUE_SIZE} from './reducers/pluginMessageQueue';
|
||||
import {ActivatablePluginDetails} from 'flipper-plugin-lib';
|
||||
import {Settings} from './reducers/settings';
|
||||
import {Idler, _SandyPluginDefinition} from 'flipper-plugin';
|
||||
import {Notification, Idler, _SandyPluginDefinition} from 'flipper-plugin';
|
||||
|
||||
type Parameters = {[key: string]: any};
|
||||
|
||||
@@ -68,16 +68,6 @@ export interface PluginClient {
|
||||
|
||||
type PluginTarget = BaseDevice | Client;
|
||||
|
||||
export type Notification = {
|
||||
id: string;
|
||||
title: string;
|
||||
message: string | ReactNode;
|
||||
severity: 'warning' | 'error';
|
||||
timestamp?: number;
|
||||
category?: string;
|
||||
action?: string;
|
||||
};
|
||||
|
||||
export type Props<T> = {
|
||||
logger: Logger;
|
||||
persistedState: T;
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
updateCategoryBlocklist,
|
||||
} from '../notifications';
|
||||
|
||||
import {Notification} from '../../plugin';
|
||||
import {Notification} from 'flipper-plugin';
|
||||
|
||||
const notification: Notification = {
|
||||
id: 'id',
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {Notification} from '../plugin';
|
||||
import {Notification} from 'flipper-plugin';
|
||||
import {Actions} from './';
|
||||
import {getStringFromErrorLike} from '../utils';
|
||||
|
||||
export type PluginNotification = {
|
||||
notification: Notification;
|
||||
pluginId: string;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import React, {useCallback, useMemo, useState} from 'react';
|
||||
import {Layout, theme} from 'flipper-plugin';
|
||||
import {Layout, theme, Notification as NotificationData} from 'flipper-plugin';
|
||||
import {styled, Glyph} from '../../ui';
|
||||
import {Input, Typography, Button, Collapse, Dropdown, Menu} from 'antd';
|
||||
import {
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
EllipsisOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import {LeftSidebar, SidebarTitle} from '../LeftSidebar';
|
||||
import {Notification as NotificationData} from '../../plugin';
|
||||
import {useStore, useDispatch} from '../../utils/useStore';
|
||||
import {ClientQuery} from '../../Client';
|
||||
import {deconstructClientId} from '../../utils/clientUtils';
|
||||
|
||||
@@ -18,11 +18,11 @@ import {
|
||||
importDataToStore,
|
||||
} from '../exportData';
|
||||
import {FlipperPlugin, FlipperDevicePlugin} from '../../plugin';
|
||||
import {Notification} from '../../plugin';
|
||||
import {default as Client, ClientExport} from '../../Client';
|
||||
import {selectedPlugins, State as PluginsState} from '../../reducers/plugins';
|
||||
import {createMockFlipperWithPlugin} from '../../test-utils/createMockFlipperWithPlugin';
|
||||
import {
|
||||
Notification,
|
||||
TestUtils,
|
||||
_SandyPluginDefinition,
|
||||
createState,
|
||||
|
||||
@@ -15,6 +15,8 @@ import GK from '../fb-stubs/GK';
|
||||
import type BaseDevice from '../devices/BaseDevice';
|
||||
import {clipboard} from 'electron';
|
||||
import constants from '../fb-stubs/constants';
|
||||
import {addNotification} from '../reducers/notifications';
|
||||
import {deconstructPluginKey} from './clientUtils';
|
||||
|
||||
export function initializeFlipperLibImplementation(
|
||||
store: Store,
|
||||
@@ -71,5 +73,15 @@ export function initializeFlipperLibImplementation(
|
||||
writeTextToClipboard(text: string) {
|
||||
clipboard.writeText(text);
|
||||
},
|
||||
showNotification(pluginId, notification) {
|
||||
const parts = deconstructPluginKey(pluginId);
|
||||
store.dispatch(
|
||||
addNotification({
|
||||
pluginId: parts.pluginName,
|
||||
client: parts.client,
|
||||
notification,
|
||||
}),
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ test('Correct top level API exposed', () => {
|
||||
"Logger",
|
||||
"MenuEntry",
|
||||
"NormalizedMenuEntry",
|
||||
"Notification",
|
||||
"PluginClient",
|
||||
"TrackType",
|
||||
]
|
||||
|
||||
@@ -46,6 +46,7 @@ export {
|
||||
buildInMenuEntries as _buildInMenuEntries,
|
||||
DefaultKeyboardAction,
|
||||
} from './plugin/MenuEntry';
|
||||
export {Notification} from './plugin/Notification';
|
||||
|
||||
export {theme} from './ui/theme';
|
||||
export {Layout} from './ui/Layout';
|
||||
|
||||
@@ -11,6 +11,7 @@ import {Logger} from '../utils/Logger';
|
||||
import {RealFlipperDevice} from './DevicePlugin';
|
||||
import {NormalizedMenuEntry} from './MenuEntry';
|
||||
import {RealFlipperClient} from './Plugin';
|
||||
import {Notification} from './Notification';
|
||||
|
||||
/**
|
||||
* This interface exposes all global methods for which an implementation will be provided by Flipper itself
|
||||
@@ -33,6 +34,7 @@ export interface FlipperLib {
|
||||
deeplink: unknown,
|
||||
): void;
|
||||
writeTextToClipboard(text: string): void;
|
||||
showNotification(pluginKey: string, notification: Notification): void;
|
||||
}
|
||||
|
||||
let flipperLibInstance: FlipperLib | undefined;
|
||||
|
||||
19
desktop/flipper-plugin/src/plugin/Notification.tsx
Normal file
19
desktop/flipper-plugin/src/plugin/Notification.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
export type Notification = {
|
||||
id: string;
|
||||
title: string;
|
||||
message: string | React.ReactNode;
|
||||
severity: 'warning' | 'error';
|
||||
timestamp?: number;
|
||||
category?: string;
|
||||
/** The action will be available as deeplink payload when the notification is clicked. */
|
||||
action?: string;
|
||||
};
|
||||
@@ -7,14 +7,15 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {SandyPluginDefinition} from './SandyPluginDefinition';
|
||||
import {message} from 'antd';
|
||||
import {EventEmitter} from 'events';
|
||||
import {SandyPluginDefinition} from './SandyPluginDefinition';
|
||||
import {MenuEntry, NormalizedMenuEntry, normalizeMenuEntry} from './MenuEntry';
|
||||
import {FlipperLib} from './FlipperLib';
|
||||
import {Device, RealFlipperDevice} from './DevicePlugin';
|
||||
import {batched} from '../state/batch';
|
||||
import {Idler} from '../utils/Idler';
|
||||
import {message} from 'antd';
|
||||
import {Notification} from './Notification';
|
||||
|
||||
type StateExportHandler<T = any> = (
|
||||
idler: Idler,
|
||||
@@ -23,6 +24,9 @@ type StateExportHandler<T = any> = (
|
||||
type StateImportHandler<T = any> = (data: T) => void;
|
||||
|
||||
export interface BasePluginClient {
|
||||
/**
|
||||
* A key that uniquely identifies this plugin instance, captures the current device/client/plugin combination.
|
||||
*/
|
||||
readonly pluginKey: string;
|
||||
readonly device: Device;
|
||||
|
||||
@@ -74,6 +78,14 @@ export interface BasePluginClient {
|
||||
* Always returns `false` in open source.
|
||||
*/
|
||||
GK(gkName: string): boolean;
|
||||
|
||||
/**
|
||||
* Shows an urgent, system wide notification, that will also be registered in Flipper's notification pane.
|
||||
* For on-screen notifications, we recommend to use either the `message` or `notification` API from `antd` directly.
|
||||
*
|
||||
* Clicking the notification will open this plugin. If the `action` id is set, it will be used as deeplink.
|
||||
*/
|
||||
showNotification(notification: Notification): void;
|
||||
}
|
||||
|
||||
let currentPluginInstance: BasePluginInstance | undefined = undefined;
|
||||
@@ -262,6 +274,9 @@ export abstract class BasePluginInstance {
|
||||
},
|
||||
createPaste: this.flipperLib.createPaste,
|
||||
GK: this.flipperLib.GK,
|
||||
showNotification: (notification: Notification) => {
|
||||
this.flipperLib.showNotification(this.pluginKey, notification);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -371,6 +371,7 @@ export function createMockFlipperLib(options?: StartPluginOptions): FlipperLib {
|
||||
selectPlugin: jest.fn(),
|
||||
isPluginAvailable: jest.fn().mockImplementation(() => false),
|
||||
writeTextToClipboard: jest.fn(),
|
||||
showNotification: jest.fn(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,10 @@ The name of the application, for example 'Facebook', 'Instagram' or 'Slack'.
|
||||
|
||||
A string that uniquely identifies the current application, is based on a combination of the application name and device serial on which the application is running.
|
||||
|
||||
#### `pluginKey`
|
||||
|
||||
A key that uniquely identifies this plugin instance, captures the current device/client/plugin combination.
|
||||
|
||||
#### `isConnected`
|
||||
|
||||
Returns whether there is currently an active connection. This is true if:
|
||||
@@ -268,6 +272,29 @@ Usage: `client.supportsMethod(method: string): Promise<Boolean>`
|
||||
|
||||
Resolves to true if the client supports the specified method. Useful when adding functionality to existing plugins, when connectivity to older clients is still required. Also useful when client plugins are implemented on multitple platforms and don't all have feature parity.
|
||||
|
||||
#### showNotification
|
||||
|
||||
Usage: `client.showNotification(notification)`
|
||||
|
||||
Shows an urgent, system wide notification, that will also be registered in Flipper's notification pane.
|
||||
For on-screen notifications, we recommend to use either the `message` or `notification` API from `antd` directly.
|
||||
|
||||
Clicking the notification will open the sending plugin. If the `action` id is set, it will be used as deeplink.
|
||||
|
||||
The notification interface is defined as:
|
||||
|
||||
```typescript
|
||||
interface Notification {
|
||||
id: string;
|
||||
title: string;
|
||||
message: string | React.ReactNode;
|
||||
severity: 'warning' | 'error';
|
||||
timestamp?: number;
|
||||
category?: string;
|
||||
action?: string;
|
||||
};
|
||||
```
|
||||
|
||||
#### `createPaste`
|
||||
|
||||
Facebook only API.
|
||||
@@ -343,6 +370,10 @@ See the similarly named method under [`PluginClient`](#pluginclient).
|
||||
|
||||
See the similarly named method under [`PluginClient`](#pluginclient).
|
||||
|
||||
#### `showNotification`
|
||||
|
||||
See the similarly named method under [`PluginClient`](#pluginclient).
|
||||
|
||||
### `isPluginAvailable`
|
||||
|
||||
See the similarly named method under [`PluginClient`](#pluginclient).
|
||||
|
||||
Reference in New Issue
Block a user