prettier 2
Summary:
Quick notes:
- This looks worse than it is. It adds mandatory parentheses to single argument lambdas. Lots of outrage on Twitter about it, personally I'm {emoji:1f937_200d_2642} about it.
- Space before function, e.g. `a = function ()` is now enforced. I like this because both were fine before.
- I added `eslint-config-prettier` to the config because otherwise a ton of rules conflict with eslint itself.
Close https://github.com/facebook/flipper/pull/915
Reviewed By: jknoxville
Differential Revision: D20594929
fbshipit-source-id: ca1c65376b90e009550dd6d1f4e0831d32cbff03
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d9d3be33b4
commit
fc9ed65762
@@ -24,7 +24,7 @@ const prettierConfig = {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
parser: 'babel-eslint',
|
parser: 'babel-eslint',
|
||||||
root: true,
|
root: true,
|
||||||
extends: 'fbjs',
|
extends: ['fbjs', 'prettier'],
|
||||||
plugins: [
|
plugins: [
|
||||||
...fbjs.plugins,
|
...fbjs.plugins,
|
||||||
'header',
|
'header',
|
||||||
@@ -43,8 +43,6 @@ module.exports = {
|
|||||||
'prefer-const': [2, {destructuring: 'all'}],
|
'prefer-const': [2, {destructuring: 'all'}],
|
||||||
'prefer-spread': 1,
|
'prefer-spread': 1,
|
||||||
'prefer-rest-params': 1,
|
'prefer-rest-params': 1,
|
||||||
'max-len': 0, // lets prettier take care of this
|
|
||||||
indent: 0, // lets prettier take care of this
|
|
||||||
'no-console': 0, // we're setting window.console in App.js
|
'no-console': 0, // we're setting window.console in App.js
|
||||||
'no-multi-spaces': 2,
|
'no-multi-spaces': 2,
|
||||||
'prefer-promise-reject-errors': 1,
|
'prefer-promise-reject-errors': 1,
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export default class Client extends EventEmitter {
|
|||||||
store: Store;
|
store: Store;
|
||||||
activePlugins: Set<string>;
|
activePlugins: Set<string>;
|
||||||
device: Promise<BaseDevice>;
|
device: Promise<BaseDevice>;
|
||||||
_deviceResolve: (device: BaseDevice) => void = _ => {};
|
_deviceResolve: (device: BaseDevice) => void = (_) => {};
|
||||||
_deviceSet: false | BaseDevice = false;
|
_deviceSet: false | BaseDevice = false;
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
lastSeenDeviceList: Array<BaseDevice>;
|
lastSeenDeviceList: Array<BaseDevice>;
|
||||||
@@ -194,7 +194,7 @@ export default class Client extends EventEmitter {
|
|||||||
const device = this.store
|
const device = this.store
|
||||||
.getState()
|
.getState()
|
||||||
.connections.devices.find(
|
.connections.devices.find(
|
||||||
device => device.serial === this.query.device_id,
|
(device) => device.serial === this.query.device_id,
|
||||||
);
|
);
|
||||||
if (device) {
|
if (device) {
|
||||||
resolve(device);
|
resolve(device);
|
||||||
@@ -214,7 +214,7 @@ export default class Client extends EventEmitter {
|
|||||||
}
|
}
|
||||||
this.lastSeenDeviceList = this.store.getState().connections.devices;
|
this.lastSeenDeviceList = this.store.getState().connections.devices;
|
||||||
const matchingDevice = newDeviceList.find(
|
const matchingDevice = newDeviceList.find(
|
||||||
device => device.serial === this.query.device_id,
|
(device) => device.serial === this.query.device_id,
|
||||||
);
|
);
|
||||||
if (matchingDevice) {
|
if (matchingDevice) {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
@@ -224,7 +224,7 @@ export default class Client extends EventEmitter {
|
|||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
'client-setMatchingDevice',
|
'client-setMatchingDevice',
|
||||||
).then(device => {
|
).then((device) => {
|
||||||
this._deviceSet = device;
|
this._deviceSet = device;
|
||||||
this._deviceResolve(device);
|
this._deviceResolve(device);
|
||||||
});
|
});
|
||||||
@@ -244,10 +244,10 @@ export default class Client extends EventEmitter {
|
|||||||
const plugins = await this.rawCall<{plugins: Plugins}>(
|
const plugins = await this.rawCall<{plugins: Plugins}>(
|
||||||
'getPlugins',
|
'getPlugins',
|
||||||
false,
|
false,
|
||||||
).then(data => data.plugins);
|
).then((data) => data.plugins);
|
||||||
this.plugins = plugins;
|
this.plugins = plugins;
|
||||||
const nativeplugins = plugins
|
const nativeplugins = plugins
|
||||||
.map(plugin => /_nativeplugin_([^_]+)_([^_]+)/.exec(plugin))
|
.map((plugin) => /_nativeplugin_([^_]+)_([^_]+)/.exec(plugin))
|
||||||
.filter(notNull)
|
.filter(notNull)
|
||||||
.map(([id, type, title]) => {
|
.map(([id, type, title]) => {
|
||||||
// TODO put this in another component, and make the "types" registerable
|
// TODO put this in another component, and make the "types" registerable
|
||||||
@@ -318,7 +318,7 @@ export default class Client extends EventEmitter {
|
|||||||
}: ${error.message} + \nDevice Stack Trace: ${error.stacktrace}`,
|
}: ${error.message} + \nDevice Stack Trace: ${error.stacktrace}`,
|
||||||
'deviceError',
|
'deviceError',
|
||||||
);
|
);
|
||||||
this.device.then(device => handleError(this.store, device, error));
|
this.device.then((device) => handleError(this.store, device, error));
|
||||||
} else if (method === 'refreshPlugins') {
|
} else if (method === 'refreshPlugins') {
|
||||||
this.refreshPlugins();
|
this.refreshPlugins();
|
||||||
} else if (method === 'execute') {
|
} else if (method === 'execute') {
|
||||||
@@ -389,7 +389,7 @@ export default class Client extends EventEmitter {
|
|||||||
reject(data.error);
|
reject(data.error);
|
||||||
const {error} = data;
|
const {error} = data;
|
||||||
if (error) {
|
if (error) {
|
||||||
this.device.then(device => handleError(this.store, device, error));
|
this.device.then((device) => handleError(this.store, device, error));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ???
|
// ???
|
||||||
@@ -466,7 +466,7 @@ export default class Client extends EventEmitter {
|
|||||||
this.connection
|
this.connection
|
||||||
.requestResponse({data: JSON.stringify(data)})
|
.requestResponse({data: JSON.stringify(data)})
|
||||||
.subscribe({
|
.subscribe({
|
||||||
onComplete: payload => {
|
onComplete: (payload) => {
|
||||||
if (!fromPlugin || this.isAcceptingMessagesFromPlugin(plugin)) {
|
if (!fromPlugin || this.isAcceptingMessagesFromPlugin(plugin)) {
|
||||||
const logEventName = this.getLogEventName(data);
|
const logEventName = this.getLogEventName(data);
|
||||||
this.logger.trackTimeSince(mark, logEventName);
|
this.logger.trackTimeSince(mark, logEventName);
|
||||||
@@ -478,7 +478,7 @@ export default class Client extends EventEmitter {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Open fresco then layout and you get errors because responses come back after deinit.
|
// Open fresco then layout and you get errors because responses come back after deinit.
|
||||||
onError: e => {
|
onError: (e) => {
|
||||||
if (this.isAcceptingMessagesFromPlugin(plugin)) {
|
if (this.isAcceptingMessagesFromPlugin(plugin)) {
|
||||||
reject(e);
|
reject(e);
|
||||||
}
|
}
|
||||||
@@ -555,8 +555,9 @@ export default class Client extends EventEmitter {
|
|||||||
send(api: string, method: string, params?: Object): void {
|
send(api: string, method: string, params?: Object): void {
|
||||||
if (!isProduction()) {
|
if (!isProduction()) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`${api}:${method ||
|
`${api}:${
|
||||||
''} client.send() is deprecated. Please use call() instead so you can handle errors.`,
|
method || ''
|
||||||
|
} client.send() is deprecated. Please use call() instead so you can handle errors.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return this.rawSend('execute', {api, method, params});
|
return this.rawSend('execute', {api, method, params});
|
||||||
|
|||||||
@@ -81,18 +81,18 @@ export function setupMenuBar(
|
|||||||
// collect all keyboard actions from all plugins
|
// collect all keyboard actions from all plugins
|
||||||
const registeredActions: Set<KeyboardAction> = new Set(
|
const registeredActions: Set<KeyboardAction> = new Set(
|
||||||
plugins
|
plugins
|
||||||
.map(plugin => plugin.keyboardActions || [])
|
.map((plugin) => plugin.keyboardActions || [])
|
||||||
.reduce((acc: KeyboardActions, cv) => acc.concat(cv), [])
|
.reduce((acc: KeyboardActions, cv) => acc.concat(cv), [])
|
||||||
.map((action: DefaultKeyboardAction | KeyboardAction) =>
|
.map((action: DefaultKeyboardAction | KeyboardAction) =>
|
||||||
typeof action === 'string'
|
typeof action === 'string'
|
||||||
? defaultKeyboardActions.find(a => a.action === action)
|
? defaultKeyboardActions.find((a) => a.action === action)
|
||||||
: action,
|
: action,
|
||||||
)
|
)
|
||||||
.filter(notNull),
|
.filter(notNull),
|
||||||
);
|
);
|
||||||
|
|
||||||
// add keyboard actions to
|
// add keyboard actions to
|
||||||
registeredActions.forEach(keyboardAction => {
|
registeredActions.forEach((keyboardAction) => {
|
||||||
if (keyboardAction != null) {
|
if (keyboardAction != null) {
|
||||||
appendMenuItem(template, actionHandler, keyboardAction);
|
appendMenuItem(template, actionHandler, keyboardAction);
|
||||||
}
|
}
|
||||||
@@ -102,15 +102,15 @@ export function setupMenuBar(
|
|||||||
const applicationMenu = electron.remote.Menu.buildFromTemplate(template);
|
const applicationMenu = electron.remote.Menu.buildFromTemplate(template);
|
||||||
|
|
||||||
// add menu items to map, so we can modify them easily later
|
// add menu items to map, so we can modify them easily later
|
||||||
registeredActions.forEach(keyboardAction => {
|
registeredActions.forEach((keyboardAction) => {
|
||||||
if (keyboardAction != null) {
|
if (keyboardAction != null) {
|
||||||
const {topLevelMenu, label, action} = keyboardAction;
|
const {topLevelMenu, label, action} = keyboardAction;
|
||||||
const menu = applicationMenu.items.find(
|
const menu = applicationMenu.items.find(
|
||||||
menuItem => menuItem.label === topLevelMenu,
|
(menuItem) => menuItem.label === topLevelMenu,
|
||||||
);
|
);
|
||||||
if (menu && menu.submenu) {
|
if (menu && menu.submenu) {
|
||||||
const menuItem = menu.submenu.items.find(
|
const menuItem = menu.submenu.items.find(
|
||||||
menuItem => menuItem.label === label,
|
(menuItem) => menuItem.label === label,
|
||||||
);
|
);
|
||||||
menuItem && menuItems.set(action, menuItem);
|
menuItem && menuItems.set(action, menuItem);
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ function appendMenuItem(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const itemIndex = template.findIndex(
|
const itemIndex = template.findIndex(
|
||||||
menu => menu.label === keyboardAction.topLevelMenu,
|
(menu) => menu.label === keyboardAction.topLevelMenu,
|
||||||
);
|
);
|
||||||
if (itemIndex > -1 && template[itemIndex].submenu != null) {
|
if (itemIndex > -1 && template[itemIndex].submenu != null) {
|
||||||
(template[itemIndex].submenu as MenuItemConstructorOptions[]).push({
|
(template[itemIndex].submenu as MenuItemConstructorOptions[]).push({
|
||||||
@@ -160,16 +160,18 @@ export function activateMenuItems(
|
|||||||
|
|
||||||
// enable keyboard actions for the current plugin
|
// enable keyboard actions for the current plugin
|
||||||
if (activePlugin.constructor.keyboardActions != null) {
|
if (activePlugin.constructor.keyboardActions != null) {
|
||||||
(activePlugin.constructor.keyboardActions || []).forEach(keyboardAction => {
|
(activePlugin.constructor.keyboardActions || []).forEach(
|
||||||
const action =
|
(keyboardAction) => {
|
||||||
typeof keyboardAction === 'string'
|
const action =
|
||||||
? keyboardAction
|
typeof keyboardAction === 'string'
|
||||||
: keyboardAction.action;
|
? keyboardAction
|
||||||
const item = menuItems.get(action);
|
: keyboardAction.action;
|
||||||
if (item != null) {
|
const item = menuItems.get(action);
|
||||||
item.enabled = true;
|
if (item != null) {
|
||||||
}
|
item.enabled = true;
|
||||||
});
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the application menu again to make sure it updates
|
// set the application menu again to make sure it updates
|
||||||
@@ -206,7 +208,7 @@ function getTemplate(
|
|||||||
{
|
{
|
||||||
label: 'Import Flipper File...',
|
label: 'Import Flipper File...',
|
||||||
accelerator: 'CommandOrControl+O',
|
accelerator: 'CommandOrControl+O',
|
||||||
click: function() {
|
click: function () {
|
||||||
showOpenDialog(store);
|
showOpenDialog(store);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -218,7 +220,7 @@ function getTemplate(
|
|||||||
const supportRequestSubmenu = [
|
const supportRequestSubmenu = [
|
||||||
{
|
{
|
||||||
label: 'Create...',
|
label: 'Create...',
|
||||||
click: function() {
|
click: function () {
|
||||||
// Dispatch an action to open the export screen of Support Request form
|
// Dispatch an action to open the export screen of Support Request form
|
||||||
store.dispatch(setStaticView(SupportRequestFormV2));
|
store.dispatch(setStaticView(SupportRequestFormV2));
|
||||||
},
|
},
|
||||||
@@ -278,7 +280,7 @@ function getTemplate(
|
|||||||
{
|
{
|
||||||
label: 'Reload',
|
label: 'Reload',
|
||||||
accelerator: 'CmdOrCtrl+R',
|
accelerator: 'CmdOrCtrl+R',
|
||||||
click: function(
|
click: function (
|
||||||
_,
|
_,
|
||||||
focusedWindow: electron.BrowserWindow | undefined,
|
focusedWindow: electron.BrowserWindow | undefined,
|
||||||
) {
|
) {
|
||||||
@@ -289,14 +291,14 @@ function getTemplate(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Toggle Full Screen',
|
label: 'Toggle Full Screen',
|
||||||
accelerator: (function() {
|
accelerator: (function () {
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
return 'Ctrl+Command+F';
|
return 'Ctrl+Command+F';
|
||||||
} else {
|
} else {
|
||||||
return 'F11';
|
return 'F11';
|
||||||
}
|
}
|
||||||
})(),
|
})(),
|
||||||
click: function(
|
click: function (
|
||||||
_,
|
_,
|
||||||
focusedWindow: electron.BrowserWindow | undefined,
|
focusedWindow: electron.BrowserWindow | undefined,
|
||||||
) {
|
) {
|
||||||
@@ -307,20 +309,20 @@ function getTemplate(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Manage Plugins...',
|
label: 'Manage Plugins...',
|
||||||
click: function() {
|
click: function () {
|
||||||
store.dispatch(setActiveSheet(ACTIVE_SHEET_PLUGINS));
|
store.dispatch(setActiveSheet(ACTIVE_SHEET_PLUGINS));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Toggle Developer Tools',
|
label: 'Toggle Developer Tools',
|
||||||
accelerator: (function() {
|
accelerator: (function () {
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
return 'Alt+Command+I';
|
return 'Alt+Command+I';
|
||||||
} else {
|
} else {
|
||||||
return 'Ctrl+Shift+I';
|
return 'Ctrl+Shift+I';
|
||||||
}
|
}
|
||||||
})(),
|
})(),
|
||||||
click: function(
|
click: function (
|
||||||
_,
|
_,
|
||||||
focusedWindow: electron.BrowserWindow | undefined,
|
focusedWindow: electron.BrowserWindow | undefined,
|
||||||
) {
|
) {
|
||||||
@@ -357,7 +359,7 @@ function getTemplate(
|
|||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: 'Getting started',
|
label: 'Getting started',
|
||||||
click: function() {
|
click: function () {
|
||||||
shell.openExternal(
|
shell.openExternal(
|
||||||
'https://fbflipper.com/docs/getting-started.html',
|
'https://fbflipper.com/docs/getting-started.html',
|
||||||
);
|
);
|
||||||
@@ -365,7 +367,7 @@ function getTemplate(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Create plugins',
|
label: 'Create plugins',
|
||||||
click: function() {
|
click: function () {
|
||||||
shell.openExternal(
|
shell.openExternal(
|
||||||
'https://fbflipper.com/docs/tutorial/intro.html',
|
'https://fbflipper.com/docs/tutorial/intro.html',
|
||||||
);
|
);
|
||||||
@@ -373,7 +375,7 @@ function getTemplate(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Report problems',
|
label: 'Report problems',
|
||||||
click: function() {
|
click: function () {
|
||||||
shell.openExternal('https://github.com/facebook/flipper/issues');
|
shell.openExternal('https://github.com/facebook/flipper/issues');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -427,13 +429,13 @@ function getTemplate(
|
|||||||
{
|
{
|
||||||
label: 'Quit',
|
label: 'Quit',
|
||||||
accelerator: 'Command+Q',
|
accelerator: 'Command+Q',
|
||||||
click: function() {
|
click: function () {
|
||||||
app.quit();
|
app.quit();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
const windowMenu = template.find(function(m) {
|
const windowMenu = template.find(function (m) {
|
||||||
return m.role === 'window';
|
return m.role === 'window';
|
||||||
});
|
});
|
||||||
if (windowMenu) {
|
if (windowMenu) {
|
||||||
|
|||||||
@@ -108,16 +108,18 @@ class NotificationsTable extends Component<Props & SearchableProps, State> {
|
|||||||
if (this.props.filters.length !== prevProps.filters.length) {
|
if (this.props.filters.length !== prevProps.filters.length) {
|
||||||
this.props.updatePluginBlacklist(
|
this.props.updatePluginBlacklist(
|
||||||
this.props.filters
|
this.props.filters
|
||||||
.filter(f => f.type === 'exclude' && f.key.toLowerCase() === 'plugin')
|
.filter(
|
||||||
.map(f => String(f.value)),
|
(f) => f.type === 'exclude' && f.key.toLowerCase() === 'plugin',
|
||||||
|
)
|
||||||
|
.map((f) => String(f.value)),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.props.updateCategoryBlacklist(
|
this.props.updateCategoryBlacklist(
|
||||||
this.props.filters
|
this.props.filters
|
||||||
.filter(
|
.filter(
|
||||||
f => f.type === 'exclude' && f.key.toLowerCase() === 'category',
|
(f) => f.type === 'exclude' && f.key.toLowerCase() === 'category',
|
||||||
)
|
)
|
||||||
.map(f => String(f.value)),
|
.map((f) => String(f.value)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +164,7 @@ class NotificationsTable extends Component<Props & SearchableProps, State> {
|
|||||||
|
|
||||||
// filter plugins
|
// filter plugins
|
||||||
const blacklistedPlugins = new Set(
|
const blacklistedPlugins = new Set(
|
||||||
this.props.blacklistedPlugins.map(p => p.toLowerCase()),
|
this.props.blacklistedPlugins.map((p) => p.toLowerCase()),
|
||||||
);
|
);
|
||||||
if (blacklistedPlugins.has(n.pluginId.toLowerCase())) {
|
if (blacklistedPlugins.has(n.pluginId.toLowerCase())) {
|
||||||
return false;
|
return false;
|
||||||
@@ -172,7 +174,7 @@ class NotificationsTable extends Component<Props & SearchableProps, State> {
|
|||||||
const {category} = n.notification;
|
const {category} = n.notification;
|
||||||
if (category) {
|
if (category) {
|
||||||
const blacklistedCategories = new Set(
|
const blacklistedCategories = new Set(
|
||||||
this.props.blacklistedCategories.map(p => p.toLowerCase()),
|
this.props.blacklistedCategories.map((p) => p.toLowerCase()),
|
||||||
);
|
);
|
||||||
if (blacklistedCategories.has(category.toLowerCase())) {
|
if (blacklistedCategories.has(category.toLowerCase())) {
|
||||||
return false;
|
return false;
|
||||||
@@ -320,7 +322,7 @@ type NotificationBoxProps = {
|
|||||||
severity: keyof typeof SEVERITY_COLOR_MAP;
|
severity: keyof typeof SEVERITY_COLOR_MAP;
|
||||||
};
|
};
|
||||||
|
|
||||||
const NotificationBox = styled(FlexRow)<NotificationBoxProps>(props => ({
|
const NotificationBox = styled(FlexRow)<NotificationBoxProps>((props) => ({
|
||||||
backgroundColor: props.inactive ? 'transparent' : colors.white,
|
backgroundColor: props.inactive ? 'transparent' : colors.white,
|
||||||
opacity: props.inactive ? 0.5 : 1,
|
opacity: props.inactive ? 0.5 : 1,
|
||||||
alignItems: 'flex-start',
|
alignItems: 'flex-start',
|
||||||
@@ -360,7 +362,7 @@ const Title = styled.div({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const NotificationContent = styled(FlexColumn)<{isSelected?: boolean}>(
|
const NotificationContent = styled(FlexColumn)<{isSelected?: boolean}>(
|
||||||
props => ({
|
(props) => ({
|
||||||
marginLeft: 6,
|
marginLeft: 6,
|
||||||
marginRight: 10,
|
marginRight: 10,
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
|
|||||||
@@ -198,11 +198,11 @@ class PluginContainer extends PureComponent<Props, State> {
|
|||||||
activePlugin,
|
activePlugin,
|
||||||
pluginKey,
|
pluginKey,
|
||||||
this.store,
|
this.store,
|
||||||
progress => {
|
(progress) => {
|
||||||
this.setState({progress});
|
this.setState({progress});
|
||||||
},
|
},
|
||||||
this.idler,
|
this.idler,
|
||||||
).then(completed => {
|
).then((completed) => {
|
||||||
const duration = Date.now() - start;
|
const duration = Date.now() - start;
|
||||||
this.props.logger.track(
|
this.props.logger.track(
|
||||||
'duration',
|
'duration',
|
||||||
@@ -345,7 +345,7 @@ class PluginContainer extends PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
: pluginState,
|
: pluginState,
|
||||||
setStaticView: (payload: StaticView) => this.props.setStaticView(payload),
|
setStaticView: (payload: StaticView) => this.props.setStaticView(payload),
|
||||||
setPersistedState: state => setPluginState({pluginKey, state}),
|
setPersistedState: (state) => setPluginState({pluginKey, state}),
|
||||||
target,
|
target,
|
||||||
deepLinkPayload: this.props.deepLinkPayload,
|
deepLinkPayload: this.props.deepLinkPayload,
|
||||||
selectPlugin: (pluginID: string, deepLinkPayload: string | null) => {
|
selectPlugin: (pluginID: string, deepLinkPayload: string | null) => {
|
||||||
@@ -353,7 +353,7 @@ class PluginContainer extends PureComponent<Props, State> {
|
|||||||
// check if plugin will be available
|
// check if plugin will be available
|
||||||
if (
|
if (
|
||||||
target instanceof Client &&
|
target instanceof Client &&
|
||||||
target.plugins.some(p => p === pluginID)
|
target.plugins.some((p) => p === pluginID)
|
||||||
) {
|
) {
|
||||||
this.props.selectPlugin({selectedPlugin: pluginID, deepLinkPayload});
|
this.props.selectPlugin({selectedPlugin: pluginID, deepLinkPayload});
|
||||||
return true;
|
return true;
|
||||||
@@ -371,8 +371,9 @@ class PluginContainer extends PureComponent<Props, State> {
|
|||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Container key="plugin">
|
<Container key="plugin">
|
||||||
<ErrorBoundary
|
<ErrorBoundary
|
||||||
heading={`Plugin "${activePlugin.title ||
|
heading={`Plugin "${
|
||||||
'Unknown'}" encountered an error during render`}>
|
activePlugin.title || 'Unknown'
|
||||||
|
}" encountered an error during render`}>
|
||||||
{React.createElement(activePlugin, props)}
|
{React.createElement(activePlugin, props)}
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export default class AutoUpdateVersion extends Component<Props, State> {
|
|||||||
notification.onclick = remote.autoUpdater.quitAndInstall;
|
notification.onclick = remote.autoUpdater.quitAndInstall;
|
||||||
});
|
});
|
||||||
|
|
||||||
remote.autoUpdater.on('error', error => {
|
remote.autoUpdater.on('error', (error) => {
|
||||||
this.setState({updater: 'error', error: error.toString()});
|
this.setState({updater: 'error', error: error.toString()});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ class BugReporterDialog extends Component<Props, State> {
|
|||||||
success: id,
|
success: id,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch((err) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
error: err.message,
|
error: err.message,
|
||||||
submitting: false,
|
submitting: false,
|
||||||
|
|||||||
@@ -48,13 +48,13 @@ class DevicesButton extends Component<Props> {
|
|||||||
// On Linux, you must run the emulator from the directory it's in because
|
// On Linux, you must run the emulator from the directory it's in because
|
||||||
// reasons ...
|
// reasons ...
|
||||||
which('emulator')
|
which('emulator')
|
||||||
.then(emulatorPath => {
|
.then((emulatorPath) => {
|
||||||
if (emulatorPath) {
|
if (emulatorPath) {
|
||||||
const child = spawn(emulatorPath, [`@${name}`], {
|
const child = spawn(emulatorPath, [`@${name}`], {
|
||||||
detached: true,
|
detached: true,
|
||||||
cwd: dirname(emulatorPath),
|
cwd: dirname(emulatorPath),
|
||||||
});
|
});
|
||||||
child.stderr.on('data', data => {
|
child.stderr.on('data', (data) => {
|
||||||
console.error(`Android emulator error: ${data}`);
|
console.error(`Android emulator error: ${data}`);
|
||||||
});
|
});
|
||||||
child.on('error', console.error);
|
child.on('error', console.error);
|
||||||
@@ -96,7 +96,7 @@ class DevicesButton extends Component<Props> {
|
|||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
...devices
|
...devices
|
||||||
.filter(device => device.deviceType === 'physical')
|
.filter((device) => device.deviceType === 'physical')
|
||||||
.map((device: BaseDevice) => ({
|
.map((device: BaseDevice) => ({
|
||||||
click: () => selectDevice(device),
|
click: () => selectDevice(device),
|
||||||
checked: device === selectedDevice,
|
checked: device === selectedDevice,
|
||||||
@@ -114,7 +114,7 @@ class DevicesButton extends Component<Props> {
|
|||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
...devices
|
...devices
|
||||||
.filter(device => device.deviceType === 'emulator')
|
.filter((device) => device.deviceType === 'emulator')
|
||||||
.map((device: BaseDevice) => ({
|
.map((device: BaseDevice) => ({
|
||||||
click: () => selectDevice(device),
|
click: () => selectDevice(device),
|
||||||
checked: device === selectedDevice,
|
checked: device === selectedDevice,
|
||||||
@@ -132,7 +132,7 @@ class DevicesButton extends Component<Props> {
|
|||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
...devices
|
...devices
|
||||||
.filter(device => device.isArchived)
|
.filter((device) => device.isArchived)
|
||||||
.map((device: BaseDevice) => ({
|
.map((device: BaseDevice) => ({
|
||||||
click: () => selectDevice(device),
|
click: () => selectDevice(device),
|
||||||
checked: device === selectedDevice,
|
checked: device === selectedDevice,
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class DoctorBar extends Component<Props, State> {
|
|||||||
static getDerivedStateFromProps(props: Props, state: State): State | null {
|
static getDerivedStateFromProps(props: Props, state: State): State | null {
|
||||||
const failedCategories = Object.values(
|
const failedCategories = Object.values(
|
||||||
props.healthcheckReport.categories,
|
props.healthcheckReport.categories,
|
||||||
).filter(cat => hasProblems(cat.result));
|
).filter((cat) => hasProblems(cat.result));
|
||||||
if (failedCategories.length == 1) {
|
if (failedCategories.length == 1) {
|
||||||
const failedCat = failedCategories[0];
|
const failedCat = failedCategories[0];
|
||||||
if (failedCat.key === 'ios' || failedCat.key === 'android') {
|
if (failedCat.key === 'ios' || failedCat.key === 'android') {
|
||||||
@@ -131,7 +131,7 @@ class DoctorBar extends Component<Props, State> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
setVisible(visible: boolean) {
|
setVisible(visible: boolean) {
|
||||||
this.setState(prevState => {
|
this.setState((prevState) => {
|
||||||
return {
|
return {
|
||||||
...prevState,
|
...prevState,
|
||||||
visible,
|
visible,
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ class DoctorSheet extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAcknowledgeOnCloseChanged(acknowledge: boolean): void {
|
onAcknowledgeOnCloseChanged(acknowledge: boolean): void {
|
||||||
this.setState(prevState => {
|
this.setState((prevState) => {
|
||||||
return {
|
return {
|
||||||
...prevState,
|
...prevState,
|
||||||
acknowledgeOnClose: acknowledge,
|
acknowledgeOnClose: acknowledge,
|
||||||
@@ -304,7 +304,9 @@ class DoctorSheet extends Component<Props, State> {
|
|||||||
|
|
||||||
getCheckMessage(checkKey: string): string {
|
getCheckMessage(checkKey: string): string {
|
||||||
for (const cat of Object.values(this.props.healthcheckReport.categories)) {
|
for (const cat of Object.values(this.props.healthcheckReport.categories)) {
|
||||||
const check = Object.values(cat.checks).find(chk => chk.key === checkKey);
|
const check = Object.values(cat.checks).find(
|
||||||
|
(chk) => chk.key === checkKey,
|
||||||
|
);
|
||||||
if (check) {
|
if (check) {
|
||||||
return check.result.message || '';
|
return check.result.message || '';
|
||||||
}
|
}
|
||||||
@@ -328,7 +330,7 @@ class DoctorSheet extends Component<Props, State> {
|
|||||||
/>
|
/>
|
||||||
{category.result.status !== 'SKIPPED' && (
|
{category.result.status !== 'SKIPPED' && (
|
||||||
<CategoryContainer>
|
<CategoryContainer>
|
||||||
{Object.values(category.checks).map(check => (
|
{Object.values(category.checks).map((check) => (
|
||||||
<HealthcheckDisplay
|
<HealthcheckDisplay
|
||||||
key={check.key}
|
key={check.key}
|
||||||
selected={check.key === this.state.selectedCheckKey}
|
selected={check.key === this.state.selectedCheckKey}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const ErrorBar = memo(function ErrorBar(props: Props) {
|
|||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
const urgentErrors = props.errors.filter(e => e.urgent);
|
const urgentErrors = props.errors.filter((e) => e.urgent);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBarContainer>
|
<ErrorBarContainer>
|
||||||
@@ -52,7 +52,7 @@ const ErrorBar = memo(function ErrorBar(props: Props) {
|
|||||||
))}
|
))}
|
||||||
</ErrorRows>
|
</ErrorRows>
|
||||||
<DismissAllErrors
|
<DismissAllErrors
|
||||||
onClick={() => setCollapsed(c => !c)}
|
onClick={() => setCollapsed((c) => !c)}
|
||||||
title="Show / hide errors">
|
title="Show / hide errors">
|
||||||
<Glyph
|
<Glyph
|
||||||
color={colors.white}
|
color={colors.white}
|
||||||
@@ -90,7 +90,7 @@ function ErrorTile({
|
|||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
{(error.details || error.error) && (
|
{(error.details || error.error) && (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setCollapsed(s => !s)}
|
onClick={() => setCollapsed((s) => !s)}
|
||||||
icon={collapsed ? `chevron-down` : 'chevron-up'}
|
icon={collapsed ? `chevron-down` : 'chevron-up'}
|
||||||
iconSize={12}
|
iconSize={12}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class ExportDataPluginSheet extends Component<Props, {}> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onChange={selectedArray => {
|
onChange={(selectedArray) => {
|
||||||
this.props.setSelectedPlugins(selectedArray);
|
this.props.setSelectedPlugins(selectedArray);
|
||||||
}}
|
}}
|
||||||
elements={this.props.availablePluginsToExport}
|
elements={this.props.availablePluginsToExport}
|
||||||
@@ -114,7 +114,7 @@ export default connect<StateFromProps, DispatchFromProps, OwnProps, Store>(
|
|||||||
pluginMessageQueue,
|
pluginMessageQueue,
|
||||||
connections: {selectedApp, clients},
|
connections: {selectedApp, clients},
|
||||||
}) => {
|
}) => {
|
||||||
const selectedClient = clients.find(o => {
|
const selectedClient = clients.find((o) => {
|
||||||
return o.id === selectedApp;
|
return o.id === selectedApp;
|
||||||
});
|
});
|
||||||
const availablePluginsToExport = getActivePersistentPlugins(
|
const availablePluginsToExport = getActivePersistentPlugins(
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ class RowComponent extends Component<RowComponentProps> {
|
|||||||
<Checkbox
|
<Checkbox
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
checked={selected}
|
checked={selected}
|
||||||
onChange={selected => {
|
onChange={(selected) => {
|
||||||
onChange(id, selected);
|
onChange(id, selected);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -145,7 +145,7 @@ class RowComponent extends Component<RowComponentProps> {
|
|||||||
<Radio
|
<Radio
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
checked={selected}
|
checked={selected}
|
||||||
onChange={selected => {
|
onChange={(selected) => {
|
||||||
onChange(id, selected);
|
onChange(id, selected);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -49,12 +49,7 @@ const shortenText = (text: string, MAX_CHARACTERS = 30): string => {
|
|||||||
if (text.length <= MAX_CHARACTERS) {
|
if (text.length <= MAX_CHARACTERS) {
|
||||||
return text;
|
return text;
|
||||||
} else {
|
} else {
|
||||||
return (
|
return text.split('').slice(0, MAX_CHARACTERS).join('') + '...';
|
||||||
text
|
|
||||||
.split('')
|
|
||||||
.slice(0, MAX_CHARACTERS)
|
|
||||||
.join('') + '...'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -94,7 +89,7 @@ class LocationsButton extends Component<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
updateBookmarks = () => {
|
updateBookmarks = () => {
|
||||||
readBookmarksFromDB().then(bookmarksMap => {
|
readBookmarksFromDB().then((bookmarksMap) => {
|
||||||
const bookmarks: Array<Bookmark> = [];
|
const bookmarks: Array<Bookmark> = [];
|
||||||
bookmarksMap.forEach((bookmark: Bookmark) => {
|
bookmarksMap.forEach((bookmark: Bookmark) => {
|
||||||
bookmarks.push(bookmark);
|
bookmarks.push(bookmark);
|
||||||
|
|||||||
@@ -124,6 +124,6 @@ function MetroButton({device}: Props) {
|
|||||||
|
|
||||||
export default connect<Props, {}, {}, State>(({connections: {devices}}) => ({
|
export default connect<Props, {}, {}, State>(({connections: {devices}}) => ({
|
||||||
device: devices.find(
|
device: devices.find(
|
||||||
device => device.os === 'Metro' && !device.isArchived,
|
(device) => device.os === 'Metro' && !device.isArchived,
|
||||||
) as MetroDevice,
|
) as MetroDevice,
|
||||||
}))(MetroButton);
|
}))(MetroButton);
|
||||||
|
|||||||
@@ -66,12 +66,12 @@ class Notifications extends PureComponent<Props, State> {
|
|||||||
onSelectPlugin={selectPlugin}
|
onSelectPlugin={selectPlugin}
|
||||||
logger={logger}
|
logger={logger}
|
||||||
defaultFilters={[
|
defaultFilters={[
|
||||||
...blacklistedPlugins.map(value => ({
|
...blacklistedPlugins.map((value) => ({
|
||||||
value,
|
value,
|
||||||
type: 'exclude',
|
type: 'exclude',
|
||||||
key: 'plugin',
|
key: 'plugin',
|
||||||
})),
|
})),
|
||||||
...blacklistedCategories.map(value => ({
|
...blacklistedCategories.map((value) => ({
|
||||||
value,
|
value,
|
||||||
type: 'exclude',
|
type: 'exclude',
|
||||||
key: 'category',
|
key: 'category',
|
||||||
|
|||||||
@@ -167,12 +167,12 @@ export default class Popover extends PureComponent<Props> {
|
|||||||
<>
|
<>
|
||||||
<Anchor src="./anchor.svg" key="anchor" />
|
<Anchor src="./anchor.svg" key="anchor" />
|
||||||
<PopoverContainer ref={this._setRef} key="popup">
|
<PopoverContainer ref={this._setRef} key="popup">
|
||||||
{this.props.sections.map(section => {
|
{this.props.sections.map((section) => {
|
||||||
if (section.items.length > 0) {
|
if (section.items.length > 0) {
|
||||||
return (
|
return (
|
||||||
<Section key={section.title}>
|
<Section key={section.title}>
|
||||||
<Heading>{section.title}</Heading>
|
<Heading>{section.title}</Heading>
|
||||||
{section.items.map(item => (
|
{section.items.map((item) => (
|
||||||
<PopoverItem key={item.title}>
|
<PopoverItem key={item.title}>
|
||||||
<ItemImage>{item.icon}</ItemImage>
|
<ItemImage>{item.icon}</ItemImage>
|
||||||
<ItemContent>
|
<ItemContent>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class PredefinedComment extends Component<{
|
|||||||
selected: boolean;
|
selected: boolean;
|
||||||
onClick: (_: unknown) => unknown;
|
onClick: (_: unknown) => unknown;
|
||||||
}> {
|
}> {
|
||||||
static Container = styled.div<{selected: boolean}>(props => {
|
static Container = styled.div<{selected: boolean}>((props) => {
|
||||||
return {
|
return {
|
||||||
border: '1px solid #f2f3f5',
|
border: '1px solid #f2f3f5',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
@@ -151,9 +151,9 @@ class FeedbackComponent extends Component<
|
|||||||
const selectedPredefinedComments: Array<string> = Object.entries(
|
const selectedPredefinedComments: Array<string> = Object.entries(
|
||||||
this.state.predefinedComments,
|
this.state.predefinedComments,
|
||||||
)
|
)
|
||||||
.map(x => ({comment: x[0], enabled: x[1]}))
|
.map((x) => ({comment: x[0], enabled: x[1]}))
|
||||||
.filter(x => x.enabled)
|
.filter((x) => x.enabled)
|
||||||
.map(x => x.comment);
|
.map((x) => x.comment);
|
||||||
const currentRating = this.state.rating;
|
const currentRating = this.state.rating;
|
||||||
if (currentRating) {
|
if (currentRating) {
|
||||||
this.props.submitComment(
|
this.props.submitComment(
|
||||||
@@ -189,9 +189,11 @@ class FeedbackComponent extends Component<
|
|||||||
}}>
|
}}>
|
||||||
<Glyph
|
<Glyph
|
||||||
name={
|
name={
|
||||||
(this.state.hoveredRating
|
(
|
||||||
? index < this.state.hoveredRating
|
this.state.hoveredRating
|
||||||
: index < (this.state.rating || 0))
|
? index < this.state.hoveredRating
|
||||||
|
: index < (this.state.rating || 0)
|
||||||
|
)
|
||||||
? 'star'
|
? 'star'
|
||||||
: 'star-outline'
|
: 'star-outline'
|
||||||
}
|
}
|
||||||
@@ -236,8 +238,8 @@ class FeedbackComponent extends Component<
|
|||||||
style={{height: 30, width: '100%'}}
|
style={{height: 30, width: '100%'}}
|
||||||
placeholder={this.props.promptData.commentPlaceholder}
|
placeholder={this.props.promptData.commentPlaceholder}
|
||||||
value={this.state.comment}
|
value={this.state.comment}
|
||||||
onChange={e => this.setState({comment: e.target.value})}
|
onChange={(e) => this.setState({comment: e.target.value})}
|
||||||
onKeyDown={e =>
|
onKeyDown={(e) =>
|
||||||
e.key == 'Enter' && this.onCommentSubmitted(this.state.comment)
|
e.key == 'Enter' && this.onCommentSubmitted(this.state.comment)
|
||||||
}
|
}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
@@ -296,7 +298,7 @@ class RatingButton extends Component<PropsFromState, State> {
|
|||||||
constructor(props: PropsFromState) {
|
constructor(props: PropsFromState) {
|
||||||
super(props);
|
super(props);
|
||||||
if (GK.get('flipper_rating')) {
|
if (GK.get('flipper_rating')) {
|
||||||
UserFeedback.getPrompt().then(prompt => {
|
UserFeedback.getPrompt().then((prompt) => {
|
||||||
this.setState({promptData: prompt});
|
this.setState({promptData: prompt});
|
||||||
setTimeout(this.triggerPopover.bind(this), 30000);
|
setTimeout(this.triggerPopover.bind(this), 30000);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class ScreenCaptureButtons extends Component<Props, State> {
|
|||||||
if (!selectedDevice) {
|
if (!selectedDevice) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const path = await selectedDevice.stopScreenCapture().catch(e => {
|
const path = await selectedDevice.stopScreenCapture().catch((e) => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
});
|
});
|
||||||
path ? openFile(path) : 0;
|
path ? openFile(path) : 0;
|
||||||
@@ -107,7 +107,7 @@ class ScreenCaptureButtons extends Component<Props, State> {
|
|||||||
this.setState({
|
this.setState({
|
||||||
recording: true,
|
recording: true,
|
||||||
});
|
});
|
||||||
this.startRecording().catch(e => {
|
this.startRecording().catch((e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
recording: false,
|
recording: false,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
<ToggledSection
|
<ToggledSection
|
||||||
label="Android Developer"
|
label="Android Developer"
|
||||||
toggled={enableAndroid}
|
toggled={enableAndroid}
|
||||||
onChange={v => {
|
onChange={(v) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
updatedSettings: {
|
updatedSettings: {
|
||||||
...this.state.updatedSettings,
|
...this.state.updatedSettings,
|
||||||
@@ -107,7 +107,7 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
label="Android SDK Location"
|
label="Android SDK Location"
|
||||||
resetValue={DEFAULT_ANDROID_SDK_PATH}
|
resetValue={DEFAULT_ANDROID_SDK_PATH}
|
||||||
defaultValue={androidHome}
|
defaultValue={androidHome}
|
||||||
onChange={v => {
|
onChange={(v) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
updatedSettings: {
|
updatedSettings: {
|
||||||
...this.state.updatedSettings,
|
...this.state.updatedSettings,
|
||||||
@@ -121,7 +121,7 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
label="iOS Developer"
|
label="iOS Developer"
|
||||||
toggled={enableIOS && this.props.platform === 'darwin'}
|
toggled={enableIOS && this.props.platform === 'darwin'}
|
||||||
frozen={this.props.platform !== 'darwin'}
|
frozen={this.props.platform !== 'darwin'}
|
||||||
onChange={v => {
|
onChange={(v) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
updatedSettings: {...this.state.updatedSettings, enableIOS: v},
|
updatedSettings: {...this.state.updatedSettings, enableIOS: v},
|
||||||
});
|
});
|
||||||
@@ -140,7 +140,7 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
</ToggledSection>
|
</ToggledSection>
|
||||||
<LauncherSettingsPanel
|
<LauncherSettingsPanel
|
||||||
isPrefetchingEnabled={enablePrefetching}
|
isPrefetchingEnabled={enablePrefetching}
|
||||||
onEnablePrefetchingChange={v => {
|
onEnablePrefetchingChange={(v) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
updatedSettings: {
|
updatedSettings: {
|
||||||
...this.state.updatedSettings,
|
...this.state.updatedSettings,
|
||||||
@@ -149,7 +149,7 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
isLocalPinIgnored={this.state.updatedLauncherSettings.ignoreLocalPin}
|
isLocalPinIgnored={this.state.updatedLauncherSettings.ignoreLocalPin}
|
||||||
onIgnoreLocalPinChange={v => {
|
onIgnoreLocalPinChange={(v) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
updatedLauncherSettings: {
|
updatedLauncherSettings: {
|
||||||
...this.state.updatedLauncherSettings,
|
...this.state.updatedLauncherSettings,
|
||||||
@@ -161,8 +161,8 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
<ToggledSection
|
<ToggledSection
|
||||||
label="React Native keyboard shortcuts"
|
label="React Native keyboard shortcuts"
|
||||||
toggled={reactNative.shortcuts.enabled}
|
toggled={reactNative.shortcuts.enabled}
|
||||||
onChange={enabled => {
|
onChange={(enabled) => {
|
||||||
this.setState(prevState => ({
|
this.setState((prevState) => ({
|
||||||
updatedSettings: {
|
updatedSettings: {
|
||||||
...prevState.updatedSettings,
|
...prevState.updatedSettings,
|
||||||
reactNative: {
|
reactNative: {
|
||||||
@@ -178,8 +178,8 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
<KeyboardShortcutInput
|
<KeyboardShortcutInput
|
||||||
label="Reload application"
|
label="Reload application"
|
||||||
value={reactNative.shortcuts.reload}
|
value={reactNative.shortcuts.reload}
|
||||||
onChange={reload => {
|
onChange={(reload) => {
|
||||||
this.setState(prevState => ({
|
this.setState((prevState) => ({
|
||||||
updatedSettings: {
|
updatedSettings: {
|
||||||
...prevState.updatedSettings,
|
...prevState.updatedSettings,
|
||||||
reactNative: {
|
reactNative: {
|
||||||
@@ -196,8 +196,8 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
<KeyboardShortcutInput
|
<KeyboardShortcutInput
|
||||||
label="Open developer menu"
|
label="Open developer menu"
|
||||||
value={reactNative.shortcuts.openDevMenu}
|
value={reactNative.shortcuts.openDevMenu}
|
||||||
onChange={openDevMenu => {
|
onChange={(openDevMenu) => {
|
||||||
this.setState(prevState => ({
|
this.setState((prevState) => ({
|
||||||
updatedSettings: {
|
updatedSettings: {
|
||||||
...prevState.updatedSettings,
|
...prevState.updatedSettings,
|
||||||
reactNative: {
|
reactNative: {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const Uploading = styled(Text)({
|
|||||||
marginTop: 15,
|
marginTop: 15,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function(props: {
|
export default function (props: {
|
||||||
statusMessage: string;
|
statusMessage: string;
|
||||||
statusUpdate: string | null;
|
statusUpdate: string | null;
|
||||||
hideNavButtons?: boolean;
|
hideNavButtons?: boolean;
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class Sheet extends Component<Props, State> {
|
|||||||
in={Boolean(this.props.activeSheet) && this.state.isVisible}
|
in={Boolean(this.props.activeSheet) && this.state.isVisible}
|
||||||
timeout={0}
|
timeout={0}
|
||||||
onExited={() => this.props.onHideSheet()}>
|
onExited={() => this.props.onHideSheet()}>
|
||||||
{state => (
|
{(state) => (
|
||||||
<DialogContainer state={state}>
|
<DialogContainer state={state}>
|
||||||
<div
|
<div
|
||||||
/* This is the target for React.portal, it should not be
|
/* This is the target for React.portal, it should not be
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ class SignInSheet extends Component<Props, State> {
|
|||||||
disabled={this.state.loading}
|
disabled={this.state.loading}
|
||||||
placeholder="Nuclide Access Token"
|
placeholder="Nuclide Access Token"
|
||||||
value={this.state.token}
|
value={this.state.token}
|
||||||
onChange={e => this.setState({token: e.target.value})}
|
onChange={(e) => this.setState({token: e.target.value})}
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
{this.state.error && (
|
{this.state.error && (
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ export default connect<StateFromProps, DispatchFromProps, OwnProps, State>(
|
|||||||
);
|
);
|
||||||
const navPluginIsActive = !!pluginStates[navigationPluginKey];
|
const navPluginIsActive = !!pluginStates[navigationPluginKey];
|
||||||
const isMetroActive = !!devices.find(
|
const isMetroActive = !!devices.find(
|
||||||
device => device.os === 'Metro' && !device.isArchived,
|
(device) => device.os === 'Metro' && !device.isArchived,
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export default class UpdateIndicator extends React.PureComponent<Props, State> {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (isProduction() && config().launcherEnabled) {
|
if (isProduction() && config().launcherEnabled) {
|
||||||
reportPlatformFailures(
|
reportPlatformFailures(
|
||||||
checkForUpdate(this.props.version).then(res => {
|
checkForUpdate(this.props.version).then((res) => {
|
||||||
if (res.kind === 'error') {
|
if (res.kind === 'error') {
|
||||||
console.warn('Version check failure: ', res.msg);
|
console.warn('Version check failure: ', res.msg);
|
||||||
throw new Error(res.msg);
|
throw new Error(res.msg);
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class UserAccount extends PureComponent<Props> {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (config.showLogin) {
|
if (config.showLogin) {
|
||||||
getUser().catch(error => {
|
getUser().catch((error) => {
|
||||||
if (error === USER_UNAUTHORIZED || error === USER_NOT_SIGNEDIN) {
|
if (error === USER_UNAUTHORIZED || error === USER_NOT_SIGNEDIN) {
|
||||||
this.openLogin();
|
this.openLogin();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export default class VideoRecordingButton extends Component<Props, State> {
|
|||||||
this.setState({
|
this.setState({
|
||||||
recording: true,
|
recording: true,
|
||||||
});
|
});
|
||||||
selectedDevice.startScreenCapture(videoPath).catch(e => {
|
selectedDevice.startScreenCapture(videoPath).catch((e) => {
|
||||||
console.error('Screen recording failed:', e);
|
console.error('Screen recording failed:', e);
|
||||||
this.setState({
|
this.setState({
|
||||||
recording: false,
|
recording: false,
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ const SidebarSection: React.FC<{
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SidebarSectionButton
|
<SidebarSectionButton
|
||||||
onClick={() => setCollapsed(s => !s)}
|
onClick={() => setCollapsed((s) => !s)}
|
||||||
level={level}
|
level={level}
|
||||||
color={color}
|
color={color}
|
||||||
collapsed={collapsed}>
|
collapsed={collapsed}>
|
||||||
@@ -212,7 +212,7 @@ class MainSidebar2 extends PureComponent<Props, State> {
|
|||||||
<Sidebar position="left" width={250} backgroundColor={colors.light02}>
|
<Sidebar position="left" width={250} backgroundColor={colors.light02}>
|
||||||
<Plugins>
|
<Plugins>
|
||||||
{devices.length ? (
|
{devices.length ? (
|
||||||
devices.map(device => this.renderDevice(device))
|
devices.map((device) => this.renderDevice(device))
|
||||||
) : (
|
) : (
|
||||||
<NoDevices />
|
<NoDevices />
|
||||||
)}
|
)}
|
||||||
@@ -234,7 +234,7 @@ class MainSidebar2 extends PureComponent<Props, State> {
|
|||||||
selectedDevice,
|
selectedDevice,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const clients = getAvailableClients(device, this.props.clients);
|
const clients = getAvailableClients(device, this.props.clients);
|
||||||
const devicePluginsItems = device.devicePlugins.map(pluginName => {
|
const devicePluginsItems = device.devicePlugins.map((pluginName) => {
|
||||||
const plugin = this.props.devicePlugins.get(pluginName)!;
|
const plugin = this.props.devicePlugins.get(pluginName)!;
|
||||||
return (
|
return (
|
||||||
<PluginSidebarListItem
|
<PluginSidebarListItem
|
||||||
@@ -272,7 +272,7 @@ class MainSidebar2 extends PureComponent<Props, State> {
|
|||||||
) : (
|
) : (
|
||||||
<div style={{marginTop: 6}}>{devicePluginsItems}</div>
|
<div style={{marginTop: 6}}>{devicePluginsItems}</div>
|
||||||
)}
|
)}
|
||||||
{clients.map(client => (
|
{clients.map((client) => (
|
||||||
<PluginList
|
<PluginList
|
||||||
device={device}
|
device={device}
|
||||||
key={client.id}
|
key={client.id}
|
||||||
@@ -293,7 +293,7 @@ class MainSidebar2 extends PureComponent<Props, State> {
|
|||||||
const {uninitializedClients} = this.props;
|
const {uninitializedClients} = this.props;
|
||||||
return uninitializedClients.length > 0 ? (
|
return uninitializedClients.length > 0 ? (
|
||||||
<SidebarSection title="Connecting..." key="unitializedClients" level={1}>
|
<SidebarSection title="Connecting..." key="unitializedClients" level={1}>
|
||||||
{uninitializedClients.map(entry => (
|
{uninitializedClients.map((entry) => (
|
||||||
<SidebarSection
|
<SidebarSection
|
||||||
color={getColorByApp(entry.client.appName)}
|
color={getColorByApp(entry.client.appName)}
|
||||||
key={JSON.stringify(entry.client)}
|
key={JSON.stringify(entry.client)}
|
||||||
@@ -387,14 +387,14 @@ function groupPluginsByCategory(plugins: FlipperPlugins): PluginsByCategory {
|
|||||||
const sortedPlugins = plugins.slice().sort(sortPluginsByName);
|
const sortedPlugins = plugins.slice().sort(sortPluginsByName);
|
||||||
const byCategory: {[cat: string]: FlipperPlugins} = {};
|
const byCategory: {[cat: string]: FlipperPlugins} = {};
|
||||||
const res: PluginsByCategory = [];
|
const res: PluginsByCategory = [];
|
||||||
sortedPlugins.forEach(plugin => {
|
sortedPlugins.forEach((plugin) => {
|
||||||
const category = plugin.category || '';
|
const category = plugin.category || '';
|
||||||
(byCategory[category] || (byCategory[category] = [])).push(plugin);
|
(byCategory[category] || (byCategory[category] = [])).push(plugin);
|
||||||
});
|
});
|
||||||
// Sort categories
|
// Sort categories
|
||||||
Object.keys(byCategory)
|
Object.keys(byCategory)
|
||||||
.sort()
|
.sort()
|
||||||
.forEach(category => {
|
.forEach((category) => {
|
||||||
res.push([category, byCategory[category]]);
|
res.push([category, byCategory[category]]);
|
||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
@@ -464,7 +464,7 @@ const PluginList = memo(function PluginList({
|
|||||||
// client is a mutable structure, so we need the event emitter to detect the addition of plugins....
|
// client is a mutable structure, so we need the event emitter to detect the addition of plugins....
|
||||||
const [_, setPluginsChanged] = useState(0);
|
const [_, setPluginsChanged] = useState(0);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const listener = () => setPluginsChanged(v => v + 1);
|
const listener = () => setPluginsChanged((v) => v + 1);
|
||||||
client.on('plugins-change', listener);
|
client.on('plugins-change', listener);
|
||||||
return () => {
|
return () => {
|
||||||
client.off('plugins-change', listener);
|
client.off('plugins-change', listener);
|
||||||
@@ -494,7 +494,7 @@ const PluginList = memo(function PluginList({
|
|||||||
const selectedNonFavoritePlugin =
|
const selectedNonFavoritePlugin =
|
||||||
selectedApp === client.id &&
|
selectedApp === client.id &&
|
||||||
client.plugins.includes(selectedPlugin!) &&
|
client.plugins.includes(selectedPlugin!) &&
|
||||||
!favoritePlugins.find(plugin => plugin.id === selectedPlugin);
|
!favoritePlugins.find((plugin) => plugin.id === selectedPlugin);
|
||||||
const allPluginsStarred = favoritePlugins.length === allPlugins.length;
|
const allPluginsStarred = favoritePlugins.length === allPlugins.length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -526,7 +526,7 @@ const PluginList = memo(function PluginList({
|
|||||||
defaultCollapsed={
|
defaultCollapsed={
|
||||||
favoritePlugins.length > 0 && !selectedNonFavoritePlugin
|
favoritePlugins.length > 0 && !selectedNonFavoritePlugin
|
||||||
}
|
}
|
||||||
title={collapsed => (
|
title={(collapsed) => (
|
||||||
<ShowMoreButton collapsed={collapsed}>
|
<ShowMoreButton collapsed={collapsed}>
|
||||||
<Glyph
|
<Glyph
|
||||||
color={colors.macOSTitleBarIconBlur}
|
color={colors.macOSTitleBarIconBlur}
|
||||||
@@ -585,7 +585,7 @@ const PluginsByCategory = memo(function PluginsByCategory({
|
|||||||
<CategoryName>{category}</CategoryName>
|
<CategoryName>{category}</CategoryName>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
)}
|
)}
|
||||||
{plugins.map(plugin => (
|
{plugins.map((plugin) => (
|
||||||
<PluginSidebarListItem
|
<PluginSidebarListItem
|
||||||
key={plugin.id}
|
key={plugin.id}
|
||||||
isActive={
|
isActive={
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ function MainSidebarUtilsSection({
|
|||||||
return (
|
return (
|
||||||
<div style={{flexShrink: 0, borderTop: `1px solid ${colors.blackAlpha10}`}}>
|
<div style={{flexShrink: 0, borderTop: `1px solid ${colors.blackAlpha10}`}}>
|
||||||
{showWatchDebugRoot &&
|
{showWatchDebugRoot &&
|
||||||
(function() {
|
(function () {
|
||||||
const active = isStaticViewActive(staticView, WatchTools);
|
const active = isStaticViewActive(staticView, WatchTools);
|
||||||
return (
|
return (
|
||||||
<ListItem
|
<ListItem
|
||||||
@@ -74,7 +74,7 @@ function MainSidebarUtilsSection({
|
|||||||
);
|
);
|
||||||
})()}
|
})()}
|
||||||
<RenderNotificationsEntry />
|
<RenderNotificationsEntry />
|
||||||
{(function() {
|
{(function () {
|
||||||
const active = isStaticViewActive(staticView, SupportRequestFormV2);
|
const active = isStaticViewActive(staticView, SupportRequestFormV2);
|
||||||
return (
|
return (
|
||||||
<ListItem
|
<ListItem
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ const PluginShape = styled(FlexBox)<{
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
export const PluginName = styled(Text)<{isActive?: boolean; count?: number}>(
|
export const PluginName = styled(Text)<{isActive?: boolean; count?: number}>(
|
||||||
props => ({
|
(props) => ({
|
||||||
minWidth: 0,
|
minWidth: 0,
|
||||||
textOverflow: 'ellipsis',
|
textOverflow: 'ellipsis',
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: 'nowrap',
|
||||||
@@ -139,7 +139,7 @@ export const PluginSidebarListItem: React.FC<{
|
|||||||
provided?: any;
|
provided?: any;
|
||||||
onFavorite?: () => void;
|
onFavorite?: () => void;
|
||||||
starred?: boolean; // undefined means: not starrable
|
starred?: boolean; // undefined means: not starrable
|
||||||
}> = function(props) {
|
}> = function (props) {
|
||||||
const {isActive, plugin, onFavorite, starred} = props;
|
const {isActive, plugin, onFavorite, starred} = props;
|
||||||
const iconColor = getColorByApp(props.app);
|
const iconColor = getColorByApp(props.app);
|
||||||
const domRef = useRef<HTMLDivElement>(null);
|
const domRef = useRef<HTMLDivElement>(null);
|
||||||
@@ -242,13 +242,13 @@ export function getFavoritePlugins(
|
|||||||
}
|
}
|
||||||
// for archived plugins, all stored plugins are enabled
|
// for archived plugins, all stored plugins are enabled
|
||||||
return allPlugins.filter(
|
return allPlugins.filter(
|
||||||
plugin => client.plugins.indexOf(plugin.id) !== -1,
|
(plugin) => client.plugins.indexOf(plugin.id) !== -1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!starredPlugins || !starredPlugins.length) {
|
if (!starredPlugins || !starredPlugins.length) {
|
||||||
return returnFavoredPlugins ? [] : allPlugins;
|
return returnFavoredPlugins ? [] : allPlugins;
|
||||||
}
|
}
|
||||||
return allPlugins.filter(plugin => {
|
return allPlugins.filter((plugin) => {
|
||||||
const idx = starredPlugins.indexOf(plugin.id);
|
const idx = starredPlugins.indexOf(plugin.id);
|
||||||
return idx === -1 ? !returnFavoredPlugins : returnFavoredPlugins;
|
return idx === -1 ? !returnFavoredPlugins : returnFavoredPlugins;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ class PluginDebugger extends Component<Props> {
|
|||||||
: p.entry
|
: p.entry
|
||||||
: 'Native Plugin';
|
: 'Native Plugin';
|
||||||
|
|
||||||
this.props.gatekeepedPlugins.forEach(plugin =>
|
this.props.gatekeepedPlugins.forEach((plugin) =>
|
||||||
rows.push(
|
rows.push(
|
||||||
this.buildRow(
|
this.buildRow(
|
||||||
plugin.name,
|
plugin.name,
|
||||||
@@ -164,7 +164,7 @@ class PluginDebugger extends Component<Props> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.props.devicePlugins.forEach(plugin =>
|
this.props.devicePlugins.forEach((plugin) =>
|
||||||
rows.push(
|
rows.push(
|
||||||
this.buildRow(
|
this.buildRow(
|
||||||
plugin.id,
|
plugin.id,
|
||||||
@@ -176,7 +176,7 @@ class PluginDebugger extends Component<Props> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.props.clientPlugins.forEach(plugin =>
|
this.props.clientPlugins.forEach((plugin) =>
|
||||||
rows.push(
|
rows.push(
|
||||||
this.buildRow(
|
this.buildRow(
|
||||||
plugin.id,
|
plugin.id,
|
||||||
@@ -188,7 +188,7 @@ class PluginDebugger extends Component<Props> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.props.disabledPlugins.forEach(plugin =>
|
this.props.disabledPlugins.forEach((plugin) =>
|
||||||
rows.push(
|
rows.push(
|
||||||
this.buildRow(
|
this.buildRow(
|
||||||
plugin.name,
|
plugin.name,
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ const PluginInstaller = function props(props: Props) {
|
|||||||
<Toolbar>
|
<Toolbar>
|
||||||
<SearchBox>
|
<SearchBox>
|
||||||
<SearchInput
|
<SearchInput
|
||||||
onChange={e => setQuery(e.target.value)}
|
onChange={(e) => setQuery(e.target.value)}
|
||||||
value={query}
|
value={query}
|
||||||
placeholder="Search Flipper plugins..."
|
placeholder="Search Flipper plugins..."
|
||||||
/>
|
/>
|
||||||
@@ -414,7 +414,9 @@ function useNPMSearch(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setSearchResults(
|
setSearchResults(
|
||||||
hits.filter(hit => !installedPlugins.has(hit.name)).map(liftUpdatable),
|
hits
|
||||||
|
.filter((hit) => !installedPlugins.has(hit.name))
|
||||||
|
.map(liftUpdatable),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Clean up: if query changes while we're searching, abandon results.
|
// Clean up: if query changes while we're searching, abandon results.
|
||||||
@@ -445,7 +447,7 @@ export default connect<PropsFromState, DispatchFromProps, OwnProps, AppState>(
|
|||||||
}),
|
}),
|
||||||
(dispatch: Dispatch<Action<any>>) => ({
|
(dispatch: Dispatch<Action<any>>) => ({
|
||||||
refreshInstalledPlugins: () => {
|
refreshInstalledPlugins: () => {
|
||||||
readInstalledPlugins().then(plugins =>
|
readInstalledPlugins().then((plugins) =>
|
||||||
dispatch(registerInstalledPlugins(plugins)),
|
dispatch(registerInstalledPlugins(plugins)),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const Row = styled(FlexColumn)({
|
|||||||
|
|
||||||
type Tabs = 'Plugin Status' | 'Install Plugins';
|
type Tabs = 'Plugin Status' | 'Install Plugins';
|
||||||
|
|
||||||
export default function(props: {onHide: () => any}) {
|
export default function (props: {onHide: () => any}) {
|
||||||
const [tab, setTab] = useState<Tabs>('Plugin Status');
|
const [tab, setTab] = useState<Tabs>('Plugin Status');
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export default function PluginPackageInstaller({
|
|||||||
<Toolbar>
|
<Toolbar>
|
||||||
<FileSelector
|
<FileSelector
|
||||||
placeholderText="Specify path to a Flipper package or just drag and drop it here..."
|
placeholderText="Specify path to a Flipper package or just drag and drop it here..."
|
||||||
onPathChanged={e => {
|
onPathChanged={(e) => {
|
||||||
setPath(e.path);
|
setPath(e.path);
|
||||||
setIsPathValid(e.isValid);
|
setIsPathValid(e.isValid);
|
||||||
setError(undefined);
|
setError(undefined);
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const ShortcutKeysContainer = styled(FlexRow)<{invalid: boolean}>(
|
|||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
padding: 2,
|
padding: 2,
|
||||||
},
|
},
|
||||||
props => ({borderColor: props.invalid ? colors.red : colors.light15}),
|
(props) => ({borderColor: props.invalid ? colors.red : colors.light15}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const ShortcutKeyContainer = styled.div({
|
const ShortcutKeyContainer = styled.div({
|
||||||
@@ -183,7 +183,7 @@ const KeyboardShortcutInput = (props: {
|
|||||||
([metaKey, altKey, ctrlKey, shiftKey].includes(true) &&
|
([metaKey, altKey, ctrlKey, shiftKey].includes(true) &&
|
||||||
character !== '') ||
|
character !== '') ||
|
||||||
[metaKey, altKey, ctrlKey, shiftKey, character].every(
|
[metaKey, altKey, ctrlKey, shiftKey, character].every(
|
||||||
value => !value,
|
(value) => !value,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
500,
|
500,
|
||||||
|
|||||||
@@ -59,13 +59,13 @@ export function FilePathConfigField(props: {
|
|||||||
const [value, setValue] = useState(props.defaultValue);
|
const [value, setValue] = useState(props.defaultValue);
|
||||||
const [isValid, setIsValid] = useState(true);
|
const [isValid, setIsValid] = useState(true);
|
||||||
fs.stat(value)
|
fs.stat(value)
|
||||||
.then(stat => stat.isDirectory())
|
.then((stat) => stat.isDirectory())
|
||||||
.then(valid => {
|
.then((valid) => {
|
||||||
if (valid !== isValid) {
|
if (valid !== isValid) {
|
||||||
setIsValid(valid);
|
setIsValid(valid);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(_ => setIsValid(false));
|
.catch((_) => setIsValid(false));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigFieldContainer>
|
<ConfigFieldContainer>
|
||||||
@@ -74,17 +74,17 @@ export function FilePathConfigField(props: {
|
|||||||
placeholder={props.label}
|
placeholder={props.label}
|
||||||
value={value}
|
value={value}
|
||||||
isValid={isValid}
|
isValid={isValid}
|
||||||
onChange={e => {
|
onChange={(e) => {
|
||||||
setValue(e.target.value);
|
setValue(e.target.value);
|
||||||
props.onChange(e.target.value);
|
props.onChange(e.target.value);
|
||||||
fs.stat(e.target.value)
|
fs.stat(e.target.value)
|
||||||
.then(stat => stat.isDirectory())
|
.then((stat) => stat.isDirectory())
|
||||||
.then(valid => {
|
.then((valid) => {
|
||||||
if (valid !== isValid) {
|
if (valid !== isValid) {
|
||||||
setIsValid(valid);
|
setIsValid(valid);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(_ => setIsValid(false));
|
.catch((_) => setIsValid(false));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<FlexColumn
|
<FlexColumn
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ export function createTablePlugin<T extends RowData>(props: Props<T>) {
|
|||||||
let paste = '';
|
let paste = '';
|
||||||
const mapFn = (row: TableBodyRow) =>
|
const mapFn = (row: TableBodyRow) =>
|
||||||
Object.keys(props.columns)
|
Object.keys(props.columns)
|
||||||
.map(key => textContent(row.columns[key].value))
|
.map((key) => textContent(row.columns[key].value))
|
||||||
.join('\t');
|
.join('\t');
|
||||||
|
|
||||||
if (this.state.selectedIds.length > 0) {
|
if (this.state.selectedIds.length > 0) {
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ export default class AndroidDevice extends BaseDevice {
|
|||||||
super(serial, deviceType, title, 'Android');
|
super(serial, deviceType, title, 'Android');
|
||||||
this.adb = adb;
|
this.adb = adb;
|
||||||
this.icon = 'icons/android.svg';
|
this.icon = 'icons/android.svg';
|
||||||
this.adb.openLogcat(this.serial).then(reader => {
|
this.adb.openLogcat(this.serial).then((reader) => {
|
||||||
reader.on('entry', entry => {
|
reader.on('entry', (entry) => {
|
||||||
let type: LogLevel = 'unknown';
|
let type: LogLevel = 'unknown';
|
||||||
if (entry.priority === Priority.VERBOSE) {
|
if (entry.priority === Priority.VERBOSE) {
|
||||||
type = 'verbose';
|
type = 'verbose';
|
||||||
@@ -69,7 +69,7 @@ export default class AndroidDevice extends BaseDevice {
|
|||||||
|
|
||||||
reverse(ports: [number, number]): Promise<void> {
|
reverse(ports: [number, number]): Promise<void> {
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
ports.map(port =>
|
ports.map((port) =>
|
||||||
this.adb.reverse(this.serial, `tcp:${port}`, `tcp:${port}`),
|
this.adb.reverse(this.serial, `tcp:${port}`, `tcp:${port}`),
|
||||||
),
|
),
|
||||||
).then(() => {
|
).then(() => {
|
||||||
@@ -100,7 +100,7 @@ export default class AndroidDevice extends BaseDevice {
|
|||||||
|
|
||||||
screenshot(): Promise<Buffer> {
|
screenshot(): Promise<Buffer> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.adb.screencap(this.serial).then(stream => {
|
this.adb.screencap(this.serial).then((stream) => {
|
||||||
const chunks: Array<Buffer> = [];
|
const chunks: Array<Buffer> = [];
|
||||||
stream
|
stream
|
||||||
.on('data', (chunk: Buffer) => chunks.push(chunk))
|
.on('data', (chunk: Buffer) => chunks.push(chunk))
|
||||||
@@ -137,13 +137,8 @@ export default class AndroidDevice extends BaseDevice {
|
|||||||
const fileSize = await this.adb
|
const fileSize = await this.adb
|
||||||
.shell(this.serial, `du "${filePath}"`)
|
.shell(this.serial, `du "${filePath}"`)
|
||||||
.then(adb.util.readAll)
|
.then(adb.util.readAll)
|
||||||
.then((output: Buffer) =>
|
.then((output: Buffer) => output.toString().trim().split('\t'))
|
||||||
output
|
.then((x) => Number(x[0]));
|
||||||
.toString()
|
|
||||||
.trim()
|
|
||||||
.split('\t'),
|
|
||||||
)
|
|
||||||
.then(x => Number(x[0]));
|
|
||||||
|
|
||||||
// 4 is what an empty file (touch file) already takes up, so it's
|
// 4 is what an empty file (touch file) already takes up, so it's
|
||||||
// definitely not a valid video file.
|
// definitely not a valid video file.
|
||||||
@@ -158,7 +153,7 @@ export default class AndroidDevice extends BaseDevice {
|
|||||||
this.recordingProcess = this.adb
|
this.recordingProcess = this.adb
|
||||||
.shell(this.serial, `screenrecord --bugreport "${recordingLocation}"`)
|
.shell(this.serial, `screenrecord --bugreport "${recordingLocation}"`)
|
||||||
.then(adb.util.readAll)
|
.then(adb.util.readAll)
|
||||||
.then(async output => {
|
.then(async (output) => {
|
||||||
const isValid = await this.isValidFile(recordingLocation);
|
const isValid = await this.isValidFile(recordingLocation);
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
const outputMessage = output.toString().trim();
|
const outputMessage = output.toString().trim();
|
||||||
@@ -168,18 +163,18 @@ export default class AndroidDevice extends BaseDevice {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(
|
.then(
|
||||||
_ =>
|
(_) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
this.adb.pull(this.serial, recordingLocation).then(stream => {
|
this.adb.pull(this.serial, recordingLocation).then((stream) => {
|
||||||
stream.on('end', resolve);
|
stream.on('end', resolve);
|
||||||
stream.on('error', reject);
|
stream.on('error', reject);
|
||||||
stream.pipe(createWriteStream(destination));
|
stream.pipe(createWriteStream(destination));
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.then(_ => destination);
|
.then((_) => destination);
|
||||||
|
|
||||||
return this.recordingProcess.then(_ => {});
|
return this.recordingProcess.then((_) => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
async stopScreenCapture(): Promise<string> {
|
async stopScreenCapture(): Promise<string> {
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ export default class BaseDevice {
|
|||||||
|
|
||||||
_notifyLogListeners(entry: DeviceLogEntry) {
|
_notifyLogListeners(entry: DeviceLogEntry) {
|
||||||
if (this.logListeners.size > 0) {
|
if (this.logListeners.size > 0) {
|
||||||
this.logListeners.forEach(listener => {
|
this.logListeners.forEach((listener) => {
|
||||||
// prevent breaking other listeners, if one listener doesn't work.
|
// prevent breaking other listeners, if one listener doesn't work.
|
||||||
try {
|
try {
|
||||||
listener(entry);
|
listener(entry);
|
||||||
@@ -176,8 +176,8 @@ export default class BaseDevice {
|
|||||||
|
|
||||||
loadDevicePlugins(devicePlugins?: Map<string, typeof FlipperDevicePlugin>) {
|
loadDevicePlugins(devicePlugins?: Map<string, typeof FlipperDevicePlugin>) {
|
||||||
this.devicePlugins = Array.from(devicePlugins ? devicePlugins.values() : [])
|
this.devicePlugins = Array.from(devicePlugins ? devicePlugins.values() : [])
|
||||||
.filter(plugin => plugin.supportsDevice(this))
|
.filter((plugin) => plugin.supportsDevice(this))
|
||||||
.sort(sortPluginsByName)
|
.sort(sortPluginsByName)
|
||||||
.map(plugin => plugin.id);
|
.map((plugin) => plugin.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export default class IOSDevice extends BaseDevice {
|
|||||||
const command = `xcrun simctl io booted screenshot ${tmpFilePath}`;
|
const command = `xcrun simctl io booted screenshot ${tmpFilePath}`;
|
||||||
return promisify(exec)(command)
|
return promisify(exec)(command)
|
||||||
.then(() => promisify(fs.readFile)(tmpFilePath))
|
.then(() => promisify(fs.readFile)(tmpFilePath))
|
||||||
.then(buffer => {
|
.then((buffer) => {
|
||||||
return promisify(fs.unlink)(tmpFilePath).then(() => buffer);
|
return promisify(fs.unlink)(tmpFilePath).then(() => buffer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -213,7 +213,7 @@ export default class IOSDevice extends BaseDevice {
|
|||||||
this.recordingLocation = undefined;
|
this.recordingLocation = undefined;
|
||||||
return recordingLocation!;
|
return recordingLocation!;
|
||||||
})
|
})
|
||||||
.catch(_e => {
|
.catch((_e) => {
|
||||||
this.recordingLocation = undefined;
|
this.recordingLocation = undefined;
|
||||||
console.error(_e);
|
console.error(_e);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ export default class MetroDevice extends BaseDevice {
|
|||||||
type,
|
type,
|
||||||
tag: message.type,
|
tag: message.type,
|
||||||
message: message.data
|
message: message.data
|
||||||
.map(v =>
|
.map((v) =>
|
||||||
v && typeof v === 'object' ? JSON.stringify(v, null, 2) : v,
|
v && typeof v === 'object' ? JSON.stringify(v, null, 2) : v,
|
||||||
)
|
)
|
||||||
.join(' '),
|
.join(' '),
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ beforeEach(() => {
|
|||||||
test('dispatcher dispatches REGISTER_PLUGINS', () => {
|
test('dispatcher dispatches REGISTER_PLUGINS', () => {
|
||||||
dispatcher(mockStore, logger);
|
dispatcher(mockStore, logger);
|
||||||
const actions = mockStore.getActions();
|
const actions = mockStore.getActions();
|
||||||
expect(actions.map(a => a.type)).toContain('REGISTER_PLUGINS');
|
expect(actions.map((a) => a.type)).toContain('REGISTER_PLUGINS');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getDynamicPlugins returns empty array on errors', () => {
|
test('getDynamicPlugins returns empty array on errors', () => {
|
||||||
|
|||||||
@@ -33,14 +33,14 @@ function createDevice(
|
|||||||
|
|
||||||
adbClient
|
adbClient
|
||||||
.getProperties(device.id)
|
.getProperties(device.id)
|
||||||
.then(async props => {
|
.then(async (props) => {
|
||||||
try {
|
try {
|
||||||
let name = props['ro.product.model'];
|
let name = props['ro.product.model'];
|
||||||
if (type === 'emulator') {
|
if (type === 'emulator') {
|
||||||
name = (await getRunningEmulatorName(device.id)) || name;
|
name = (await getRunningEmulatorName(device.id)) || name;
|
||||||
}
|
}
|
||||||
const isKaiOSDevice = Object.keys(props).some(
|
const isKaiOSDevice = Object.keys(props).some(
|
||||||
name => name.startsWith('kaios') || name.startsWith('ro.kaios'),
|
(name) => name.startsWith('kaios') || name.startsWith('ro.kaios'),
|
||||||
);
|
);
|
||||||
const androidLikeDevice = new (isKaiOSDevice
|
const androidLikeDevice = new (isKaiOSDevice
|
||||||
? KaiOSDevice
|
? KaiOSDevice
|
||||||
@@ -53,7 +53,7 @@ function createDevice(
|
|||||||
reject(e);
|
reject(e);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
if (
|
if (
|
||||||
e &&
|
e &&
|
||||||
e.message &&
|
e.message &&
|
||||||
@@ -74,7 +74,7 @@ export async function getActiveAndroidDevices(
|
|||||||
const client = await getAdbClient(store);
|
const client = await getAdbClient(store);
|
||||||
const androidDevices = await client.listDevices();
|
const androidDevices = await client.listDevices();
|
||||||
const devices = await Promise.all(
|
const devices = await Promise.all(
|
||||||
androidDevices.map(device => createDevice(client, device)),
|
androidDevices.map((device) => createDevice(client, device)),
|
||||||
);
|
);
|
||||||
return devices.filter(Boolean) as any;
|
return devices.filter(Boolean) as any;
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ export default (store: Store, logger: Logger) => {
|
|||||||
// get emulators
|
// get emulators
|
||||||
promisify(which)('emulator')
|
promisify(which)('emulator')
|
||||||
.catch(() => `${process.env.ANDROID_HOME || ''}/tools/emulator`)
|
.catch(() => `${process.env.ANDROID_HOME || ''}/tools/emulator`)
|
||||||
.then(emulatorPath => {
|
.then((emulatorPath) => {
|
||||||
child_process.exec(
|
child_process.exec(
|
||||||
`${emulatorPath} -list-avds`,
|
`${emulatorPath} -list-avds`,
|
||||||
(error: Error | null, data: string | null) => {
|
(error: Error | null, data: string | null) => {
|
||||||
@@ -126,11 +126,11 @@ export default (store: Store, logger: Logger) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
getAdbClient(store)
|
getAdbClient(store)
|
||||||
.then(client => {
|
.then((client) => {
|
||||||
client
|
client
|
||||||
.trackDevices()
|
.trackDevices()
|
||||||
.then(tracker => {
|
.then((tracker) => {
|
||||||
tracker.on('error', err => {
|
tracker.on('error', (err) => {
|
||||||
if (err.message === 'Connection closed') {
|
if (err.message === 'Connection closed') {
|
||||||
// adb server has shutdown, remove all android devices
|
// adb server has shutdown, remove all android devices
|
||||||
const {connections} = store.getState();
|
const {connections} = store.getState();
|
||||||
@@ -148,13 +148,13 @@ export default (store: Store, logger: Logger) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tracker.on('add', async device => {
|
tracker.on('add', async (device) => {
|
||||||
if (device.type !== 'offline') {
|
if (device.type !== 'offline') {
|
||||||
registerDevice(client, device, store);
|
registerDevice(client, device, store);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tracker.on('change', async device => {
|
tracker.on('change', async (device) => {
|
||||||
if (device.type === 'offline') {
|
if (device.type === 'offline') {
|
||||||
unregisterDevices([device.id]);
|
unregisterDevices([device.id]);
|
||||||
} else {
|
} else {
|
||||||
@@ -162,7 +162,7 @@ export default (store: Store, logger: Logger) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tracker.on('remove', device => {
|
tracker.on('remove', (device) => {
|
||||||
unregisterDevices([device.id]);
|
unregisterDevices([device.id]);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@@ -174,7 +174,7 @@ export default (store: Store, logger: Logger) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
console.error(`Failed to watch for android devices: ${e.message}`);
|
console.error(`Failed to watch for android devices: ${e.message}`);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -201,7 +201,7 @@ export default (store: Store, logger: Logger) => {
|
|||||||
(device: BaseDevice) =>
|
(device: BaseDevice) =>
|
||||||
device.serial === androidDevice.serial && device.isArchived,
|
device.serial === androidDevice.serial && device.isArchived,
|
||||||
)
|
)
|
||||||
.map(device => device.serial);
|
.map((device) => device.serial);
|
||||||
|
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: 'UNREGISTER_DEVICES',
|
type: 'UNREGISTER_DEVICES',
|
||||||
@@ -223,7 +223,7 @@ export default (store: Store, logger: Logger) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function unregisterDevices(deviceIds: Array<string>) {
|
async function unregisterDevices(deviceIds: Array<string>) {
|
||||||
deviceIds.forEach(id =>
|
deviceIds.forEach((id) =>
|
||||||
logger.track('usage', 'unregister-device', {
|
logger.track('usage', 'unregister-device', {
|
||||||
os: 'Android',
|
os: 'Android',
|
||||||
serial: id,
|
serial: id,
|
||||||
@@ -231,10 +231,10 @@ export default (store: Store, logger: Logger) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const archivedDevices = deviceIds
|
const archivedDevices = deviceIds
|
||||||
.map(id => {
|
.map((id) => {
|
||||||
const device = store
|
const device = store
|
||||||
.getState()
|
.getState()
|
||||||
.connections.devices.find(device => device.serial === id);
|
.connections.devices.find((device) => device.serial === id);
|
||||||
if (device && !device.isArchived) {
|
if (device && !device.isArchived) {
|
||||||
return device.archive();
|
return device.archive();
|
||||||
}
|
}
|
||||||
@@ -259,7 +259,7 @@ export default (store: Store, logger: Logger) => {
|
|||||||
|
|
||||||
// cleanup method
|
// cleanup method
|
||||||
return () =>
|
return () =>
|
||||||
getAdbClient(store).then(client => {
|
getAdbClient(store).then((client) => {
|
||||||
client.kill();
|
client.kill();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,10 +35,7 @@ export const uriComponents = (url: string): Array<string> => {
|
|||||||
/^flipper:\/\/([^\/]*)\/([^\/]*)\/?(.*)$/,
|
/^flipper:\/\/([^\/]*)\/([^\/]*)\/?(.*)$/,
|
||||||
);
|
);
|
||||||
if (match) {
|
if (match) {
|
||||||
return match
|
return match.map(decodeURIComponent).slice(1).filter(Boolean);
|
||||||
.map(decodeURIComponent)
|
|
||||||
.slice(1)
|
|
||||||
.filter(Boolean);
|
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
@@ -79,8 +76,8 @@ export default (store: Store, _logger: Logger) => {
|
|||||||
return (
|
return (
|
||||||
typeof url === 'string' &&
|
typeof url === 'string' &&
|
||||||
fetch(url)
|
fetch(url)
|
||||||
.then(res => res.text())
|
.then((res) => res.text())
|
||||||
.then(data => importDataToStore(url, data, store))
|
.then((data) => importDataToStore(url, data, store))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
store.dispatch(toggleAction('downloadingImportData', false));
|
store.dispatch(toggleAction('downloadingImportData', false));
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ const portForwarders: Array<ChildProcess> = GK.get('flipper_ios_device_support')
|
|||||||
|
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
window.addEventListener('beforeunload', () => {
|
window.addEventListener('beforeunload', () => {
|
||||||
portForwarders.forEach(process => process.kill());
|
portForwarders.forEach((process) => process.kill());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,12 +74,12 @@ async function queryDevices(store: Store, logger: Logger): Promise<void> {
|
|||||||
const {connections} = store.getState();
|
const {connections} = store.getState();
|
||||||
const currentDeviceIDs: Set<string> = new Set(
|
const currentDeviceIDs: Set<string> = new Set(
|
||||||
connections.devices
|
connections.devices
|
||||||
.filter(device => device instanceof IOSDevice)
|
.filter((device) => device instanceof IOSDevice)
|
||||||
.map(device => device.serial),
|
.map((device) => device.serial),
|
||||||
);
|
);
|
||||||
return Promise.all([getActiveSimulators(), getActiveDevices()])
|
return Promise.all([getActiveSimulators(), getActiveDevices()])
|
||||||
.then(([a, b]) => a.concat(b))
|
.then(([a, b]) => a.concat(b))
|
||||||
.then(activeDevices => {
|
.then((activeDevices) => {
|
||||||
for (const {udid, type, name} of activeDevices) {
|
for (const {udid, type, name} of activeDevices) {
|
||||||
if (currentDeviceIDs.has(udid)) {
|
if (currentDeviceIDs.has(udid)) {
|
||||||
currentDeviceIDs.delete(udid);
|
currentDeviceIDs.delete(udid);
|
||||||
@@ -106,7 +106,7 @@ async function queryDevices(store: Store, logger: Logger): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentDeviceIDs.size > 0) {
|
if (currentDeviceIDs.size > 0) {
|
||||||
currentDeviceIDs.forEach(id =>
|
currentDeviceIDs.forEach((id) =>
|
||||||
logger.track('usage', 'unregister-device', {os: 'iOS', serial: id}),
|
logger.track('usage', 'unregister-device', {os: 'iOS', serial: id}),
|
||||||
);
|
);
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
@@ -136,9 +136,9 @@ function getActiveSimulators(): Promise<Array<IOSDeviceParams>> {
|
|||||||
|
|
||||||
return simulators
|
return simulators
|
||||||
.filter(
|
.filter(
|
||||||
simulator => simulator.state === 'Booted' && isAvailable(simulator),
|
(simulator) => simulator.state === 'Booted' && isAvailable(simulator),
|
||||||
)
|
)
|
||||||
.map(simulator => {
|
.map((simulator) => {
|
||||||
return {
|
return {
|
||||||
udid: simulator.udid,
|
udid: simulator.udid,
|
||||||
type: 'emulator',
|
type: 'emulator',
|
||||||
@@ -146,11 +146,11 @@ function getActiveSimulators(): Promise<Array<IOSDeviceParams>> {
|
|||||||
} as IOSDeviceParams;
|
} as IOSDeviceParams;
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(_ => []);
|
.catch((_) => []);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActiveDevices(): Promise<Array<IOSDeviceParams>> {
|
function getActiveDevices(): Promise<Array<IOSDeviceParams>> {
|
||||||
return iosUtil.targets().catch(e => {
|
return iosUtil.targets().catch((e) => {
|
||||||
console.error(e.message);
|
console.error(e.message);
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
@@ -163,7 +163,7 @@ function queryDevicesForever(store: Store, logger: Logger) {
|
|||||||
// to avoid simultaneous queries which can cause multiple user input prompts.
|
// to avoid simultaneous queries which can cause multiple user input prompts.
|
||||||
setTimeout(() => queryDevicesForever(store, logger), 3000);
|
setTimeout(() => queryDevicesForever(store, logger), 3000);
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch((err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -233,8 +233,8 @@ async function checkIfDevicesCanBeQueryied(store: Store): Promise<boolean> {
|
|||||||
|
|
||||||
async function isXcodeDetected(): Promise<boolean> {
|
async function isXcodeDetected(): Promise<boolean> {
|
||||||
return promisify(child_process.exec)('xcode-select -p')
|
return promisify(child_process.exec)('xcode-select -p')
|
||||||
.then(_ => true)
|
.then((_) => true)
|
||||||
.catch(_ => false);
|
.catch((_) => false);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getActiveDevicesAndSimulators(): Promise<
|
export async function getActiveDevicesAndSimulators(): Promise<
|
||||||
@@ -245,7 +245,7 @@ export async function getActiveDevicesAndSimulators(): Promise<
|
|||||||
getActiveDevices(),
|
getActiveDevices(),
|
||||||
]);
|
]);
|
||||||
const allDevices = activeDevices[0].concat(activeDevices[1]);
|
const allDevices = activeDevices[0].concat(activeDevices[1]);
|
||||||
return allDevices.map(device => {
|
return allDevices.map((device) => {
|
||||||
const {udid, type, name} = device;
|
const {udid, type, name} = device;
|
||||||
return new IOSDevice(udid, type, name);
|
return new IOSDevice(udid, type, name);
|
||||||
});
|
});
|
||||||
@@ -260,11 +260,11 @@ export default (store: Store, logger: Logger) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
isXcodeDetected()
|
isXcodeDetected()
|
||||||
.then(isDetected => {
|
.then((isDetected) => {
|
||||||
store.dispatch(setXcodeDetected(isDetected));
|
store.dispatch(setXcodeDetected(isDetected));
|
||||||
return isDetected;
|
return isDetected;
|
||||||
})
|
})
|
||||||
.then(isDetected =>
|
.then((isDetected) =>
|
||||||
isDetected ? queryDevicesForever(store, logger) : Promise.resolve(),
|
isDetected ? queryDevicesForever(store, logger) : Promise.resolve(),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {Store} from '../reducers/index';
|
|||||||
import {Dispatcher} from './types';
|
import {Dispatcher} from './types';
|
||||||
import {notNull} from '../utils/typeUtils';
|
import {notNull} from '../utils/typeUtils';
|
||||||
|
|
||||||
export default function(store: Store, logger: Logger): () => Promise<void> {
|
export default function (store: Store, logger: Logger): () => Promise<void> {
|
||||||
// This only runs in development as when the reload
|
// This only runs in development as when the reload
|
||||||
// kicks in it doesn't unregister the shortcuts
|
// kicks in it doesn't unregister the shortcuts
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
@@ -48,7 +48,7 @@ export default function(store: Store, logger: Logger): () => Promise<void> {
|
|||||||
reactNative,
|
reactNative,
|
||||||
].filter(notNull);
|
].filter(notNull);
|
||||||
const globalCleanup = dispatchers
|
const globalCleanup = dispatchers
|
||||||
.map(dispatcher => dispatcher(store, logger))
|
.map((dispatcher) => dispatcher(store, logger))
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
return () => {
|
return () => {
|
||||||
return Promise.all(globalCleanup).then(() => {});
|
return Promise.all(globalCleanup).then(() => {});
|
||||||
|
|||||||
@@ -22,22 +22,22 @@ const METRO_MESSAGE = ['React Native packager is running', 'Metro is running'];
|
|||||||
const QUERY_INTERVAL = 5000;
|
const QUERY_INTERVAL = 5000;
|
||||||
|
|
||||||
async function isMetroRunning(): Promise<boolean> {
|
async function isMetroRunning(): Promise<boolean> {
|
||||||
return new Promise(resolve => {
|
return new Promise((resolve) => {
|
||||||
// We use Node's http library, rather than fetch api, as the latter cannot supress network errors being shown in the devtools console
|
// We use Node's http library, rather than fetch api, as the latter cannot supress network errors being shown in the devtools console
|
||||||
// which generates a lot of noise
|
// which generates a lot of noise
|
||||||
http
|
http
|
||||||
.get(METRO_URL, resp => {
|
.get(METRO_URL, (resp) => {
|
||||||
let data = '';
|
let data = '';
|
||||||
resp
|
resp
|
||||||
.on('data', chunk => {
|
.on('data', (chunk) => {
|
||||||
data += chunk;
|
data += chunk;
|
||||||
})
|
})
|
||||||
.on('end', () => {
|
.on('end', () => {
|
||||||
const isMetro = METRO_MESSAGE.some(msg => data.includes(msg));
|
const isMetro = METRO_MESSAGE.some((msg) => data.includes(msg));
|
||||||
resolve(isMetro);
|
resolve(isMetro);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.on('error', err => {
|
.on('error', (err) => {
|
||||||
console.debug('Could not connect to METRO ' + err);
|
console.debug('Could not connect to METRO ' + err);
|
||||||
resolve(false);
|
resolve(false);
|
||||||
});
|
});
|
||||||
@@ -79,7 +79,7 @@ async function unregisterDevices(store: Store, logger: Logger) {
|
|||||||
let archivedDevice: ArchivedDevice | undefined = undefined;
|
let archivedDevice: ArchivedDevice | undefined = undefined;
|
||||||
const device = store
|
const device = store
|
||||||
.getState()
|
.getState()
|
||||||
.connections.devices.find(device => device.serial === METRO_URL);
|
.connections.devices.find((device) => device.serial === METRO_URL);
|
||||||
if (device && !device.isArchived) {
|
if (device && !device.isArchived) {
|
||||||
archivedDevice = device.archive();
|
archivedDevice = device.archive();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export default (store: Store, logger: Logger) => {
|
|||||||
...devicePlugins,
|
...devicePlugins,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Object.keys(pluginStates).forEach(key => {
|
Object.keys(pluginStates).forEach((key) => {
|
||||||
if (knownPluginStates.get(key) !== pluginStates[key]) {
|
if (knownPluginStates.get(key) !== pluginStates[key]) {
|
||||||
knownPluginStates.set(key, pluginStates[key]);
|
knownPluginStates.set(key, pluginStates[key]);
|
||||||
const plugin = deconstructPluginKey(key);
|
const plugin = deconstructPluginKey(key);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {registerInstalledPlugins} from '../reducers/pluginManager';
|
|||||||
import {readInstalledPlugins} from '../utils/pluginManager';
|
import {readInstalledPlugins} from '../utils/pluginManager';
|
||||||
|
|
||||||
function refreshInstalledPlugins(store: Store) {
|
function refreshInstalledPlugins(store: Store) {
|
||||||
readInstalledPlugins().then(plugins =>
|
readInstalledPlugins().then((plugins) =>
|
||||||
store.dispatch(registerInstalledPlugins(plugins)),
|
store.dispatch(registerInstalledPlugins(plugins)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,8 +100,8 @@ function getBundledPlugins(): Array<PluginDefinition> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return bundledPlugins
|
return bundledPlugins
|
||||||
.filter(plugin => notNull(plugin.out))
|
.filter((plugin) => notNull(plugin.out))
|
||||||
.map(plugin => ({
|
.map((plugin) => ({
|
||||||
...plugin,
|
...plugin,
|
||||||
out: path.join(pluginPath, plugin.out!),
|
out: path.join(pluginPath, plugin.out!),
|
||||||
}));
|
}));
|
||||||
@@ -164,7 +164,7 @@ export const requirePlugin = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set values from package.json as static variables on class
|
// set values from package.json as static variables on class
|
||||||
Object.keys(pluginDefinition).forEach(key => {
|
Object.keys(pluginDefinition).forEach((key) => {
|
||||||
if (key === 'name') {
|
if (key === 'name') {
|
||||||
plugin.id = plugin.id || pluginDefinition.name;
|
plugin.id = plugin.id || pluginDefinition.name;
|
||||||
} else if (key === 'id') {
|
} else if (key === 'id') {
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ export default (store: Store) => {
|
|||||||
const devices = store
|
const devices = store
|
||||||
.getState()
|
.getState()
|
||||||
.connections.devices.filter(
|
.connections.devices.filter(
|
||||||
device => device.os === 'Metro' && !device.isArchived,
|
(device) => device.os === 'Metro' && !device.isArchived,
|
||||||
) as MetroDevice[];
|
) as MetroDevice[];
|
||||||
|
|
||||||
devices.forEach(device => device.sendCommand(shortcut.command));
|
devices.forEach((device) => device.sendCommand(shortcut.command));
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export default (store: Store, logger: Logger) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
server.addListener('error', err => {
|
server.addListener('error', (err) => {
|
||||||
const message: string =
|
const message: string =
|
||||||
err.code === 'EADDRINUSE'
|
err.code === 'EADDRINUSE'
|
||||||
? "Couldn't start websocket server. Looks like you have multiple copies of Flipper running."
|
? "Couldn't start websocket server. Looks like you have multiple copies of Flipper running."
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ export function computeUsageSummary(
|
|||||||
|
|
||||||
return intervals.reduce<UsageSummary>(
|
return intervals.reduce<UsageSummary>(
|
||||||
(acc: UsageSummary, x: UsageInterval) =>
|
(acc: UsageSummary, x: UsageInterval) =>
|
||||||
produce(acc, draft => {
|
produce(acc, (draft) => {
|
||||||
draft.total.focusedTime += x.focused ? x.length : 0;
|
draft.total.focusedTime += x.focused ? x.length : 0;
|
||||||
draft.total.unfocusedTime += x.focused ? 0 : x.length;
|
draft.total.unfocusedTime += x.focused ? 0 : x.length;
|
||||||
const pluginName = x.plugin ?? 'none';
|
const pluginName = x.plugin ?? 'none';
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ import {getUser, logoutUser} from '../fb-stubs/user';
|
|||||||
|
|
||||||
export default (store: Store, _logger: Logger) => {
|
export default (store: Store, _logger: Logger) => {
|
||||||
getUser()
|
getUser()
|
||||||
.then(user => {
|
.then((user) => {
|
||||||
store.dispatch(login(user));
|
store.dispatch(login(user));
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
store.dispatch(logout());
|
store.dispatch(logout());
|
||||||
console.error(e);
|
console.error(e);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
import {Tristate} from 'app/src/reducers/settings';
|
import {Tristate} from 'app/src/reducers/settings';
|
||||||
|
|
||||||
export default function(_props: {
|
export default function (_props: {
|
||||||
isPrefetchingEnabled: Tristate;
|
isPrefetchingEnabled: Tristate;
|
||||||
onEnablePrefetchingChange: (v: Tristate) => void;
|
onEnablePrefetchingChange: (v: Tristate) => void;
|
||||||
isLocalPinIgnored: boolean;
|
isLocalPinIgnored: boolean;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export function extractError(
|
|||||||
...data: Array<any>
|
...data: Array<any>
|
||||||
): {message: string; error: Error} {
|
): {message: string; error: Error} {
|
||||||
const message = data.map(getStringFromErrorLike).join(' ');
|
const message = data.map(getStringFromErrorLike).join(' ');
|
||||||
const error = data.find(e => e instanceof Error) || new Error(message);
|
const error = data.find((e) => e instanceof Error) || new Error(message);
|
||||||
return {
|
return {
|
||||||
message,
|
message,
|
||||||
error,
|
error,
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ async function targets(): Promise<Array<DeviceTarget>> {
|
|||||||
return stdout
|
return stdout
|
||||||
.toString()
|
.toString()
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.map(line => line.trim())
|
.map((line) => line.trim())
|
||||||
.map(line => /(.+) \([^(]+\) \[(.*)\]( \(Simulator\))?/.exec(line))
|
.map((line) => /(.+) \([^(]+\) \[(.*)\]( \(Simulator\))?/.exec(line))
|
||||||
.filter(notNull)
|
.filter(notNull)
|
||||||
.filter(
|
.filter(
|
||||||
([_match, name, _udid, isSim]) =>
|
([_match, name, _udid, isSim]) =>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const AppFrame = () => {
|
|||||||
const [warnEmployee, setWarnEmployee] = useState(false);
|
const [warnEmployee, setWarnEmployee] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (fbConfig.warnFBEmployees) {
|
if (fbConfig.warnFBEmployees) {
|
||||||
isFBEmployee().then(isEmployee => {
|
isFBEmployee().then((isEmployee) => {
|
||||||
setWarnEmployee(isEmployee);
|
setWarnEmployee(isEmployee);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ function setProcessState(store: Store) {
|
|||||||
// it exists
|
// it exists
|
||||||
process.env.PATH =
|
process.env.PATH =
|
||||||
['emulator', 'tools', 'platform-tools']
|
['emulator', 'tools', 'platform-tools']
|
||||||
.map(directory => path.resolve(androidHome, directory))
|
.map((directory) => path.resolve(androidHome, directory))
|
||||||
.join(':') + `:${process.env.PATH}`;
|
.join(':') + `:${process.env.PATH}`;
|
||||||
|
|
||||||
window.requestIdleCallback(() => {
|
window.requestIdleCallback(() => {
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ export class FlipperPlugin<
|
|||||||
});
|
});
|
||||||
this.realClient.subscribe(id, method, callback);
|
this.realClient.subscribe(id, method, callback);
|
||||||
},
|
},
|
||||||
supportsMethod: method => this.realClient.supportsMethod(id, method),
|
supportsMethod: (method) => this.realClient.supportsMethod(id, method),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ const NonWrappingText = styled(Text)({
|
|||||||
userSelect: 'none',
|
userSelect: 'none',
|
||||||
});
|
});
|
||||||
|
|
||||||
const BooleanValue = styled(NonWrappingText)<{active?: boolean}>(props => ({
|
const BooleanValue = styled(NonWrappingText)<{active?: boolean}>((props) => ({
|
||||||
'&::before': {
|
'&::before': {
|
||||||
content: '""',
|
content: '""',
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
@@ -339,7 +339,7 @@ export default function createTableNativePlugin(id: string, title: string) {
|
|||||||
if (!this.props.persistedState.tableMetadata) {
|
if (!this.props.persistedState.tableMetadata) {
|
||||||
this.client
|
this.client
|
||||||
.call('getMetadata')
|
.call('getMetadata')
|
||||||
.then(metadata => {
|
.then((metadata) => {
|
||||||
this.props.setPersistedState({
|
this.props.setPersistedState({
|
||||||
tableMetadata: {
|
tableMetadata: {
|
||||||
...metadata,
|
...metadata,
|
||||||
@@ -347,7 +347,7 @@ export default function createTableNativePlugin(id: string, title: string) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(e => this.setState({error: e}));
|
.catch((e) => this.setState({error: e}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -380,13 +380,13 @@ export default function createTableNativePlugin(id: string, title: string) {
|
|||||||
Object.keys(this.props.persistedState.tableMetadata.columns)) ||
|
Object.keys(this.props.persistedState.tableMetadata.columns)) ||
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
.map(key => textContent(row.columns[key].value))
|
.map((key) => textContent(row.columns[key].value))
|
||||||
.join('\t');
|
.join('\t');
|
||||||
|
|
||||||
if (this.state.selectedIds.length > 0) {
|
if (this.state.selectedIds.length > 0) {
|
||||||
// create paste from selection
|
// create paste from selection
|
||||||
paste = this.props.persistedState.rows
|
paste = this.props.persistedState.rows
|
||||||
.filter(row => this.state.selectedIds.indexOf(row.key) > -1)
|
.filter((row) => this.state.selectedIds.indexOf(row.key) > -1)
|
||||||
.map(mapFn)
|
.map(mapFn)
|
||||||
.join('\n');
|
.join('\n');
|
||||||
} else {
|
} else {
|
||||||
@@ -413,7 +413,7 @@ export default function createTableNativePlugin(id: string, title: string) {
|
|||||||
);
|
);
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
return rows.map(r => {
|
return rows.map((r) => {
|
||||||
return {
|
return {
|
||||||
...r,
|
...r,
|
||||||
columns: Object.keys(r.columns).reduce((map, columnName) => {
|
columns: Object.keys(r.columns).reduce((map, columnName) => {
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
|
|||||||
|
|
||||||
const newDevices = state.devices.slice();
|
const newDevices = state.devices.slice();
|
||||||
const existing = state.devices.findIndex(
|
const existing = state.devices.findIndex(
|
||||||
device => device.serial === payload.serial,
|
(device) => device.serial === payload.serial,
|
||||||
);
|
);
|
||||||
if (existing !== -1) {
|
if (existing !== -1) {
|
||||||
console.debug(
|
console.debug(
|
||||||
@@ -231,9 +231,9 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
|
|||||||
const deviceSerials = action.payload;
|
const deviceSerials = action.payload;
|
||||||
|
|
||||||
return updateSelection(
|
return updateSelection(
|
||||||
produce(state, draft => {
|
produce(state, (draft) => {
|
||||||
draft.devices = draft.devices.filter(
|
draft.devices = draft.devices.filter(
|
||||||
device => !deviceSerials.has(device.serial),
|
(device) => !deviceSerials.has(device.serial),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -265,7 +265,7 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
|
|||||||
|
|
||||||
case 'STAR_PLUGIN': {
|
case 'STAR_PLUGIN': {
|
||||||
const {selectedPlugin, selectedApp} = action.payload;
|
const {selectedPlugin, selectedApp} = action.payload;
|
||||||
return produce(state, draft => {
|
return produce(state, (draft) => {
|
||||||
if (!draft.userStarredPlugins[selectedApp]) {
|
if (!draft.userStarredPlugins[selectedApp]) {
|
||||||
draft.userStarredPlugins[selectedApp] = [selectedPlugin];
|
draft.userStarredPlugins[selectedApp] = [selectedPlugin];
|
||||||
} else {
|
} else {
|
||||||
@@ -291,7 +291,7 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
|
|||||||
return updateSelection({
|
return updateSelection({
|
||||||
...state,
|
...state,
|
||||||
clients: state.clients.concat(payload),
|
clients: state.clients.concat(payload),
|
||||||
uninitializedClients: state.uninitializedClients.filter(c => {
|
uninitializedClients: state.uninitializedClients.filter((c) => {
|
||||||
return (
|
return (
|
||||||
c.deviceId !== payload.query.device_id ||
|
c.deviceId !== payload.query.device_id ||
|
||||||
c.client.appName !== payload.query.app
|
c.client.appName !== payload.query.app
|
||||||
@@ -335,7 +335,7 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
uninitializedClients: state.uninitializedClients
|
uninitializedClients: state.uninitializedClients
|
||||||
.filter(entry => !isEqual(entry.client, payload))
|
.filter((entry) => !isEqual(entry.client, payload))
|
||||||
.concat([{client: payload}])
|
.concat([{client: payload}])
|
||||||
.sort((a, b) => a.client.appName.localeCompare(b.client.appName)),
|
.sort((a, b) => a.client.appName.localeCompare(b.client.appName)),
|
||||||
};
|
};
|
||||||
@@ -345,7 +345,7 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
uninitializedClients: state.uninitializedClients
|
uninitializedClients: state.uninitializedClients
|
||||||
.map(c =>
|
.map((c) =>
|
||||||
isEqual(c.client, payload.client)
|
isEqual(c.client, payload.client)
|
||||||
? {...c, deviceId: payload.deviceId}
|
? {...c, deviceId: payload.deviceId}
|
||||||
: c,
|
: c,
|
||||||
@@ -365,7 +365,7 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
uninitializedClients: state.uninitializedClients
|
uninitializedClients: state.uninitializedClients
|
||||||
.map(c =>
|
.map((c) =>
|
||||||
isEqual(c.client, payload.client)
|
isEqual(c.client, payload.client)
|
||||||
? {...c, errorMessage: errorMessage}
|
? {...c, errorMessage: errorMessage}
|
||||||
: c,
|
: c,
|
||||||
@@ -392,10 +392,10 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
|
|||||||
case 'REGISTER_PLUGINS': {
|
case 'REGISTER_PLUGINS': {
|
||||||
// plugins are registered after creating the base devices, so update them
|
// plugins are registered after creating the base devices, so update them
|
||||||
const plugins = action.payload;
|
const plugins = action.payload;
|
||||||
plugins.forEach(plugin => {
|
plugins.forEach((plugin) => {
|
||||||
if (plugin.prototype instanceof FlipperDevicePlugin) {
|
if (plugin.prototype instanceof FlipperDevicePlugin) {
|
||||||
// smell: devices are mutable
|
// smell: devices are mutable
|
||||||
state.devices.forEach(device => {
|
state.devices.forEach((device) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (plugin.supportsDevice(device)) {
|
if (plugin.supportsDevice(device)) {
|
||||||
device.devicePlugins = [
|
device.devicePlugins = [
|
||||||
@@ -429,7 +429,7 @@ export default (state: State = INITAL_STATE, action: Actions): State => {
|
|||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
const deviceNotSupportedError = nextState.errors.find(
|
const deviceNotSupportedError = nextState.errors.find(
|
||||||
error => error.message === deviceNotSupportedErrorMessage,
|
(error) => error.message === deviceNotSupportedErrorMessage,
|
||||||
);
|
);
|
||||||
if (deviceNotSupportedError) {
|
if (deviceNotSupportedError) {
|
||||||
deviceNotSupportedError.message = error;
|
deviceNotSupportedError.message = error;
|
||||||
@@ -445,7 +445,7 @@ function mergeError(
|
|||||||
errors: FlipperError[],
|
errors: FlipperError[],
|
||||||
newError: FlipperError,
|
newError: FlipperError,
|
||||||
): FlipperError[] {
|
): FlipperError[] {
|
||||||
const idx = errors.findIndex(error => error.message === newError.message);
|
const idx = errors.findIndex((error) => error.message === newError.message);
|
||||||
const results = errors.slice();
|
const results = errors.slice();
|
||||||
if (idx !== -1) {
|
if (idx !== -1) {
|
||||||
results[idx] = {
|
results[idx] = {
|
||||||
@@ -555,12 +555,12 @@ export function getClientById(
|
|||||||
clients: Client[],
|
clients: Client[],
|
||||||
clientId: string | null | undefined,
|
clientId: string | null | undefined,
|
||||||
): Client | undefined {
|
): Client | undefined {
|
||||||
return clients.find(client => client.id === clientId);
|
return clients.find((client) => client.id === clientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canBeDefaultDevice(device: BaseDevice) {
|
export function canBeDefaultDevice(device: BaseDevice) {
|
||||||
return !DEFAULT_DEVICE_BLACKLIST.some(
|
return !DEFAULT_DEVICE_BLACKLIST.some(
|
||||||
blacklistedDevice => device instanceof blacklistedDevice,
|
(blacklistedDevice) => device instanceof blacklistedDevice,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,9 +585,9 @@ function updateSelection(state: Readonly<State>): State {
|
|||||||
if (!device) {
|
if (!device) {
|
||||||
device =
|
device =
|
||||||
state.devices.find(
|
state.devices.find(
|
||||||
device => device.title === state.userPreferredDevice,
|
(device) => device.title === state.userPreferredDevice,
|
||||||
) ||
|
) ||
|
||||||
state.devices.find(device => canBeDefaultDevice(device)) ||
|
state.devices.find((device) => canBeDefaultDevice(device)) ||
|
||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
updates.selectedDevice = device;
|
updates.selectedDevice = device;
|
||||||
|
|||||||
@@ -82,24 +82,24 @@ export type HealthcheckReport = {
|
|||||||
|
|
||||||
function recomputeHealthcheckStatus(draft: State): void {
|
function recomputeHealthcheckStatus(draft: State): void {
|
||||||
draft.healthcheckReport.result = computeAggregatedResult(
|
draft.healthcheckReport.result = computeAggregatedResult(
|
||||||
Object.values(draft.healthcheckReport.categories).map(c => c.result),
|
Object.values(draft.healthcheckReport.categories).map((c) => c.result),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeAggregatedResult(
|
function computeAggregatedResult(
|
||||||
results: HealthcheckResult[],
|
results: HealthcheckResult[],
|
||||||
): HealthcheckResult {
|
): HealthcheckResult {
|
||||||
return results.some(r => r.status === 'IN_PROGRESS')
|
return results.some((r) => r.status === 'IN_PROGRESS')
|
||||||
? {status: 'IN_PROGRESS'}
|
? {status: 'IN_PROGRESS'}
|
||||||
: results.every(r => r.status === 'SUCCESS')
|
: results.every((r) => r.status === 'SUCCESS')
|
||||||
? {status: 'SUCCESS'}
|
? {status: 'SUCCESS'}
|
||||||
: results.some(r => r.status === 'FAILED' && !r.isAcknowledged)
|
: results.some((r) => r.status === 'FAILED' && !r.isAcknowledged)
|
||||||
? {status: 'FAILED', isAcknowledged: false}
|
? {status: 'FAILED', isAcknowledged: false}
|
||||||
: results.some(r => r.status === 'FAILED')
|
: results.some((r) => r.status === 'FAILED')
|
||||||
? {status: 'FAILED', isAcknowledged: true}
|
? {status: 'FAILED', isAcknowledged: true}
|
||||||
: results.some(r => r.status === 'WARNING' && !r.isAcknowledged)
|
: results.some((r) => r.status === 'WARNING' && !r.isAcknowledged)
|
||||||
? {status: 'WARNING', isAcknowledged: false}
|
? {status: 'WARNING', isAcknowledged: false}
|
||||||
: results.some(r => r.status === 'WARNING')
|
: results.some((r) => r.status === 'WARNING')
|
||||||
? {status: 'WARNING', isAcknowledged: true}
|
? {status: 'WARNING', isAcknowledged: true}
|
||||||
: {status: 'SKIPPED'};
|
: {status: 'SKIPPED'};
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@ const start = produce((draft: State, healthchecks: Healthchecks) => {
|
|||||||
result: {status: 'IN_PROGRESS'},
|
result: {status: 'IN_PROGRESS'},
|
||||||
label: category.label,
|
label: category.label,
|
||||||
checks: createDict<HealthcheckReportItem>(
|
checks: createDict<HealthcheckReportItem>(
|
||||||
category.healthchecks.map(check => [
|
category.healthchecks.map((check) => [
|
||||||
check.key,
|
check.key,
|
||||||
{
|
{
|
||||||
key: check.key,
|
key: check.key,
|
||||||
@@ -176,11 +176,11 @@ const start = produce((draft: State, healthchecks: Healthchecks) => {
|
|||||||
|
|
||||||
const finish = produce((draft: State) => {
|
const finish = produce((draft: State) => {
|
||||||
Object.values(draft.healthcheckReport.categories)
|
Object.values(draft.healthcheckReport.categories)
|
||||||
.filter(cat => cat.result.status !== 'SKIPPED')
|
.filter((cat) => cat.result.status !== 'SKIPPED')
|
||||||
.forEach(cat => {
|
.forEach((cat) => {
|
||||||
cat.result.message = undefined;
|
cat.result.message = undefined;
|
||||||
cat.result = computeAggregatedResult(
|
cat.result = computeAggregatedResult(
|
||||||
Object.values(cat.checks).map(c => c.result),
|
Object.values(cat.checks).map((c) => c.result),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
recomputeHealthcheckStatus(draft);
|
recomputeHealthcheckStatus(draft);
|
||||||
@@ -191,18 +191,18 @@ const finish = produce((draft: State) => {
|
|||||||
|
|
||||||
const acknowledge = produce((draft: State) => {
|
const acknowledge = produce((draft: State) => {
|
||||||
draft.acknowledgedProblems = ([] as string[]).concat(
|
draft.acknowledgedProblems = ([] as string[]).concat(
|
||||||
...Object.values(draft.healthcheckReport.categories).map(cat =>
|
...Object.values(draft.healthcheckReport.categories).map((cat) =>
|
||||||
Object.values(cat.checks)
|
Object.values(cat.checks)
|
||||||
.filter(
|
.filter(
|
||||||
chk =>
|
(chk) =>
|
||||||
chk.result.status === 'FAILED' || chk.result.status === 'WARNING',
|
chk.result.status === 'FAILED' || chk.result.status === 'WARNING',
|
||||||
)
|
)
|
||||||
.map(chk => chk.key),
|
.map((chk) => chk.key),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
Object.values(draft.healthcheckReport.categories).forEach(cat => {
|
Object.values(draft.healthcheckReport.categories).forEach((cat) => {
|
||||||
cat.result.isAcknowledged = true;
|
cat.result.isAcknowledged = true;
|
||||||
Object.values(cat.checks).forEach(chk => {
|
Object.values(cat.checks).forEach((chk) => {
|
||||||
chk.result.isAcknowledged = true;
|
chk.result.isAcknowledged = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -211,9 +211,9 @@ const acknowledge = produce((draft: State) => {
|
|||||||
|
|
||||||
function setAcknowledgedProblemsToEmpty(draft: State) {
|
function setAcknowledgedProblemsToEmpty(draft: State) {
|
||||||
draft.acknowledgedProblems = [];
|
draft.acknowledgedProblems = [];
|
||||||
Object.values(draft.healthcheckReport.categories).forEach(cat => {
|
Object.values(draft.healthcheckReport.categories).forEach((cat) => {
|
||||||
cat.result.isAcknowledged = false;
|
cat.result.isAcknowledged = false;
|
||||||
Object.values(cat.checks).forEach(chk => {
|
Object.values(cat.checks).forEach((chk) => {
|
||||||
chk.result.isAcknowledged = false;
|
chk.result.isAcknowledged = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export default function reducer(
|
|||||||
|
|
||||||
case 'CLEAR_MESSAGE_QUEUE': {
|
case 'CLEAR_MESSAGE_QUEUE': {
|
||||||
const {pluginKey, amount} = action.payload;
|
const {pluginKey, amount} = action.payload;
|
||||||
return produce(state, draft => {
|
return produce(state, (draft) => {
|
||||||
const messages = draft[pluginKey];
|
const messages = draft[pluginKey];
|
||||||
if (messages) {
|
if (messages) {
|
||||||
messages.splice(0, amount);
|
messages.splice(0, amount);
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export default function reducer(
|
|||||||
action: Actions,
|
action: Actions,
|
||||||
): State {
|
): State {
|
||||||
if (action.type === 'REGISTER_PLUGINS') {
|
if (action.type === 'REGISTER_PLUGINS') {
|
||||||
return produce(state, draft => {
|
return produce(state, (draft) => {
|
||||||
const {devicePlugins, clientPlugins} = draft;
|
const {devicePlugins, clientPlugins} = draft;
|
||||||
action.payload.forEach((p: PluginClass) => {
|
action.payload.forEach((p: PluginClass) => {
|
||||||
if (devicePlugins.has(p.id) || clientPlugins.has(p.id)) {
|
if (devicePlugins.has(p.id) || clientPlugins.has(p.id)) {
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ export class Group {
|
|||||||
setStaticView(require('../fb-stubs/SupportRequestFormV2').default),
|
setStaticView(require('../fb-stubs/SupportRequestFormV2').default),
|
||||||
);
|
);
|
||||||
const selectedApp = store.getState().connections.selectedApp;
|
const selectedApp = store.getState().connections.selectedApp;
|
||||||
const selectedClient = store.getState().connections.clients.find(o => {
|
const selectedClient = store.getState().connections.clients.find((o) => {
|
||||||
return o.id === store.getState().connections.selectedApp;
|
return o.id === store.getState().connections.selectedApp;
|
||||||
});
|
});
|
||||||
let errorMessage: string | undefined = undefined;
|
let errorMessage: string | undefined = undefined;
|
||||||
@@ -160,10 +160,10 @@ export class Group {
|
|||||||
errorMessage,
|
errorMessage,
|
||||||
'Deeplink',
|
'Deeplink',
|
||||||
10000,
|
10000,
|
||||||
payload => {
|
(payload) => {
|
||||||
store.dispatch(addStatusMessage(payload));
|
store.dispatch(addStatusMessage(payload));
|
||||||
},
|
},
|
||||||
payload => {
|
(payload) => {
|
||||||
store.dispatch(removeStatusMessage(payload));
|
store.dispatch(removeStatusMessage(payload));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -175,10 +175,10 @@ export class Group {
|
|||||||
'Please select an app and the device from the dropdown.',
|
'Please select an app and the device from the dropdown.',
|
||||||
'Deeplink',
|
'Deeplink',
|
||||||
10000,
|
10000,
|
||||||
payload => {
|
(payload) => {
|
||||||
store.dispatch(addStatusMessage(payload));
|
store.dispatch(addStatusMessage(payload));
|
||||||
},
|
},
|
||||||
payload => {
|
(payload) => {
|
||||||
store.dispatch(removeStatusMessage(payload));
|
store.dispatch(removeStatusMessage(payload));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -199,8 +199,8 @@ export class Group {
|
|||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
setSelectedPlugins(
|
setSelectedPlugins(
|
||||||
this.getPluginsToSelect().filter(s => {
|
this.getPluginsToSelect().filter((s) => {
|
||||||
return pluginsList.map(s => s.id).includes(s);
|
return pluginsList.map((s) => s.id).includes(s);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -231,7 +231,7 @@ export class Group {
|
|||||||
const emptyPlugins: Array<string> = [];
|
const emptyPlugins: Array<string> = [];
|
||||||
for (const plugin of this.requiredPlugins) {
|
for (const plugin of this.requiredPlugins) {
|
||||||
if (
|
if (
|
||||||
!activePersistentPlugins.find(o => {
|
!activePersistentPlugins.find((o) => {
|
||||||
return o.id === plugin;
|
return o.id === plugin;
|
||||||
})
|
})
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export default function reducer(
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
} else if (action.type === 'windowIsFocused') {
|
} else if (action.type === 'windowIsFocused') {
|
||||||
return produce(state, draft => {
|
return produce(state, (draft) => {
|
||||||
draft.timeline.push({
|
draft.timeline.push({
|
||||||
type: 'WINDOW_FOCUS_CHANGE',
|
type: 'WINDOW_FOCUS_CHANGE',
|
||||||
time: action.payload.time,
|
time: action.payload.time,
|
||||||
@@ -64,7 +64,7 @@ export default function reducer(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (action.type === 'SELECT_PLUGIN') {
|
} else if (action.type === 'SELECT_PLUGIN') {
|
||||||
return produce(state, draft => {
|
return produce(state, (draft) => {
|
||||||
draft.timeline.push({
|
draft.timeline.push({
|
||||||
type: 'PLUGIN_SELECTED',
|
type: 'PLUGIN_SELECTED',
|
||||||
time: action.payload.time,
|
time: action.payload.time,
|
||||||
|
|||||||
@@ -90,7 +90,9 @@ class Server extends EventEmitter {
|
|||||||
const {insecure, secure} = this.store.getState().application.serverPorts;
|
const {insecure, secure} = this.store.getState().application.serverPorts;
|
||||||
this.initialisePromise = this.certificateProvider
|
this.initialisePromise = this.certificateProvider
|
||||||
.loadSecureServerConfig()
|
.loadSecureServerConfig()
|
||||||
.then(options => (this.secureServer = this.startServer(secure, options)))
|
.then(
|
||||||
|
(options) => (this.secureServer = this.startServer(secure, options)),
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.insecureServer = this.startServer(insecure);
|
this.insecureServer = this.startServer(insecure);
|
||||||
return;
|
return;
|
||||||
@@ -116,12 +118,12 @@ class Server extends EventEmitter {
|
|||||||
let rsServer: RSocketServer<any, any> | undefined; // eslint-disable-line prefer-const
|
let rsServer: RSocketServer<any, any> | undefined; // eslint-disable-line prefer-const
|
||||||
const serverFactory = (onConnect: (socket: Socket) => void) => {
|
const serverFactory = (onConnect: (socket: Socket) => void) => {
|
||||||
const transportServer = sslConfig
|
const transportServer = sslConfig
|
||||||
? tls.createServer(sslConfig, socket => {
|
? tls.createServer(sslConfig, (socket) => {
|
||||||
onConnect(socket);
|
onConnect(socket);
|
||||||
})
|
})
|
||||||
: net.createServer(onConnect);
|
: net.createServer(onConnect);
|
||||||
transportServer
|
transportServer
|
||||||
.on('error', err => {
|
.on('error', (err) => {
|
||||||
server.emit('error', err);
|
server.emit('error', err);
|
||||||
console.error(`Error opening server on port ${port}`, 'server');
|
console.error(`Error opening server on port ${port}`, 'server');
|
||||||
reject(err);
|
reject(err);
|
||||||
@@ -174,8 +176,8 @@ class Server extends EventEmitter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const cleanup = () => {
|
const cleanup = () => {
|
||||||
Object.values(clients).map(p =>
|
Object.values(clients).map((p) =>
|
||||||
p.then(c => this.removeConnection(c.id)),
|
p.then((c) => this.removeConnection(c.id)),
|
||||||
);
|
);
|
||||||
this.store.dispatch({
|
this.store.dispatch({
|
||||||
type: 'UNREGISTER_DEVICES',
|
type: 'UNREGISTER_DEVICES',
|
||||||
@@ -201,7 +203,7 @@ class Server extends EventEmitter {
|
|||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
clients[app] = client;
|
clients[app] = client;
|
||||||
client.then(c => {
|
client.then((c) => {
|
||||||
ws.on('message', (m: any) => {
|
ws.on('message', (m: any) => {
|
||||||
const parsed = JSON.parse(m.toString());
|
const parsed = JSON.parse(m.toString());
|
||||||
if (parsed.app === app) {
|
if (parsed.app === app) {
|
||||||
@@ -213,7 +215,7 @@ class Server extends EventEmitter {
|
|||||||
}
|
}
|
||||||
case 'disconnect': {
|
case 'disconnect': {
|
||||||
const app = message.app;
|
const app = message.app;
|
||||||
(clients[app] || Promise.resolve()).then(c => {
|
(clients[app] || Promise.resolve()).then((c) => {
|
||||||
this.removeConnection(c.id);
|
this.removeConnection(c.id);
|
||||||
delete clients[app];
|
delete clients[app];
|
||||||
});
|
});
|
||||||
@@ -252,7 +254,7 @@ class Server extends EventEmitter {
|
|||||||
socket,
|
socket,
|
||||||
{app, os, device, device_id, sdk_version},
|
{app, os, device, device_id, sdk_version},
|
||||||
{csr, csr_path},
|
{csr, csr_path},
|
||||||
).then(client => {
|
).then((client) => {
|
||||||
return (resolvedClient = client);
|
return (resolvedClient = client);
|
||||||
});
|
});
|
||||||
let resolvedClient: Client | undefined;
|
let resolvedClient: Client | undefined;
|
||||||
@@ -260,7 +262,7 @@ class Server extends EventEmitter {
|
|||||||
socket.connectionStatus().subscribe({
|
socket.connectionStatus().subscribe({
|
||||||
onNext(payload) {
|
onNext(payload) {
|
||||||
if (payload.kind == 'ERROR' || payload.kind == 'CLOSED') {
|
if (payload.kind == 'ERROR' || payload.kind == 'CLOSED') {
|
||||||
client.then(client => {
|
client.then((client) => {
|
||||||
console.debug(`Device disconnected ${client.id}`, 'server');
|
console.debug(`Device disconnected ${client.id}`, 'server');
|
||||||
server.removeConnection(client.id);
|
server.removeConnection(client.id);
|
||||||
});
|
});
|
||||||
@@ -276,7 +278,7 @@ class Server extends EventEmitter {
|
|||||||
if (resolvedClient) {
|
if (resolvedClient) {
|
||||||
resolvedClient.onMessage(payload.data);
|
resolvedClient.onMessage(payload.data);
|
||||||
} else {
|
} else {
|
||||||
client.then(client => {
|
client.then((client) => {
|
||||||
client.onMessage(payload.data);
|
client.onMessage(payload.data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -306,7 +308,7 @@ class Server extends EventEmitter {
|
|||||||
payload: Payload<string, any>,
|
payload: Payload<string, any>,
|
||||||
): Single<Payload<string, any>> => {
|
): Single<Payload<string, any>> => {
|
||||||
if (typeof payload.data !== 'string') {
|
if (typeof payload.data !== 'string') {
|
||||||
return new Single(_ => {});
|
return new Single((_) => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
let rawData;
|
let rawData;
|
||||||
@@ -318,7 +320,7 @@ class Server extends EventEmitter {
|
|||||||
'clientMessage',
|
'clientMessage',
|
||||||
'server',
|
'server',
|
||||||
);
|
);
|
||||||
return new Single(_ => {});
|
return new Single((_) => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
const json: {
|
const json: {
|
||||||
@@ -330,7 +332,7 @@ class Server extends EventEmitter {
|
|||||||
console.debug('CSR received from device', 'server');
|
console.debug('CSR received from device', 'server');
|
||||||
|
|
||||||
const {csr, destination} = json;
|
const {csr, destination} = json;
|
||||||
return new Single(subscriber => {
|
return new Single((subscriber) => {
|
||||||
subscriber.onSubscribe(undefined);
|
subscriber.onSubscribe(undefined);
|
||||||
reportPlatformFailures(
|
reportPlatformFailures(
|
||||||
this.certificateProvider.processCertificateSigningRequest(
|
this.certificateProvider.processCertificateSigningRequest(
|
||||||
@@ -340,7 +342,7 @@ class Server extends EventEmitter {
|
|||||||
),
|
),
|
||||||
'processCertificateSigningRequest',
|
'processCertificateSigningRequest',
|
||||||
)
|
)
|
||||||
.then(result => {
|
.then((result) => {
|
||||||
subscriber.onComplete({
|
subscriber.onComplete({
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
deviceId: result.deviceId,
|
deviceId: result.deviceId,
|
||||||
@@ -352,13 +354,13 @@ class Server extends EventEmitter {
|
|||||||
deviceId: result.deviceId,
|
deviceId: result.deviceId,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
subscriber.onError(e);
|
subscriber.onError(e);
|
||||||
this.emit('client-setup-error', {client, error: e});
|
this.emit('client-setup-error', {client, error: e});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return new Single(_ => {});
|
return new Single((_) => {});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Leaving this here for a while for backwards compatibility,
|
// Leaving this here for a while for backwards compatibility,
|
||||||
@@ -388,7 +390,7 @@ class Server extends EventEmitter {
|
|||||||
const {csr, destination} = json;
|
const {csr, destination} = json;
|
||||||
this.certificateProvider
|
this.certificateProvider
|
||||||
.processCertificateSigningRequest(csr, clientData.os, destination)
|
.processCertificateSigningRequest(csr, clientData.os, destination)
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -398,11 +400,12 @@ class Server extends EventEmitter {
|
|||||||
|
|
||||||
close(): Promise<void> {
|
close(): Promise<void> {
|
||||||
if (this.initialisePromise) {
|
if (this.initialisePromise) {
|
||||||
return this.initialisePromise.then(_ => {
|
return this.initialisePromise.then((_) => {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
this.secureServer && this.secureServer.then(server => server.stop()),
|
this.secureServer &&
|
||||||
|
this.secureServer.then((server) => server.stop()),
|
||||||
this.insecureServer &&
|
this.insecureServer &&
|
||||||
this.insecureServer.then(server => server.stop()),
|
this.insecureServer.then((server) => server.stop()),
|
||||||
]).then(() => undefined);
|
]).then(() => undefined);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -424,7 +427,7 @@ class Server extends EventEmitter {
|
|||||||
// otherwise, use given device_id
|
// otherwise, use given device_id
|
||||||
const {csr_path, csr} = csrQuery;
|
const {csr_path, csr} = csrQuery;
|
||||||
return (csr_path && csr
|
return (csr_path && csr
|
||||||
? this.certificateProvider.extractAppNameFromCSR(csr).then(appName => {
|
? this.certificateProvider.extractAppNameFromCSR(csr).then((appName) => {
|
||||||
return this.certificateProvider.getTargetDeviceId(
|
return this.certificateProvider.getTargetDeviceId(
|
||||||
query.os,
|
query.os,
|
||||||
appName,
|
appName,
|
||||||
@@ -433,7 +436,7 @@ class Server extends EventEmitter {
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
: Promise.resolve(query.device_id)
|
: Promise.resolve(query.device_id)
|
||||||
).then(csrId => {
|
).then((csrId) => {
|
||||||
query.device_id = csrId;
|
query.device_id = csrId;
|
||||||
query.app = appNameWithUpdateHint(query);
|
query.app = appNameWithUpdateHint(query);
|
||||||
|
|
||||||
@@ -517,7 +520,7 @@ class ConnectionTracker {
|
|||||||
const time = Date.now();
|
const time = Date.now();
|
||||||
let entry = this.connectionAttempts.get(key) || [];
|
let entry = this.connectionAttempts.get(key) || [];
|
||||||
entry.push(time);
|
entry.push(time);
|
||||||
entry = entry.filter(t => t >= time - this.timeWindowMillis);
|
entry = entry.filter((t) => t >= time - this.timeWindowMillis);
|
||||||
|
|
||||||
this.connectionAttempts.set(key, entry);
|
this.connectionAttempts.set(key, entry);
|
||||||
if (entry.length >= this.connectionProblemThreshold) {
|
if (entry.length >= this.connectionProblemThreshold) {
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ const StyledButton = styled.div<{
|
|||||||
pulse?: boolean;
|
pulse?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
dropdown?: Array<MenuItemConstructorOptions>;
|
dropdown?: Array<MenuItemConstructorOptions>;
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
props.windowIsFocused && !props.disabled
|
props.windowIsFocused && !props.disabled
|
||||||
? colors.white
|
? colors.white
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const IconContainer = styled.div({
|
|||||||
});
|
});
|
||||||
IconContainer.displayName = 'ButtonGroupChain:IconContainer';
|
IconContainer.displayName = 'ButtonGroupChain:IconContainer';
|
||||||
|
|
||||||
const ButtonGroupChainContainer = styled.div<{iconSize: number}>(props => ({
|
const ButtonGroupChainContainer = styled.div<{iconSize: number}>((props) => ({
|
||||||
display: 'inline-flex',
|
display: 'inline-flex',
|
||||||
marginLeft: 10,
|
marginLeft: 10,
|
||||||
'&:first-child>*:not(:first-child):nth-child(odd)': {
|
'&:first-child>*:not(:first-child):nth-child(odd)': {
|
||||||
|
|||||||
@@ -116,11 +116,11 @@ export default class FileList extends Component<FileListProps, FileListState> {
|
|||||||
const name = files.shift();
|
const name = files.shift();
|
||||||
if (name) {
|
if (name) {
|
||||||
this.fetchFile(name)
|
this.fetchFile(name)
|
||||||
.then(data => {
|
.then((data) => {
|
||||||
filesSet.set(name, data);
|
filesSet.set(name, data);
|
||||||
next();
|
next();
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch((err) => {
|
||||||
setState({error: err, files: EMPTY_MAP});
|
setState({error: err, files: EMPTY_MAP});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,7 @@ export default class FileList extends Component<FileListProps, FileListState> {
|
|||||||
initialFetch(props: FileListProps) {
|
initialFetch(props: FileListProps) {
|
||||||
this.removeWatcher();
|
this.removeWatcher();
|
||||||
|
|
||||||
fs.access(props.src, fs.constants.R_OK, err => {
|
fs.access(props.src, fs.constants.R_OK, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.setState({error: err, files: EMPTY_MAP});
|
this.setState({error: err, files: EMPTY_MAP});
|
||||||
return;
|
return;
|
||||||
@@ -159,7 +159,7 @@ export default class FileList extends Component<FileListProps, FileListState> {
|
|||||||
this.fetchFiles();
|
this.fetchFiles();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.watcher.on('error', err => {
|
this.watcher.on('error', (err) => {
|
||||||
this.setState({error: err, files: EMPTY_MAP});
|
this.setState({error: err, files: EMPTY_MAP});
|
||||||
this.removeWatcher();
|
this.removeWatcher();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const defaultProps: Props = {
|
const defaultProps: Props = {
|
||||||
onPathChanged: _ => {},
|
onPathChanged: (_) => {},
|
||||||
placeholderText: '',
|
placeholderText: '',
|
||||||
defaultPath: '/',
|
defaultPath: '/',
|
||||||
showHiddenFiles: false,
|
showHiddenFiles: false,
|
||||||
@@ -92,12 +92,12 @@ export default function FileSelector({
|
|||||||
placeholder={placeholderText}
|
placeholder={placeholderText}
|
||||||
value={value}
|
value={value}
|
||||||
isValid={true}
|
isValid={true}
|
||||||
onDrop={e => {
|
onDrop={(e) => {
|
||||||
if (e.dataTransfer.files.length) {
|
if (e.dataTransfer.files.length) {
|
||||||
onChange(e.dataTransfer.files[0].path);
|
onChange(e.dataTransfer.files[0].path);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onChange={e => {
|
onChange={(e) => {
|
||||||
onChange(e.target.value);
|
onChange(e.target.value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const ColoredIconCustom = styled.div<{
|
|||||||
size: number;
|
size: number;
|
||||||
color?: string;
|
color?: string;
|
||||||
src: string;
|
src: string;
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
height: props.size,
|
height: props.size,
|
||||||
verticalAlign: 'middle',
|
verticalAlign: 'middle',
|
||||||
width: props.size,
|
width: props.size,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const animation = keyframes({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const LoadingIndicator = styled.div<{size: number}>(props => ({
|
const LoadingIndicator = styled.div<{size: number}>((props) => ({
|
||||||
animation: `${animation} 1s infinite linear`,
|
animation: `${animation} 1s infinite linear`,
|
||||||
width: props.size,
|
width: props.size,
|
||||||
height: props.size,
|
height: props.size,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const Row = styled.div({
|
|||||||
marginBottom: 5,
|
marginBottom: 5,
|
||||||
lineHeight: 1.34,
|
lineHeight: 1.34,
|
||||||
});
|
});
|
||||||
const Heading = styled.div<{level: number}>(props => ({
|
const Heading = styled.div<{level: number}>((props) => ({
|
||||||
fontSize: props.level === 1 ? 18 : 12,
|
fontSize: props.level === 1 ? 18 : 12,
|
||||||
textTransform: props.level > 1 ? 'uppercase' : undefined,
|
textTransform: props.level > 1 ? 'uppercase' : undefined,
|
||||||
color: props.level > 1 ? '#90949c' : undefined,
|
color: props.level > 1 ? '#90949c' : undefined,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ type MouseEventHandler = (
|
|||||||
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
|
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
const Markers = styled.div<{totalTime: number}>(props => ({
|
const Markers = styled.div<{totalTime: number}>((props) => ({
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
margin: 10,
|
margin: 10,
|
||||||
height: props.totalTime,
|
height: props.totalTime,
|
||||||
@@ -56,7 +56,7 @@ const Point = styled(FlexRow)<{
|
|||||||
threadColor: string;
|
threadColor: string;
|
||||||
selected: boolean;
|
selected: boolean;
|
||||||
cut: boolean;
|
cut: boolean;
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: props.positionY,
|
top: props.positionY,
|
||||||
left: 0,
|
left: 0,
|
||||||
@@ -187,8 +187,8 @@ export default class MarkerTimeline extends Component<Props, State> {
|
|||||||
|
|
||||||
timePoints.push({
|
timePoints.push({
|
||||||
timestamp,
|
timestamp,
|
||||||
markerNames: points.map(p => p.label),
|
markerNames: points.map((p) => p.label),
|
||||||
markerKeys: points.map(p => p.key),
|
markerKeys: points.map((p) => p.key),
|
||||||
positionY,
|
positionY,
|
||||||
isCut,
|
isCut,
|
||||||
color,
|
color,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const multilineStyle = (props: {valid: boolean}) => ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const MultiLineInput = styled.textarea<{valid?: boolean}>(props => ({
|
const MultiLineInput = styled.textarea<{valid?: boolean}>((props) => ({
|
||||||
...multilineStyle({valid: props.valid === undefined || props.valid}),
|
...multilineStyle({valid: props.valid === undefined || props.valid}),
|
||||||
padding: '0 10px',
|
padding: '0 10px',
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ OrderableContainer.displayName = 'Orderable:OrderableContainer';
|
|||||||
|
|
||||||
const OrderableItemContainer = styled.div<{
|
const OrderableItemContainer = styled.div<{
|
||||||
orientation: 'vertical' | 'horizontal';
|
orientation: 'vertical' | 'horizontal';
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
display: props.orientation === 'vertical' ? 'block' : 'inline-block',
|
display: props.orientation === 'vertical' ? 'block' : 'inline-block',
|
||||||
}));
|
}));
|
||||||
OrderableItemContainer.displayName = 'Orderable:OrderableItemContainer';
|
OrderableItemContainer.displayName = 'Orderable:OrderableItemContainer';
|
||||||
@@ -407,7 +407,7 @@ export default class Orderable extends React.Component<
|
|||||||
<OrderableContainer
|
<OrderableContainer
|
||||||
className={this.props.className}
|
className={this.props.className}
|
||||||
ref={this.setContainerRef}>
|
ref={this.setContainerRef}>
|
||||||
{order.map(key => {
|
{order.map((key) => {
|
||||||
const item = items[key];
|
const item = items[key];
|
||||||
if (item) {
|
if (item) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -88,14 +88,14 @@ export default class Panel extends React.Component<
|
|||||||
static PanelContainer = styled(FlexColumn)<{
|
static PanelContainer = styled(FlexColumn)<{
|
||||||
floating?: boolean;
|
floating?: boolean;
|
||||||
collapsed?: boolean;
|
collapsed?: boolean;
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
padding: props.floating ? 10 : 0,
|
padding: props.floating ? 10 : 0,
|
||||||
borderBottom: props.collapsed ? 'none' : BORDER,
|
borderBottom: props.collapsed ? 'none' : BORDER,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
static PanelHeader = styled(FlexBox)<{floating?: boolean; padded?: boolean}>(
|
static PanelHeader = styled(FlexBox)<{floating?: boolean; padded?: boolean}>(
|
||||||
props => ({
|
(props) => ({
|
||||||
backgroundColor: '#f6f7f9',
|
backgroundColor: '#f6f7f9',
|
||||||
border: props.floating ? BORDER : 'none',
|
border: props.floating ? BORDER : 'none',
|
||||||
borderBottom: BORDER,
|
borderBottom: BORDER,
|
||||||
@@ -113,7 +113,7 @@ export default class Panel extends React.Component<
|
|||||||
);
|
);
|
||||||
|
|
||||||
static PanelBody = styled(FlexColumn)<{floating?: boolean; padded?: boolean}>(
|
static PanelBody = styled(FlexColumn)<{floating?: boolean; padded?: boolean}>(
|
||||||
props => ({
|
(props) => ({
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
border: props.floating ? BORDER : 'none',
|
border: props.floating ? BORDER : 'none',
|
||||||
borderBottomLeftRadius: 2,
|
borderBottomLeftRadius: 2,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ type Opts = {
|
|||||||
skewLeft?: boolean;
|
skewLeft?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const PopoverContainer = styled(FlexColumn)<{opts?: Opts}>(props => ({
|
const PopoverContainer = styled(FlexColumn)<{opts?: Opts}>((props) => ({
|
||||||
backgroundColor: colors.white,
|
backgroundColor: colors.white,
|
||||||
borderRadius: 7,
|
borderRadius: 7,
|
||||||
border: '1px solid rgba(0,0,0,0.3)',
|
border: '1px solid rgba(0,0,0,0.3)',
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const LabelText = styled(Text)({
|
|||||||
});
|
});
|
||||||
LabelText.displayName = 'Select:LabelText';
|
LabelText.displayName = 'Select:LabelText';
|
||||||
|
|
||||||
const SelectMenu = styled.select<{grow?: boolean}>(props => ({
|
const SelectMenu = styled.select<{grow?: boolean}>((props) => ({
|
||||||
flexGrow: props.grow ? 1 : 0,
|
flexGrow: props.grow ? 1 : 0,
|
||||||
}));
|
}));
|
||||||
SelectMenu.displayName = 'Select:SelectMenu';
|
SelectMenu.displayName = 'Select:SelectMenu';
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const SidebarContainer = styled(FlexColumn)<{
|
|||||||
position: 'right' | 'top' | 'left' | 'bottom';
|
position: 'right' | 'top' | 'left' | 'bottom';
|
||||||
backgroundColor?: BackgroundClipProperty;
|
backgroundColor?: BackgroundClipProperty;
|
||||||
overflow?: boolean;
|
overflow?: boolean;
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
backgroundColor: props.backgroundColor || colors.macOSTitleBarBackgroundBlur,
|
backgroundColor: props.backgroundColor || colors.macOSTitleBarBackgroundBlur,
|
||||||
borderLeft: props.position === 'right' ? '1px solid #b3b3b3' : 'none',
|
borderLeft: props.position === 'right' ? '1px solid #b3b3b3' : 'none',
|
||||||
borderTop: props.position === 'bottom' ? '1px solid #b3b3b3' : 'none',
|
borderTop: props.position === 'bottom' ? '1px solid #b3b3b3' : 'none',
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import Text from './Text';
|
|||||||
/**
|
/**
|
||||||
* Subtle text that should not draw attention
|
* Subtle text that should not draw attention
|
||||||
*/
|
*/
|
||||||
const SmallText = styled(Text)<{center?: boolean}>(props => ({
|
const SmallText = styled(Text)<{center?: boolean}>((props) => ({
|
||||||
color: colors.light20,
|
color: colors.light20,
|
||||||
size: 10,
|
size: 10,
|
||||||
fontStyle: 'italic',
|
fontStyle: 'italic',
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ export default class StackTrace extends Component<{
|
|||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const columnOrder = Object.keys(COLUMNS).map(key => ({
|
const columnOrder = Object.keys(COLUMNS).map((key) => ({
|
||||||
key,
|
key,
|
||||||
visible: Boolean(columns[key]),
|
visible: Boolean(columns[key]),
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const TabListItem = styled.div<{
|
|||||||
active?: boolean;
|
active?: boolean;
|
||||||
width?: WidthProperty<number>;
|
width?: WidthProperty<number>;
|
||||||
container?: boolean;
|
container?: boolean;
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
background: props.container
|
background: props.container
|
||||||
? props.active
|
? props.active
|
||||||
? 'linear-gradient(to bottom, #67a6f7 0%, #0072FA 100%)'
|
? 'linear-gradient(to bottom, #67a6f7 0%, #0072FA 100%)'
|
||||||
@@ -251,7 +251,7 @@ export default function Tabs(props: {
|
|||||||
{comp.props.label}
|
{comp.props.label}
|
||||||
{closable && (
|
{closable && (
|
||||||
<CloseButton // eslint-disable-next-line react/jsx-no-bind
|
<CloseButton // eslint-disable-next-line react/jsx-no-bind
|
||||||
ref={ref => (closeButton = ref)} // eslint-disable-next-line react/jsx-no-bind
|
ref={(ref) => (closeButton = ref)} // eslint-disable-next-line react/jsx-no-bind
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
if (isActive && onActive) {
|
if (isActive && onActive) {
|
||||||
const index = keys.indexOf(key);
|
const index = keys.indexOf(key);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const Text = styled.span<{
|
|||||||
wordWrap?: WordWrapProperty;
|
wordWrap?: WordWrapProperty;
|
||||||
whiteSpace?: WhiteSpaceProperty;
|
whiteSpace?: WhiteSpaceProperty;
|
||||||
cursor?: CursorProperty;
|
cursor?: CursorProperty;
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
color: props.color ? props.color : 'inherit',
|
color: props.color ? props.color : 'inherit',
|
||||||
cursor: props.cursor ? props.cursor : 'auto',
|
cursor: props.cursor ? props.cursor : 'auto',
|
||||||
display: 'inline',
|
display: 'inline',
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export default function ToggleButton(props: Props) {
|
|||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
onClick={e => {
|
onClick={(e) => {
|
||||||
setSwitching(true);
|
setSwitching(true);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
props?.onClick?.(e);
|
props?.onClick?.(e);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import styled from '@emotion/styled';
|
|||||||
const Toolbar = styled(FlexRow)<{
|
const Toolbar = styled(FlexRow)<{
|
||||||
position?: 'bottom' | 'top';
|
position?: 'bottom' | 'top';
|
||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
backgroundColor: colors.light02,
|
backgroundColor: colors.light02,
|
||||||
borderBottom:
|
borderBottom:
|
||||||
props.position === 'bottom'
|
props.position === 'bottom'
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ const TooltipBubble = styled.div<{
|
|||||||
maxWidth: MaxWidthProperty<number>;
|
maxWidth: MaxWidthProperty<number>;
|
||||||
color: ColorProperty;
|
color: ColorProperty;
|
||||||
};
|
};
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
zIndex: 99999999999,
|
zIndex: 99999999999,
|
||||||
backgroundColor: props.options.backgroundColor,
|
backgroundColor: props.options.backgroundColor,
|
||||||
@@ -101,7 +101,7 @@ const TooltipTail = styled.div<{
|
|||||||
options: {
|
options: {
|
||||||
backgroundColor: BackgroundColorProperty;
|
backgroundColor: BackgroundColorProperty;
|
||||||
};
|
};
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
display: 'block',
|
display: 'block',
|
||||||
whiteSpace: 'pre',
|
whiteSpace: 'pre',
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type Props = {
|
|||||||
maxHeight?: number;
|
maxHeight?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const View = styled.div<Props>(props => ({
|
const View = styled.div<Props>((props) => ({
|
||||||
height: props.grow ? '100%' : 'auto',
|
height: props.grow ? '100%' : 'auto',
|
||||||
overflow: props.scrollable ? 'auto' : 'visible',
|
overflow: props.scrollable ? 'auto' : 'visible',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ const NumberValue = styled.span({
|
|||||||
});
|
});
|
||||||
NumberValue.displayName = 'DataDescription:NumberValue';
|
NumberValue.displayName = 'DataDescription:NumberValue';
|
||||||
|
|
||||||
const ColorBox = styled.span<{color: string}>(props => ({
|
const ColorBox = styled.span<{color: string}>((props) => ({
|
||||||
backgroundColor: props.color,
|
backgroundColor: props.color,
|
||||||
boxShadow: 'inset 0 0 1px rgba(0, 0, 0, 1)',
|
boxShadow: 'inset 0 0 1px rgba(0, 0, 0, 1)',
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
@@ -375,9 +375,9 @@ class ColorEditor extends Component<{
|
|||||||
<CompactPicker
|
<CompactPicker
|
||||||
color={colorInfo}
|
color={colorInfo}
|
||||||
colors={this.props.colorSet
|
colors={this.props.colorSet
|
||||||
.filter(x => x != 0)
|
.filter((x) => x != 0)
|
||||||
.map(parseColor)
|
.map(parseColor)
|
||||||
.map(rgba => {
|
.map((rgba) => {
|
||||||
if (!rgba) {
|
if (!rgba) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -527,7 +527,7 @@ function parseColor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const size = val.length;
|
const size = val.length;
|
||||||
const [r, g, b] = parts.map(num => {
|
const [r, g, b] = parts.map((num) => {
|
||||||
if (size === 3) {
|
if (size === 3) {
|
||||||
return parseInt(num + num, 16);
|
return parseInt(num + num, 16);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {TooltipOptions} from '../TooltipProvider';
|
|||||||
export {DataValueExtractor} from './DataPreview';
|
export {DataValueExtractor} from './DataPreview';
|
||||||
|
|
||||||
const BaseContainer = styled.div<{depth?: number; disabled?: boolean}>(
|
const BaseContainer = styled.div<{depth?: number; disabled?: boolean}>(
|
||||||
props => ({
|
(props) => ({
|
||||||
fontFamily: 'Menlo, monospace',
|
fontFamily: 'Menlo, monospace',
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
lineHeight: '17px',
|
lineHeight: '17px',
|
||||||
@@ -277,10 +277,10 @@ function isComponentExpanded(
|
|||||||
if (diffType === 'object') {
|
if (diffType === 'object') {
|
||||||
const sortedDataValues = Object.keys(data)
|
const sortedDataValues = Object.keys(data)
|
||||||
.sort()
|
.sort()
|
||||||
.map(key => data[key]);
|
.map((key) => data[key]);
|
||||||
const sortedDiffValues = Object.keys(diffValue)
|
const sortedDiffValues = Object.keys(diffValue)
|
||||||
.sort()
|
.sort()
|
||||||
.map(key => diffValue[key]);
|
.map((key) => diffValue[key]);
|
||||||
if (JSON.stringify(sortedDataValues) !== JSON.stringify(sortedDiffValues)) {
|
if (JSON.stringify(sortedDataValues) !== JSON.stringify(sortedDiffValues)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export function DesktopDropdown(props: {
|
|||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<DesktopDropdownContainer>
|
<DesktopDropdownContainer>
|
||||||
{React.Children.map(props.children, child => {
|
{React.Children.map(props.children, (child) => {
|
||||||
return (
|
return (
|
||||||
child &&
|
child &&
|
||||||
React.cloneElement(child, {
|
React.cloneElement(child, {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ const backgroundColorHover = (props: {selected: boolean; focused: boolean}) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const ElementsRowContainer = styled(ContextMenu)<any>(props => ({
|
const ElementsRowContainer = styled(ContextMenu)<any>((props) => ({
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: backgroundColor(props),
|
backgroundColor: backgroundColor(props),
|
||||||
@@ -85,7 +85,7 @@ const ElementsRowDecoration = styled(FlexRow)({
|
|||||||
});
|
});
|
||||||
ElementsRowDecoration.displayName = 'Elements:ElementsRowDecoration';
|
ElementsRowDecoration.displayName = 'Elements:ElementsRowDecoration';
|
||||||
|
|
||||||
const ElementsLine = styled.div<{childrenCount: number}>(props => ({
|
const ElementsLine = styled.div<{childrenCount: number}>((props) => ({
|
||||||
backgroundColor: colors.light20,
|
backgroundColor: colors.light20,
|
||||||
height: props.childrenCount * ROW_HEIGHT - 4,
|
height: props.childrenCount * ROW_HEIGHT - 4,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
@@ -136,7 +136,7 @@ class PartialHighlight extends PureComponent<{
|
|||||||
highlighted: string | undefined | null;
|
highlighted: string | undefined | null;
|
||||||
content: string;
|
content: string;
|
||||||
}> {
|
}> {
|
||||||
static HighlightedText = styled.span<{selected: boolean}>(props => ({
|
static HighlightedText = styled.span<{selected: boolean}>((props) => ({
|
||||||
backgroundColor: colors.lemon,
|
backgroundColor: colors.lemon,
|
||||||
color: props.selected ? `${colors.grapeDark3} !important` : 'auto',
|
color: props.selected ? `${colors.grapeDark3} !important` : 'auto',
|
||||||
}));
|
}));
|
||||||
@@ -270,7 +270,7 @@ class ElementsRow extends PureComponent<ElementsRowProps, ElementsRowState> {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
items = items.concat(
|
items = items.concat(
|
||||||
props.element.attributes.map(o => {
|
props.element.attributes.map((o) => {
|
||||||
return {
|
return {
|
||||||
label: `Copy ${o.name}`,
|
label: `Copy ${o.name}`,
|
||||||
click: () => {
|
click: () => {
|
||||||
@@ -341,7 +341,7 @@ class ElementsRow extends PureComponent<ElementsRowProps, ElementsRowState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const attributes = element.attributes
|
const attributes = element.attributes
|
||||||
? element.attributes.map(attr => (
|
? element.attributes.map((attr) => (
|
||||||
<ElementsRowAttribute
|
<ElementsRowAttribute
|
||||||
key={attr.name}
|
key={attr.name}
|
||||||
name={attr.name}
|
name={attr.name}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export class InspectorSidebar extends Component<Props, State> {
|
|||||||
|
|
||||||
const sections: Array<any> =
|
const sections: Array<any> =
|
||||||
(extensions &&
|
(extensions &&
|
||||||
extensions.map(ext =>
|
extensions.map((ext) =>
|
||||||
ext(
|
ext(
|
||||||
this.props.client,
|
this.props.client,
|
||||||
this.props.realClient,
|
this.props.realClient,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import React from 'react';
|
|||||||
import {ColorProperty} from 'csstype';
|
import {ColorProperty} from 'csstype';
|
||||||
|
|
||||||
const Token = styled(Text)<{focused?: boolean; color?: ColorProperty}>(
|
const Token = styled(Text)<{focused?: boolean; color?: ColorProperty}>(
|
||||||
props => ({
|
(props) => ({
|
||||||
display: 'inline-flex',
|
display: 'inline-flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: props.focused
|
backgroundColor: props.focused
|
||||||
@@ -43,7 +43,7 @@ Token.displayName = 'FilterToken:Token';
|
|||||||
const Key = styled(Text)<{
|
const Key = styled(Text)<{
|
||||||
type: 'exclude' | 'include' | 'enum';
|
type: 'exclude' | 'include' | 'enum';
|
||||||
focused?: boolean;
|
focused?: boolean;
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
paddingRight: 12,
|
paddingRight: 12,
|
||||||
@@ -73,7 +73,7 @@ const Value = styled(Text)({
|
|||||||
});
|
});
|
||||||
Value.displayName = 'FilterToken:Value';
|
Value.displayName = 'FilterToken:Value';
|
||||||
|
|
||||||
const Chevron = styled.div<{focused?: boolean}>(props => ({
|
const Chevron = styled.div<{focused?: boolean}>((props) => ({
|
||||||
border: 0,
|
border: 0,
|
||||||
paddingLeft: 3,
|
paddingLeft: 3,
|
||||||
paddingRight: 1,
|
paddingRight: 1,
|
||||||
@@ -187,7 +187,7 @@ export default class FilterToken extends PureComponent<Props> {
|
|||||||
if (filter.type === 'enum') {
|
if (filter.type === 'enum') {
|
||||||
let {value} = filter;
|
let {value} = filter;
|
||||||
if (value.indexOf(newValue) > -1) {
|
if (value.indexOf(newValue) > -1) {
|
||||||
value = value.filter(v => v !== newValue);
|
value = value.filter((v) => v !== newValue);
|
||||||
} else {
|
} else {
|
||||||
value = value.concat([newValue]);
|
value = value.concat([newValue]);
|
||||||
}
|
}
|
||||||
@@ -214,7 +214,7 @@ export default class FilterToken extends PureComponent<Props> {
|
|||||||
|
|
||||||
if (filter.type === 'enum') {
|
if (filter.type === 'enum') {
|
||||||
const getEnum = (value: string) =>
|
const getEnum = (value: string) =>
|
||||||
filter.enum.find(e => e.value === value);
|
filter.enum.find((e) => e.value === value);
|
||||||
const firstValue = getEnum(filter.value[0]);
|
const firstValue = getEnum(filter.value[0]);
|
||||||
const secondValue = getEnum(filter.value[1]);
|
const secondValue = getEnum(filter.value[1]);
|
||||||
if (filter.value.length === 0) {
|
if (filter.value.length === 0) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export const SearchInput = styled(Input)<{
|
|||||||
focus?: boolean;
|
focus?: boolean;
|
||||||
regex?: boolean;
|
regex?: boolean;
|
||||||
isValidInput?: boolean;
|
isValidInput?: boolean;
|
||||||
}>(props => ({
|
}>((props) => ({
|
||||||
border: props.focus ? '1px solid black' : 0,
|
border: props.focus ? '1px solid black' : 0,
|
||||||
...(props.regex ? {fontFamily: 'monospace'} : {}),
|
...(props.regex ? {fontFamily: 'monospace'} : {}),
|
||||||
padding: 0,
|
padding: 0,
|
||||||
@@ -186,9 +186,9 @@ const Searchable = (
|
|||||||
if (defaultFilters != null) {
|
if (defaultFilters != null) {
|
||||||
// merge default filter with persisted filters
|
// merge default filter with persisted filters
|
||||||
const savedStateFilters = savedState.filters;
|
const savedStateFilters = savedState.filters;
|
||||||
defaultFilters.forEach(defaultFilter => {
|
defaultFilters.forEach((defaultFilter) => {
|
||||||
const filterIndex = savedStateFilters.findIndex(
|
const filterIndex = savedStateFilters.findIndex(
|
||||||
f => f.key === defaultFilter.key,
|
(f) => f.key === defaultFilter.key,
|
||||||
);
|
);
|
||||||
const savedDefaultFilter = savedStateFilters[filterIndex];
|
const savedDefaultFilter = savedStateFilters[filterIndex];
|
||||||
if (filterIndex > -1 && savedDefaultFilter.type === 'enum') {
|
if (filterIndex > -1 && savedDefaultFilter.type === 'enum') {
|
||||||
@@ -196,11 +196,11 @@ const Searchable = (
|
|||||||
savedDefaultFilter.enum = defaultFilter.enum;
|
savedDefaultFilter.enum = defaultFilter.enum;
|
||||||
}
|
}
|
||||||
const filters = new Set(
|
const filters = new Set(
|
||||||
savedDefaultFilter.enum.map(filter => filter.value),
|
savedDefaultFilter.enum.map((filter) => filter.value),
|
||||||
);
|
);
|
||||||
savedStateFilters[
|
savedStateFilters[
|
||||||
filterIndex
|
filterIndex
|
||||||
].value = savedDefaultFilter.value.filter(value =>
|
].value = savedDefaultFilter.value.filter((value) =>
|
||||||
filters.has(value),
|
filters.has(value),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -281,9 +281,7 @@ const Searchable = (
|
|||||||
// the table (in case there is more than one table rendered at a time)
|
// the table (in case there is more than one table rendered at a time)
|
||||||
return (
|
return (
|
||||||
'TABLE_COLUMNS_' +
|
'TABLE_COLUMNS_' +
|
||||||
Object.keys(this.props.columns)
|
Object.keys(this.props.columns).join('_').toUpperCase()
|
||||||
.join('_')
|
|
||||||
.toUpperCase()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -374,7 +372,7 @@ const Searchable = (
|
|||||||
|
|
||||||
addFilter = (filter: Filter) => {
|
addFilter = (filter: Filter) => {
|
||||||
const filterIndex = this.state.filters.findIndex(
|
const filterIndex = this.state.filters.findIndex(
|
||||||
f => f.key === filter.key,
|
(f) => f.key === filter.key,
|
||||||
);
|
);
|
||||||
if (filterIndex > -1) {
|
if (filterIndex > -1) {
|
||||||
const filters = [...this.state.filters];
|
const filters = [...this.state.filters];
|
||||||
@@ -457,7 +455,7 @@ const Searchable = (
|
|||||||
clear = () =>
|
clear = () =>
|
||||||
this.setState({
|
this.setState({
|
||||||
filters: this.state.filters.filter(
|
filters: this.state.filters.filter(
|
||||||
f => f.type === 'enum' && f.persistent === true,
|
(f) => f.type === 'enum' && f.persistent === true,
|
||||||
),
|
),
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -54,12 +54,12 @@ const rowMatchesFilters = (filters: Array<Filter>, row: TableBodyRow) =>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.every(x => x === true);
|
.every((x) => x === true);
|
||||||
|
|
||||||
function rowMatchesRegex(values: Array<string>, regex: string): boolean {
|
function rowMatchesRegex(values: Array<string>, regex: string): boolean {
|
||||||
try {
|
try {
|
||||||
const re = new RegExp(regex);
|
const re = new RegExp(regex);
|
||||||
return values.some(x => re.test(x));
|
return values.some((x) => re.test(x));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ function rowMatchesSearchTerm(
|
|||||||
if (searchTerm == null || searchTerm.length === 0) {
|
if (searchTerm == null || searchTerm.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const rowValues = Object.keys(row.columns).map(key =>
|
const rowValues = Object.keys(row.columns).map((key) =>
|
||||||
textContent(row.columns[key].value),
|
textContent(row.columns[key].value),
|
||||||
);
|
);
|
||||||
if (isBodySearchEnabled) {
|
if (isBodySearchEnabled) {
|
||||||
@@ -91,7 +91,7 @@ function rowMatchesSearchTerm(
|
|||||||
if (isRegex) {
|
if (isRegex) {
|
||||||
return rowMatchesRegex(rowValues, searchTerm);
|
return rowMatchesRegex(rowValues, searchTerm);
|
||||||
}
|
}
|
||||||
return rowValues.some(x =>
|
return rowValues.some((x) =>
|
||||||
x.toLowerCase().includes(searchTerm.toLowerCase()),
|
x.toLowerCase().includes(searchTerm.toLowerCase()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,12 +48,12 @@ const rowMatchesFilters = (filters: Array<Filter>, row: TableBodyRow) =>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.every(x => x === true);
|
.every((x) => x === true);
|
||||||
|
|
||||||
function rowMatchesRegex(values: Array<string>, regex: string): boolean {
|
function rowMatchesRegex(values: Array<string>, regex: string): boolean {
|
||||||
try {
|
try {
|
||||||
const re = new RegExp(regex);
|
const re = new RegExp(regex);
|
||||||
return values.some(x => re.test(x));
|
return values.some((x) => re.test(x));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ function rowMatchesSearchTerm(
|
|||||||
if (searchTerm == null || searchTerm.length === 0) {
|
if (searchTerm == null || searchTerm.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const rowValues = Object.keys(row.columns).map(key =>
|
const rowValues = Object.keys(row.columns).map((key) =>
|
||||||
textContent(row.columns[key].value),
|
textContent(row.columns[key].value),
|
||||||
);
|
);
|
||||||
if (row.filterValue != null) {
|
if (row.filterValue != null) {
|
||||||
@@ -76,7 +76,7 @@ function rowMatchesSearchTerm(
|
|||||||
if (isRegex) {
|
if (isRegex) {
|
||||||
return rowMatchesRegex(rowValues, searchTerm);
|
return rowMatchesRegex(rowValues, searchTerm);
|
||||||
}
|
}
|
||||||
return rowValues.some(x =>
|
return rowValues.some((x) =>
|
||||||
x.toLowerCase().includes(searchTerm.toLowerCase()),
|
x.toLowerCase().includes(searchTerm.toLowerCase()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ type ManagedTableState = {
|
|||||||
shouldScrollToBottom: boolean;
|
shouldScrollToBottom: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Container = styled(FlexColumn)<{canOverflow?: boolean}>(props => ({
|
const Container = styled(FlexColumn)<{canOverflow?: boolean}>((props) => ({
|
||||||
overflow: props.canOverflow ? 'scroll' : 'visible',
|
overflow: props.canOverflow ? 'scroll' : 'visible',
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
}));
|
}));
|
||||||
@@ -169,10 +169,7 @@ export class ManagedTable extends React.Component<
|
|||||||
|
|
||||||
getTableKey = (): string => {
|
getTableKey = (): string => {
|
||||||
return (
|
return (
|
||||||
'TABLE_COLUMNS_' +
|
'TABLE_COLUMNS_' + Object.keys(this.props.columns).join('_').toUpperCase()
|
||||||
Object.keys(this.props.columns)
|
|
||||||
.join('_')
|
|
||||||
.toUpperCase()
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -195,7 +192,7 @@ export class ManagedTable extends React.Component<
|
|||||||
const columnOrder =
|
const columnOrder =
|
||||||
JSON.parse(window.localStorage.getItem(this.getTableKey()) || 'null') ||
|
JSON.parse(window.localStorage.getItem(this.getTableKey()) || 'null') ||
|
||||||
this.props.columnOrder ||
|
this.props.columnOrder ||
|
||||||
Object.keys(this.props.columns).map(key => ({key, visible: true}));
|
Object.keys(this.props.columns).map((key) => ({key, visible: true}));
|
||||||
this.state = {
|
this.state = {
|
||||||
columnOrder,
|
columnOrder,
|
||||||
columnKeys: this.computeColumnKeys(columnOrder),
|
columnKeys: this.computeColumnKeys(columnOrder),
|
||||||
@@ -288,7 +285,7 @@ export class ManagedTable extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeColumnKeys(columnOrder: TableColumnOrder) {
|
computeColumnKeys(columnOrder: TableColumnOrder) {
|
||||||
return columnOrder.map(k => (k.visible ? k.key : null)).filter(notNull);
|
return columnOrder.map((k) => (k.visible ? k.key : null)).filter(notNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollToHighlightedRows = () => {
|
scrollToHighlightedRows = () => {
|
||||||
@@ -335,7 +332,7 @@ export class ManagedTable extends React.Component<
|
|||||||
const {highlightedRows} = this.state;
|
const {highlightedRows} = this.state;
|
||||||
const lastItemKey = Array.from(this.state.highlightedRows).pop();
|
const lastItemKey = Array.from(this.state.highlightedRows).pop();
|
||||||
const lastItemIndex = this.props.rows.findIndex(
|
const lastItemIndex = this.props.rows.findIndex(
|
||||||
row => row.key === lastItemKey,
|
(row) => row.key === lastItemKey,
|
||||||
);
|
);
|
||||||
const newIndex = Math.min(
|
const newIndex = Math.min(
|
||||||
rows.length - 1,
|
rows.length - 1,
|
||||||
@@ -516,8 +513,8 @@ export class ManagedTable extends React.Component<
|
|||||||
{
|
{
|
||||||
label: 'Copy cell',
|
label: 'Copy cell',
|
||||||
submenu: this.state.columnOrder
|
submenu: this.state.columnOrder
|
||||||
.filter(c => c.visible)
|
.filter((c) => c.visible)
|
||||||
.map(c => c.key)
|
.map((c) => c.key)
|
||||||
.map((column, index) => ({
|
.map((column, index) => ({
|
||||||
label: this.props.columns[column].value,
|
label: this.props.columns[column].value,
|
||||||
click: () => {
|
click: () => {
|
||||||
@@ -559,9 +556,9 @@ export class ManagedTable extends React.Component<
|
|||||||
|
|
||||||
getHeaderText = (): string => {
|
getHeaderText = (): string => {
|
||||||
return this.state.columnOrder
|
return this.state.columnOrder
|
||||||
.filter(c => c.visible)
|
.filter((c) => c.visible)
|
||||||
.map(c => c.key)
|
.map((c) => c.key)
|
||||||
.map(key => this.props.columns[key].value)
|
.map((key) => this.props.columns[key].value)
|
||||||
.join('\t');
|
.join('\t');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -572,7 +569,7 @@ export class ManagedTable extends React.Component<
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return this.props.rows
|
return this.props.rows
|
||||||
.filter(row => highlightedRows.has(row.key))
|
.filter((row) => highlightedRows.has(row.key))
|
||||||
.map(
|
.map(
|
||||||
(row: TableBodyRow) =>
|
(row: TableBodyRow) =>
|
||||||
row.copyText || this.getTextContentOfRow(row.key).join('\t'),
|
row.copyText || this.getTextContentOfRow(row.key).join('\t'),
|
||||||
@@ -581,7 +578,7 @@ export class ManagedTable extends React.Component<
|
|||||||
};
|
};
|
||||||
|
|
||||||
getTextContentOfRow = (key: string): Array<string> => {
|
getTextContentOfRow = (key: string): Array<string> => {
|
||||||
const row = this.props.rows.find(row => row.key === key);
|
const row = this.props.rows.find((row) => row.key === key);
|
||||||
if (!row) {
|
if (!row) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -708,7 +705,7 @@ export class ManagedTable extends React.Component<
|
|||||||
}>
|
}>
|
||||||
<List
|
<List
|
||||||
itemCount={rows.length}
|
itemCount={rows.length}
|
||||||
itemSize={index =>
|
itemSize={(index) =>
|
||||||
(rows[index] && rows[index].height) ||
|
(rows[index] && rows[index].height) ||
|
||||||
rowLineHeight ||
|
rowLineHeight ||
|
||||||
DEFAULT_ROW_HEIGHT
|
DEFAULT_ROW_HEIGHT
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ type ManagedTableState = {
|
|||||||
shouldScrollToBottom: boolean;
|
shouldScrollToBottom: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Container = styled(FlexColumn)<{canOverflow?: boolean}>(props => ({
|
const Container = styled(FlexColumn)<{canOverflow?: boolean}>((props) => ({
|
||||||
overflow: props.canOverflow ? 'scroll' : 'visible',
|
overflow: props.canOverflow ? 'scroll' : 'visible',
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
}));
|
}));
|
||||||
@@ -161,10 +161,7 @@ class ManagedTable extends React.Component<
|
|||||||
|
|
||||||
getTableKey = (): string => {
|
getTableKey = (): string => {
|
||||||
return (
|
return (
|
||||||
'TABLE_COLUMNS_' +
|
'TABLE_COLUMNS_' + Object.keys(this.props.columns).join('_').toUpperCase()
|
||||||
Object.keys(this.props.columns)
|
|
||||||
.join('_')
|
|
||||||
.toUpperCase()
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -172,7 +169,7 @@ class ManagedTable extends React.Component<
|
|||||||
columnOrder:
|
columnOrder:
|
||||||
JSON.parse(window.localStorage.getItem(this.getTableKey()) || 'null') ||
|
JSON.parse(window.localStorage.getItem(this.getTableKey()) || 'null') ||
|
||||||
this.props.columnOrder ||
|
this.props.columnOrder ||
|
||||||
Object.keys(this.props.columns).map(key => ({key, visible: true})),
|
Object.keys(this.props.columns).map((key) => ({key, visible: true})),
|
||||||
columnSizes:
|
columnSizes:
|
||||||
this.props.tableKey && globalTableState[this.props.tableKey]
|
this.props.tableKey && globalTableState[this.props.tableKey]
|
||||||
? globalTableState[this.props.tableKey]
|
? globalTableState[this.props.tableKey]
|
||||||
@@ -316,7 +313,7 @@ class ManagedTable extends React.Component<
|
|||||||
const {highlightedRows} = this.state;
|
const {highlightedRows} = this.state;
|
||||||
const lastItemKey = Array.from(this.state.highlightedRows).pop();
|
const lastItemKey = Array.from(this.state.highlightedRows).pop();
|
||||||
const lastItemIndex = this.props.rows.findIndex(
|
const lastItemIndex = this.props.rows.findIndex(
|
||||||
row => row.key === lastItemKey,
|
(row) => row.key === lastItemKey,
|
||||||
);
|
);
|
||||||
const newIndex = Math.min(
|
const newIndex = Math.min(
|
||||||
rows.size - 1,
|
rows.size - 1,
|
||||||
@@ -497,8 +494,8 @@ class ManagedTable extends React.Component<
|
|||||||
{
|
{
|
||||||
label: 'Copy cell',
|
label: 'Copy cell',
|
||||||
submenu: this.state.columnOrder
|
submenu: this.state.columnOrder
|
||||||
.filter(c => c.visible)
|
.filter((c) => c.visible)
|
||||||
.map(c => c.key)
|
.map((c) => c.key)
|
||||||
.map((column, index) => ({
|
.map((column, index) => ({
|
||||||
label: this.props.columns[column].value,
|
label: this.props.columns[column].value,
|
||||||
click: () => {
|
click: () => {
|
||||||
@@ -540,9 +537,9 @@ class ManagedTable extends React.Component<
|
|||||||
|
|
||||||
getHeaderText = (): string => {
|
getHeaderText = (): string => {
|
||||||
return this.state.columnOrder
|
return this.state.columnOrder
|
||||||
.filter(c => c.visible)
|
.filter((c) => c.visible)
|
||||||
.map(c => c.key)
|
.map((c) => c.key)
|
||||||
.map(key => this.props.columns[key].value)
|
.map((key) => this.props.columns[key].value)
|
||||||
.join('\t');
|
.join('\t');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -553,7 +550,7 @@ class ManagedTable extends React.Component<
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return this.props.rows
|
return this.props.rows
|
||||||
.filter(row => highlightedRows.has(row.key))
|
.filter((row) => highlightedRows.has(row.key))
|
||||||
.map(
|
.map(
|
||||||
(row: TableBodyRow) =>
|
(row: TableBodyRow) =>
|
||||||
row.copyText || this.getTextContentOfRow(row.key).join('\t'),
|
row.copyText || this.getTextContentOfRow(row.key).join('\t'),
|
||||||
@@ -562,7 +559,7 @@ class ManagedTable extends React.Component<
|
|||||||
};
|
};
|
||||||
|
|
||||||
getTextContentOfRow = (key: string): Array<string> => {
|
getTextContentOfRow = (key: string): Array<string> => {
|
||||||
const row = this.props.rows.find(row => row.key === key);
|
const row = this.props.rows.find((row) => row.key === key);
|
||||||
if (!row) {
|
if (!row) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -606,7 +603,7 @@ class ManagedTable extends React.Component<
|
|||||||
const {onAddFilter, multiline, zebra, rows} = this.props;
|
const {onAddFilter, multiline, zebra, rows} = this.props;
|
||||||
const {columnOrder, columnSizes, highlightedRows} = this.state;
|
const {columnOrder, columnSizes, highlightedRows} = this.state;
|
||||||
const columnKeys = columnOrder
|
const columnKeys = columnOrder
|
||||||
.map(k => (k.visible ? k.key : null))
|
.map((k) => (k.visible ? k.key : null))
|
||||||
.filter(notNull);
|
.filter(notNull);
|
||||||
|
|
||||||
const row = rows.get(index);
|
const row = rows.get(index);
|
||||||
@@ -619,8 +616,8 @@ class ManagedTable extends React.Component<
|
|||||||
key={row.key}
|
key={row.key}
|
||||||
columnSizes={columnSizes}
|
columnSizes={columnSizes}
|
||||||
columnKeys={columnKeys}
|
columnKeys={columnKeys}
|
||||||
onMouseDown={e => this.onHighlight(e, row, index)}
|
onMouseDown={(e) => this.onHighlight(e, row, index)}
|
||||||
onMouseEnter={e => this.onMouseEnterRow(e, row, index)}
|
onMouseEnter={(e) => this.onMouseEnterRow(e, row, index)}
|
||||||
multiline={multiline}
|
multiline={multiline}
|
||||||
rowLineHeight={24}
|
rowLineHeight={24}
|
||||||
highlighted={highlightedRows.has(row.key)}
|
highlighted={highlightedRows.has(row.key)}
|
||||||
@@ -690,7 +687,7 @@ class ManagedTable extends React.Component<
|
|||||||
}>
|
}>
|
||||||
<List
|
<List
|
||||||
itemCount={rows.size}
|
itemCount={rows.size}
|
||||||
itemSize={index =>
|
itemSize={(index) =>
|
||||||
(rows.get(index) && rows.get(index)!.height) ||
|
(rows.get(index) && rows.get(index)!.height) ||
|
||||||
rowLineHeight ||
|
rowLineHeight ||
|
||||||
DEFAULT_ROW_HEIGHT
|
DEFAULT_ROW_HEIGHT
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user