From 5e107538256085778729d89b45da951c6c4f3dc4 Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Mon, 4 Nov 2024 23:49:48 -0300 Subject: [PATCH] [menu-bar] Add logs to debug menu (#211) --- apps/menu-bar/modules/menu-bar/index.ts | 11 ++++- .../src/components/DebugLogs/DebugLogRow.tsx | 49 +++++++++++++++++++ .../components/DebugLogs/ObjectInspector.tsx | 45 +++++++++++++++++ .../src/components/DebugLogs/index.tsx | 41 ++++++++++++++++ apps/menu-bar/src/windows/DebugMenu.tsx | 20 +++++--- apps/menu-bar/src/windows/Settings.tsx | 15 ++---- apps/menu-bar/src/windows/index.ts | 4 +- 7 files changed, 165 insertions(+), 20 deletions(-) create mode 100644 apps/menu-bar/src/components/DebugLogs/DebugLogRow.tsx create mode 100644 apps/menu-bar/src/components/DebugLogs/ObjectInspector.tsx create mode 100644 apps/menu-bar/src/components/DebugLogs/index.tsx diff --git a/apps/menu-bar/modules/menu-bar/index.ts b/apps/menu-bar/modules/menu-bar/index.ts index 0da45b65..fc982fcf 100644 --- a/apps/menu-bar/modules/menu-bar/index.ts +++ b/apps/menu-bar/modules/menu-bar/index.ts @@ -4,6 +4,9 @@ import MenuBarModule, { emitter } from './src/MenuBarModule'; import Alert from '../../src/modules/Alert'; import { convertCliErrorObjectToError } from '../../src/utils/helpers'; +export type Log = { command: string; info: string }; +const logs: Log[] = []; + let hasShownCliErrorAlert = false; let listenerCounter = 0; async function runCli(command: string, args: string[], callback?: (status: string) => void) { @@ -12,11 +15,13 @@ async function runCli(command: string, args: string[], callback?: (status: strin if (event.listenerId !== id) { return; } + logs.push({ command, info: event.output }); callback?.(event.output); }; const listener = emitter.addListener('onCLIOutput', filteredCallback); try { const result = await MenuBarModule.runCli(command, args, id); + logs.push({ command, info: result }); return result; } catch (error) { if (error instanceof CodedError && error.code === 'ERR_INTERNAL_CLI') { @@ -29,7 +34,10 @@ async function runCli(command: string, args: string[], callback?: (status: strin } } else if (error instanceof Error) { // Original error from CLI is a stringified JSON object - throw convertCliErrorObjectToError(JSON.parse(error.message)); + const cliError = convertCliErrorObjectToError(JSON.parse(error.message)); + logs.push({ command, info: cliError.message }); + + throw cliError; } throw error; } finally { @@ -61,4 +69,5 @@ export default { MenuBarModule.showMultiOptionAlert(title, message, options), openPopover: () => MenuBarModule.openPopover(), closePopover: () => MenuBarModule.closePopover(), + logs, }; diff --git a/apps/menu-bar/src/components/DebugLogs/DebugLogRow.tsx b/apps/menu-bar/src/components/DebugLogs/DebugLogRow.tsx new file mode 100644 index 00000000..62b4deed --- /dev/null +++ b/apps/menu-bar/src/components/DebugLogs/DebugLogRow.tsx @@ -0,0 +1,49 @@ +import { useState } from 'react'; +import { TouchableOpacity, StyleProp, ViewStyle } from 'react-native'; + +import { ObjectInspector } from './ObjectInspector'; +import type { Log } from '../../../modules/menu-bar/index'; +import { Text } from '../Text'; +import { View, Row } from '../View'; + +interface Props { + log: Log; + style?: StyleProp; +} + +const DebugLogRow = ({ log, style }: Props) => { + const [isOpen, setIsOpen] = useState(false); + + return ( + + setIsOpen((prev) => !prev)} disabled={!log.info}> + + {log.command} + + {log.info} + + + {isOpen ? : null} + + + ); +}; + +const ExtraInfo = ({ log }: Props) => { + let extraInfo = log.info; + const looksLikeJSON = extraInfo?.startsWith('{') || extraInfo?.startsWith('['); + + if (looksLikeJSON) { + try { + extraInfo = JSON.parse(log.info); + } catch {} + } + + return ; +}; + +export default DebugLogRow; diff --git a/apps/menu-bar/src/components/DebugLogs/ObjectInspector.tsx b/apps/menu-bar/src/components/DebugLogs/ObjectInspector.tsx new file mode 100644 index 00000000..eaf4409b --- /dev/null +++ b/apps/menu-bar/src/components/DebugLogs/ObjectInspector.tsx @@ -0,0 +1,45 @@ +import { useState } from 'react'; +import { TouchableOpacity } from 'react-native'; + +import { Text } from '../Text'; +import { View } from '../View'; + +export const ObjectInspector = ({ obj, name }: { obj: any; name?: string }) => { + const [isOpen, setIsOpen] = useState(false); + const isObject = typeof obj === 'object'; + const isArray = Array.isArray(obj); + + return ( + setIsOpen((prev) => !prev)}> + + {isObject ? ( + + {isOpen ? '▼' : '▶'} {name ? `${name}: ` : ''} + + ) : ( + + {name ? `${name}: ` : ''} + {String(obj)} + + )} + {isObject && !isOpen ? ( + + {JSON.stringify(obj)} + + ) : null} + + {isObject && isOpen ? ( + + {Object.keys(obj).map((key) => ( + + ))} + + ) : null} + + ); +}; diff --git a/apps/menu-bar/src/components/DebugLogs/index.tsx b/apps/menu-bar/src/components/DebugLogs/index.tsx new file mode 100644 index 00000000..79a309b3 --- /dev/null +++ b/apps/menu-bar/src/components/DebugLogs/index.tsx @@ -0,0 +1,41 @@ +import { ScrollView } from 'react-native'; + +import DebugLogRow from './DebugLogRow'; +import MenuBarModule from '../../modules/MenuBarModule'; +import { useExpoPalette } from '../../utils/useExpoTheme'; +import { Text } from '../Text'; +import { Row } from '../View'; + +export const DebugLogs = () => { + const palette = useExpoPalette(); + + return ( + + + Command: + Extra info: + + {MenuBarModule.logs.map((log, index) => { + return ( + + ); + })} + + ); +}; diff --git a/apps/menu-bar/src/windows/DebugMenu.tsx b/apps/menu-bar/src/windows/DebugMenu.tsx index 86e9638b..63ff2cbb 100644 --- a/apps/menu-bar/src/windows/DebugMenu.tsx +++ b/apps/menu-bar/src/windows/DebugMenu.tsx @@ -1,6 +1,7 @@ import { StyleSheet, TouchableOpacity } from 'react-native'; -import { View, Text } from '../components'; +import { View, Row, Text } from '../components'; +import { DebugLogs } from '../components/DebugLogs'; import NativeColorPalette from '../components/NativeColorPalette'; import MenuBarModule from '../modules/MenuBarModule'; import { resetApolloStore, resetStorage } from '../modules/Storage'; @@ -8,6 +9,12 @@ import { resetApolloStore, resetStorage } from '../modules/Storage'; const DebugMenu = () => { return ( + + + Logs + + + Reset storage @@ -15,12 +22,11 @@ const DebugMenu = () => { Clear Apollo Store - - {`App version: ${MenuBarModule.appVersion}`} - - - {`Build version: ${MenuBarModule.buildVersion}`} - + + + {`App version: ${MenuBarModule.appVersion} - Build version: ${MenuBarModule.buildVersion}`} + + ); }; diff --git a/apps/menu-bar/src/windows/Settings.tsx b/apps/menu-bar/src/windows/Settings.tsx index e5fdc0bf..ae7ed629 100644 --- a/apps/menu-bar/src/windows/Settings.tsx +++ b/apps/menu-bar/src/windows/Settings.tsx @@ -227,16 +227,11 @@ const Settings = () => { Log in or create an account to access your projects, builds and more. - {__DEV__ ? ( - WindowsNavigator.open('DebugMenu')} - style={[ - styles.debugButton, - getStylesForColor('primary', theme)?.touchableStyle, - ]}> - - - ) : null} + WindowsNavigator.open('DebugMenu')} + style={[styles.debugButton, getStylesForColor('primary', theme)?.touchableStyle]}> + +