Convert logs plugin to TypeScript

Summary: _typescript_

Reviewed By: danielbuechele

Differential Revision: D17184173

fbshipit-source-id: c7a055544ee4d9e07e5685fa84669d68fd68bf31
This commit is contained in:
Pascal Hartig
2019-09-16 09:11:36 -07:00
committed by Facebook Github Bot
parent 25de8ee90a
commit 2fcd0cbcac
5 changed files with 87 additions and 72 deletions

View File

@@ -70,7 +70,10 @@ export {
TableColumnOrderVal, TableColumnOrderVal,
TableColumnSizes, TableColumnSizes,
} from './ui/components/table/types'; } from './ui/components/table/types';
export {default as ManagedTable} from './ui/components/table/ManagedTable'; export {
default as ManagedTable,
ManagedTable as ManagedTableClass,
} from './ui/components/table/ManagedTable';
export {ManagedTableProps} from './ui/components/table/ManagedTable'; export {ManagedTableProps} from './ui/components/table/ManagedTable';
export { export {
default as ManagedTable_immutable, default as ManagedTable_immutable,

View File

@@ -5,7 +5,7 @@
* @format * @format
*/ */
import {addEntriesToState, processEntry} from '../index'; import {addEntriesToState, processEntry} from '../index.tsx';
const entry = { const entry = {
tag: 'OpenGLRenderer', tag: 'OpenGLRenderer',

View File

@@ -5,19 +5,20 @@
* @format * @format
*/ */
import type { import {
TableBodyRow, TableBodyRow,
TableColumnOrder, TableColumnOrder,
TableColumnSizes, TableColumnSizes,
TableColumns, TableColumns,
} from 'flipper'; } from 'flipper';
import type {Counter} from './LogWatcher.tsx'; import {Counter} from './LogWatcher';
import type {Props as PluginProps} from '../../plugin.tsx'; import {Props as PluginProps, BaseAction} from '../../plugin';
import type {DeviceLogEntry} from '../../devices/BaseDevice.tsx'; import {DeviceLogEntry} from '../../devices/BaseDevice';
import { import {
Text, Text,
ManagedTable, ManagedTable,
ManagedTableClass,
Button, Button,
colors, colors,
ContextMenu, ContextMenu,
@@ -30,27 +31,33 @@ import {
Device, Device,
createPaste, createPaste,
textContent, textContent,
KeyboardActions,
} from 'flipper'; } from 'flipper';
import LogWatcher from './LogWatcher.tsx'; import LogWatcher from './LogWatcher';
import React from 'react';
import {MenuTemplate} from 'src/ui/components/ContextMenu';
const LOG_WATCHER_LOCAL_STORAGE_KEY = 'LOG_WATCHER_LOCAL_STORAGE_KEY'; const LOG_WATCHER_LOCAL_STORAGE_KEY = 'LOG_WATCHER_LOCAL_STORAGE_KEY';
type Entries = Array<{ type Entries = Array<{
row: TableBodyRow, row: TableBodyRow;
entry: DeviceLogEntry, entry: DeviceLogEntry;
}>; }>;
type State = {| type BaseState = {
rows: Array<TableBodyRow>, rows: Array<TableBodyRow>;
entries: Entries, entries: Entries;
key2entry: {[key: string]: DeviceLogEntry}, key2entry: {[key: string]: DeviceLogEntry};
highlightedRows: Set<string>, };
counters: Array<Counter>,
|};
type Actions = {||}; type AdditionalState = {
highlightedRows: Set<string>;
counters: Array<Counter>;
};
type PersistedState = {||}; type State = BaseState & AdditionalState;
type PersistedState = {};
const Icon = styled(Glyph)({ const Icon = styled(Glyph)({
marginTop: 5, marginTop: 5,
@@ -69,8 +76,8 @@ function getLineCount(str: string): number {
return count; return count;
} }
function keepKeys(obj, keys) { function keepKeys<A>(obj: A, keys: Array<string>): A {
const result = {}; const result: A = {} as A;
for (const key in obj) { for (const key in obj) {
if (keys.includes(key)) { if (keys.includes(key)) {
result[key] = obj[key]; result[key] = obj[key];
@@ -146,11 +153,11 @@ const INITIAL_COLUMN_ORDER = [
const LOG_TYPES: { const LOG_TYPES: {
[level: string]: { [level: string]: {
label: string, label: string;
color: string, color: string;
icon?: React.Node, icon?: React.ReactNode;
style?: Object, style?: Object;
}, };
} = { } = {
verbose: { verbose: {
label: 'Verbose', label: 'Verbose',
@@ -221,24 +228,26 @@ const HiddenScrollText = styled(Text)({
}, },
}); });
const LogCount = styled('div')(({backgroundColor}) => ({ const LogCount = styled('div')(
backgroundColor, ({backgroundColor}: {backgroundColor: string}) => ({
borderRadius: '999em', backgroundColor,
fontSize: 11, borderRadius: '999em',
marginTop: 4, fontSize: 11,
minWidth: 16, marginTop: 4,
height: 16, minWidth: 16,
color: colors.white, height: 16,
textAlign: 'center', color: colors.white,
lineHeight: '16px', textAlign: 'center',
paddingLeft: 4, lineHeight: '16px',
paddingRight: 4, paddingLeft: 4,
textOverflow: 'ellipsis', paddingRight: 4,
overflow: 'hidden', textOverflow: 'ellipsis',
whiteSpace: 'nowrap', overflow: 'hidden',
})); whiteSpace: 'nowrap',
}),
);
function pad(chunk: mixed, len: number): string { function pad(chunk: any, len: number): string {
let str = String(chunk); let str = String(chunk);
while (str.length < len) { while (str.length < len) {
str = `0${str}`; str = `0${str}`;
@@ -248,12 +257,12 @@ function pad(chunk: mixed, len: number): string {
export function addEntriesToState( export function addEntriesToState(
items: Entries, items: Entries,
state: $Shape<State> = { state: BaseState = {
rows: [], rows: [],
entries: [], entries: [],
key2entry: {}, key2entry: {},
}, },
): $Shape<State> { ): BaseState {
const rows = [...state.rows]; const rows = [...state.rows];
const entries = [...state.entries]; const entries = [...state.entries];
const key2entry = {...state.key2entry}; const key2entry = {...state.key2entry};
@@ -263,7 +272,7 @@ export function addEntriesToState(
entries.push({row, entry}); entries.push({row, entry});
key2entry[row.key] = entry; key2entry[row.key] = entry;
let previousEntry: ?DeviceLogEntry = null; let previousEntry: DeviceLogEntry | null = null;
if (i > 0) { if (i > 0) {
previousEntry = items[i - 1].entry; previousEntry = items[i - 1].entry;
@@ -285,7 +294,7 @@ export function addRowIfNeeded(
rows: Array<TableBodyRow>, rows: Array<TableBodyRow>,
row: TableBodyRow, row: TableBodyRow,
entry: DeviceLogEntry, entry: DeviceLogEntry,
previousEntry: ?DeviceLogEntry, previousEntry: DeviceLogEntry | null,
) { ) {
const previousRow = rows.length > 0 ? rows[rows.length - 1] : null; const previousRow = rows.length > 0 ? rows[rows.length - 1] : null;
if ( if (
@@ -315,10 +324,10 @@ export function processEntry(
entry: DeviceLogEntry, entry: DeviceLogEntry,
key: string, key: string,
): { ): {
row: TableBodyRow, row: TableBodyRow;
entry: DeviceLogEntry, entry: DeviceLogEntry;
} { } {
const {icon, style} = LOG_TYPES[(entry.type: string)] || LOG_TYPES.debug; const {icon, style} = LOG_TYPES[entry.type] || LOG_TYPES.debug;
// build the item, it will either be batched or added straight away // build the item, it will either be batched or added straight away
return { return {
entry, entry,
@@ -374,13 +383,16 @@ export function processEntry(
export default class LogTable extends FlipperDevicePlugin< export default class LogTable extends FlipperDevicePlugin<
State, State,
Actions, BaseAction,
PersistedState, PersistedState
> { > {
static keyboardActions = ['clear', 'goToBottom', 'createPaste']; static keyboardActions: KeyboardActions = [
'clear',
'goToBottom',
'createPaste',
];
initTimer: ?TimeoutID; batchTimer: NodeJS.Timeout | undefined;
batchTimer: ?TimeoutID;
static supportsDevice(device: Device) { static supportsDevice(device: Device) {
return device.os === 'iOS' || device.os === 'Android'; return device.os === 'iOS' || device.os === 'Android';
@@ -407,10 +419,10 @@ export default class LogTable extends FlipperDevicePlugin<
}; };
calculateHighlightedRows = ( calculateHighlightedRows = (
deepLinkPayload: ?string, deepLinkPayload: string | null,
rows: Array<TableBodyRow>, rows: Array<TableBodyRow>,
): Set<string> => { ): Set<string> => {
const highlightedRows = new Set(); const highlightedRows = new Set<string>();
if (!deepLinkPayload) { if (!deepLinkPayload) {
return highlightedRows; return highlightedRows;
} }
@@ -418,10 +430,8 @@ export default class LogTable extends FlipperDevicePlugin<
// Run through array from last to first, because we want to show the last // Run through array from last to first, because we want to show the last
// time it the log we are looking for appeared. // time it the log we are looking for appeared.
for (let i = rows.length - 1; i >= 0; i--) { for (let i = rows.length - 1; i >= 0; i--) {
if ( const filterValue = rows[i].filterValue;
rows[i].filterValue && if (filterValue != null && filterValue.includes(deepLinkPayload)) {
rows[i].filterValue.includes(deepLinkPayload)
) {
highlightedRows.add(rows[i].key); highlightedRows.add(rows[i].key);
break; break;
} }
@@ -431,7 +441,8 @@ export default class LogTable extends FlipperDevicePlugin<
const arr = deepLinkPayload.split('\n'); const arr = deepLinkPayload.split('\n');
for (const msg of arr) { for (const msg of arr) {
for (let i = rows.length - 1; i >= 0; i--) { for (let i = rows.length - 1; i >= 0; i--) {
if (rows[i].filterValue && rows[i].filterValue.includes(msg)) { const filterValue = rows[i].filterValue;
if (filterValue != null && filterValue.includes(msg)) {
highlightedRows.add(rows[i].key); highlightedRows.add(rows[i].key);
break; break;
} }
@@ -441,11 +452,11 @@ export default class LogTable extends FlipperDevicePlugin<
return highlightedRows; return highlightedRows;
}; };
tableRef: ?ManagedTable; tableRef: ManagedTableClass | undefined;
columns: TableColumns; columns: TableColumns;
columnSizes: TableColumnSizes; columnSizes: TableColumnSizes;
columnOrder: TableColumnOrder; columnOrder: TableColumnOrder;
logListener: ?Symbol; logListener: Symbol | undefined;
batch: Entries = []; batch: Entries = [];
queued: boolean = false; queued: boolean = false;
@@ -464,6 +475,7 @@ export default class LogTable extends FlipperDevicePlugin<
this.device this.device
.getLogs() .getLogs()
.map(log => processEntry(log, String(this.counter++))), .map(log => processEntry(log, String(this.counter++))),
this.state,
); );
this.state = { this.state = {
...initialState, ...initialState,
@@ -487,7 +499,7 @@ export default class LogTable extends FlipperDevicePlugin<
if (entry.message.match(counter.expression)) { if (entry.message.match(counter.expression)) {
counterUpdated = true; counterUpdated = true;
if (counter.notify) { if (counter.notify) {
new window.Notification(`${counter.label}`, { new Notification(`${counter.label}`, {
body: 'The watched log message appeared', body: 'The watched log message appeared',
}); });
} }
@@ -505,8 +517,8 @@ export default class LogTable extends FlipperDevicePlugin<
}; };
scheudleEntryForBatch = (item: { scheudleEntryForBatch = (item: {
row: TableBodyRow, row: TableBodyRow;
entry: DeviceLogEntry, entry: DeviceLogEntry;
}) => { }) => {
// batch up logs to be processed every 250ms, if we have lots of log // batch up logs to be processed every 250ms, if we have lots of log
// messages coming in, then calling an setState 200+ times is actually // messages coming in, then calling an setState 200+ times is actually
@@ -553,7 +565,7 @@ export default class LogTable extends FlipperDevicePlugin<
createPaste = () => { createPaste = () => {
let paste = ''; let paste = '';
const mapFn = row => const mapFn = (row: TableBodyRow) =>
Object.keys(COLUMNS) Object.keys(COLUMNS)
.map(key => textContent(row.columns[key].value)) .map(key => textContent(row.columns[key].value))
.join('\t'); .join('\t');
@@ -571,7 +583,7 @@ export default class LogTable extends FlipperDevicePlugin<
createPaste(paste); createPaste(paste);
}; };
setTableRef = (ref: React.ElementRef<typeof ManagedTable>) => { setTableRef = (ref: ManagedTableClass) => {
this.tableRef = ref; this.tableRef = ref;
}; };
@@ -608,7 +620,7 @@ export default class LogTable extends FlipperDevicePlugin<
flex: 1, flex: 1,
}); });
buildContextMenuItems = () => [ buildContextMenuItems: () => MenuTemplate = () => [
{ {
type: 'separator', type: 'separator',
}, },

View File

@@ -1,7 +1,7 @@
{ {
"name": "DeviceLogs", "name": "DeviceLogs",
"version": "1.0.0", "version": "1.0.0",
"main": "index.js", "main": "index.tsx",
"license": "MIT", "license": "MIT",
"dependencies": {}, "dependencies": {},
"title": "Logs", "title": "Logs",

View File

@@ -149,7 +149,7 @@ const Container = styled(FlexColumn)((props: {canOverflow?: boolean}) => ({
const globalTableState: {[key: string]: TableColumnSizes} = {}; const globalTableState: {[key: string]: TableColumnSizes} = {};
class ManagedTable extends React.Component< export class ManagedTable extends React.Component<
ManagedTableProps, ManagedTableProps,
ManagedTableState ManagedTableState
> { > {
@@ -607,7 +607,7 @@ class ManagedTable extends React.Component<
getRow = ({index, style}: {index: number; style: React.CSSProperties}) => { getRow = ({index, style}: {index: number; style: React.CSSProperties}) => {
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: Array<string> = columnOrder
.map(k => (k.visible ? k.key : null)) .map(k => (k.visible ? k.key : null))
.filter(notNull); .filter(notNull);