Summary: Bumps [prettier](https://github.com/prettier/prettier) from 2.2.1 to 2.3.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/prettier/prettier/releases">prettier's releases</a>.</em></p> <blockquote> <h2>2.3.0</h2> <p><a href="https://github.com/prettier/prettier/compare/2.2.1...2.3.0">diff</a></p> <p>{emoji:1f517} <a href="https://prettier.io/blog/2021/05/09/2.3.0.html">Release Notes</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md">prettier's changelog</a>.</em></p> <blockquote> <h1>2.3.0</h1> <p><a href="https://github.com/prettier/prettier/compare/2.2.1...2.3.0">diff</a></p> <p>{emoji:1f517} <a href="https://prettier.io/blog/2021/05/09/2.3.0.html">Release Notes</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="2afc3b9ae6"><code>2afc3b9</code></a> Release 2.3.0</li> <li><a href="7cfa9aa89b"><code>7cfa9aa</code></a> Fix pre-commit hook setup command (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10710">#10710</a>)</li> <li><a href="c8c02b4753"><code>c8c02b4</code></a> Build(deps-dev): Bump concurrently from 6.0.2 to 6.1.0 in /website (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10834">#10834</a>)</li> <li><a href="6506e0f50e"><code>6506e0f</code></a> Build(deps-dev): Bump webpack-cli from 4.6.0 to 4.7.0 in /website (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10836">#10836</a>)</li> <li><a href="69fae9c291"><code>69fae9c</code></a> Build(deps): Bump flow-parser from 0.150.0 to 0.150.1 (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10839">#10839</a>)</li> <li><a href="164a6e2351"><code>164a6e2</code></a> Switch CLI to async (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10804">#10804</a>)</li> <li><a href="d3e7e2f634"><code>d3e7e2f</code></a> Build(deps): Bump codecov/codecov-action from v1.4.1 to v1.5.0 (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10833">#10833</a>)</li> <li><a href="9e09845da0"><code>9e09845</code></a> Build(deps): Bump <code>@angular/compiler</code> from 11.2.12 to 11.2.13 (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10838">#10838</a>)</li> <li><a href="1bfab3d045"><code>1bfab3d</code></a> Build(deps-dev): Bump eslint from 7.25.0 to 7.26.0 (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10840">#10840</a>)</li> <li><a href="387fce4ed8"><code>387fce4</code></a> Minor formatting tweaks (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10807">#10807</a>)</li> <li>Additional commits viewable in <a href="https://github.com/prettier/prettier/compare/2.2.1...2.3.0">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `dependabot rebase` will rebase this PR - `dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `dependabot merge` will merge this PR after your CI passes on it - `dependabot squash and merge` will squash and merge this PR after your CI passes on it - `dependabot cancel merge` will cancel a previously requested merge and block automerging - `dependabot reopen` will reopen this PR if it is closed - `dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Pull Request resolved: https://github.com/facebook/flipper/pull/2300 Reviewed By: passy Differential Revision: D28323849 Pulled By: cekkaewnumchai fbshipit-source-id: 1842877ccc9a9587af7f0d9ff9432c2075c8ee22
249 lines
5.7 KiB
TypeScript
249 lines
5.7 KiB
TypeScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
*/
|
|
|
|
import {
|
|
DevicePluginClient,
|
|
DeviceLogEntry,
|
|
usePlugin,
|
|
createDataSource,
|
|
DataTable,
|
|
DataTableColumn,
|
|
theme,
|
|
DataTableManager,
|
|
createState,
|
|
useValue,
|
|
DataFormatter,
|
|
} from 'flipper-plugin';
|
|
import {
|
|
PlayCircleOutlined,
|
|
PauseCircleOutlined,
|
|
DeleteOutlined,
|
|
} from '@ant-design/icons';
|
|
import React, {createRef, CSSProperties} from 'react';
|
|
import {Badge, Button} from 'antd';
|
|
|
|
import {baseRowStyle, logTypes} from './logTypes';
|
|
|
|
export type ExtendedLogEntry = DeviceLogEntry & {
|
|
count: number;
|
|
};
|
|
|
|
function createColumnConfig(
|
|
_os: 'iOS' | 'Android' | 'Metro',
|
|
): DataTableColumn<ExtendedLogEntry>[] {
|
|
return [
|
|
{
|
|
key: 'type',
|
|
title: '',
|
|
width: 30,
|
|
filters: Object.entries(logTypes).map(([value, config]) => ({
|
|
label: config.label,
|
|
value,
|
|
enabled: config.enabled,
|
|
})),
|
|
onRender(entry) {
|
|
return entry.count > 1 ? (
|
|
<Badge
|
|
count={entry.count}
|
|
size="small"
|
|
style={{
|
|
marginTop: 4,
|
|
color: theme.white,
|
|
background:
|
|
(logTypes[entry.type]?.style as any)?.color ??
|
|
theme.textColorSecondary,
|
|
}}
|
|
/>
|
|
) : (
|
|
logTypes[entry.type]?.icon
|
|
);
|
|
},
|
|
},
|
|
{
|
|
key: 'date',
|
|
title: 'Time',
|
|
width: 120,
|
|
},
|
|
{
|
|
key: 'pid',
|
|
title: 'PID',
|
|
width: 60,
|
|
visible: true,
|
|
},
|
|
{
|
|
key: 'tid',
|
|
title: 'TID',
|
|
width: 60,
|
|
visible: false,
|
|
},
|
|
{
|
|
key: 'tag',
|
|
title: 'Tag',
|
|
width: 160,
|
|
},
|
|
{
|
|
key: 'app',
|
|
title: 'App',
|
|
width: 160,
|
|
visible: false,
|
|
},
|
|
{
|
|
key: 'message',
|
|
title: 'Message',
|
|
wrap: true,
|
|
formatters: [
|
|
DataFormatter.truncate(400),
|
|
DataFormatter.prettyPrintJson,
|
|
DataFormatter.linkify,
|
|
],
|
|
},
|
|
];
|
|
}
|
|
|
|
function getRowStyle(entry: DeviceLogEntry): CSSProperties | undefined {
|
|
return (logTypes[entry.type]?.style as any) ?? baseRowStyle;
|
|
}
|
|
|
|
export function devicePlugin(client: DevicePluginClient) {
|
|
const rows = createDataSource<ExtendedLogEntry>([], {
|
|
limit: 200000,
|
|
persist: 'logs',
|
|
});
|
|
const isPaused = createState(true);
|
|
const tableManagerRef =
|
|
createRef<undefined | DataTableManager<ExtendedLogEntry>>();
|
|
|
|
client.onDeepLink((payload: unknown) => {
|
|
if (typeof payload === 'string') {
|
|
// timeout as we want to await restoring any previous scroll positin first, then scroll to the
|
|
setTimeout(() => {
|
|
let hasMatch = false;
|
|
rows.view.output(0, rows.view.size).forEach((row, index) => {
|
|
if (row.message.includes(payload)) {
|
|
tableManagerRef.current?.selectItem(index, hasMatch);
|
|
hasMatch = true;
|
|
}
|
|
});
|
|
}, 500);
|
|
}
|
|
});
|
|
|
|
client.addMenuEntry(
|
|
{
|
|
action: 'clear',
|
|
handler: clearLogs,
|
|
},
|
|
{
|
|
action: 'createPaste',
|
|
handler: createPaste,
|
|
},
|
|
{
|
|
action: 'goToBottom',
|
|
handler: goToBottom,
|
|
},
|
|
);
|
|
|
|
let logDisposer: (() => void) | undefined;
|
|
|
|
function resumePause() {
|
|
if (isPaused.get() && client.device.isConnected) {
|
|
// start listening to the logs
|
|
isPaused.set(false);
|
|
logDisposer = client.device.onLogEntry((entry: DeviceLogEntry) => {
|
|
const lastIndex = rows.size - 1;
|
|
const previousRow = rows.get(lastIndex);
|
|
if (
|
|
previousRow &&
|
|
previousRow.message === entry.message &&
|
|
previousRow.tag === entry.tag &&
|
|
previousRow.type === entry.type
|
|
) {
|
|
rows.update(lastIndex, {
|
|
...previousRow,
|
|
count: previousRow.count + 1,
|
|
});
|
|
} else {
|
|
rows.append({
|
|
...entry,
|
|
count: 1,
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
logDisposer?.();
|
|
isPaused.set(true);
|
|
}
|
|
}
|
|
|
|
function clearLogs() {
|
|
// Non public Android specific api
|
|
(client.device.realDevice as any)?.clearLogs?.();
|
|
rows.clear();
|
|
tableManagerRef.current?.clearSelection();
|
|
}
|
|
|
|
function createPaste() {
|
|
let selection = tableManagerRef.current?.getSelectedItems();
|
|
if (!selection?.length) {
|
|
selection = rows.view.output(0, rows.view.size);
|
|
}
|
|
if (selection?.length) {
|
|
client.createPaste(JSON.stringify(selection, null, 2));
|
|
}
|
|
}
|
|
|
|
function goToBottom() {
|
|
tableManagerRef?.current?.selectItem(rows.view.size - 1);
|
|
}
|
|
|
|
// start listening to the logs
|
|
resumePause();
|
|
|
|
const columns = createColumnConfig(client.device.os as any);
|
|
|
|
return {
|
|
columns,
|
|
isConnected: client.device.isConnected,
|
|
isPaused,
|
|
tableManagerRef,
|
|
rows,
|
|
clearLogs,
|
|
resumePause,
|
|
};
|
|
}
|
|
|
|
export function Component() {
|
|
const plugin = usePlugin(devicePlugin);
|
|
const paused = useValue(plugin.isPaused);
|
|
return (
|
|
<DataTable<ExtendedLogEntry>
|
|
dataSource={plugin.rows}
|
|
columns={plugin.columns}
|
|
enableAutoScroll
|
|
onRowStyle={getRowStyle}
|
|
extraActions={
|
|
plugin.isConnected ? (
|
|
<>
|
|
<Button
|
|
title={`Click to ${paused ? 'resume' : 'pause'} the log stream`}
|
|
danger={paused}
|
|
onClick={plugin.resumePause}>
|
|
{paused ? <PlayCircleOutlined /> : <PauseCircleOutlined />}
|
|
</Button>
|
|
<Button title="Clear logs" onClick={plugin.clearLogs}>
|
|
<DeleteOutlined />
|
|
</Button>
|
|
</>
|
|
) : undefined
|
|
}
|
|
tableManagerRef={plugin.tableManagerRef}
|
|
/>
|
|
);
|
|
}
|