Skip to content

Commit

Permalink
[menu-bar] Add logs to debug menu (#211)
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrieldonadel authored Nov 5, 2024
1 parent b4958b7 commit 5e10753
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 20 deletions.
11 changes: 10 additions & 1 deletion apps/menu-bar/modules/menu-bar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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') {
Expand All @@ -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 {
Expand Down Expand Up @@ -61,4 +69,5 @@ export default {
MenuBarModule.showMultiOptionAlert(title, message, options),
openPopover: () => MenuBarModule.openPopover(),
closePopover: () => MenuBarModule.closePopover(),
logs,
};
49 changes: 49 additions & 0 deletions apps/menu-bar/src/components/DebugLogs/DebugLogRow.tsx
Original file line number Diff line number Diff line change
@@ -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<ViewStyle>;
}

const DebugLogRow = ({ log, style }: Props) => {
const [isOpen, setIsOpen] = useState(false);

return (
<View style={style}>
<TouchableOpacity onPress={() => setIsOpen((prev) => !prev)} disabled={!log.info}>
<Row
flex="1"
style={{
paddingVertical: 5,
}}>
<Text style={{ marginRight: 40 }}>{log.command}</Text>
<Text style={{ flex: 1 }} numberOfLines={1}>
{log.info}
</Text>
</Row>
{isOpen ? <ExtraInfo log={log} /> : null}
</TouchableOpacity>
</View>
);
};

const ExtraInfo = ({ log }: Props) => {
let extraInfo = log.info;
const looksLikeJSON = extraInfo?.startsWith('{') || extraInfo?.startsWith('[');

if (looksLikeJSON) {
try {
extraInfo = JSON.parse(log.info);
} catch {}
}

return <ObjectInspector obj={extraInfo} />;
};

export default DebugLogRow;
45 changes: 45 additions & 0 deletions apps/menu-bar/src/components/DebugLogs/ObjectInspector.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<TouchableOpacity onPress={() => setIsOpen((prev) => !prev)}>
<View
style={{
flexDirection: 'row',
paddingVertical: 5,
flex: 1,
}}>
{isObject ? (
<Text>
{isOpen ? '▼' : '▶'} {name ? `${name}: ` : ''}
</Text>
) : (
<Text>
{name ? `${name}: ` : ''}
{String(obj)}
</Text>
)}
{isObject && !isOpen ? (
<Text style={{ opacity: 0.6, marginLeft: 6 }} numberOfLines={1}>
{JSON.stringify(obj)}
</Text>
) : null}
</View>
{isObject && isOpen ? (
<View style={{ marginLeft: 10 }}>
{Object.keys(obj).map((key) => (
<ObjectInspector obj={obj[key]} name={isArray ? `[${key}]` : key} />
))}
</View>
) : null}
</TouchableOpacity>
);
};
41 changes: 41 additions & 0 deletions apps/menu-bar/src/components/DebugLogs/index.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<ScrollView
contentContainerStyle={{
backgroundColor: palette['gray']['200'],
borderRadius: 4,
}}>
<Row
flex="1"
style={{
paddingHorizontal: 10,
paddingVertical: 5,
}}>
<Text style={{ marginRight: 40 }}>Command: </Text>
<Text style={{ flex: 1 }}>Extra info:</Text>
</Row>
{MenuBarModule.logs.map((log, index) => {
return (
<DebugLogRow
log={log}
key={log.command + index}
style={{
paddingHorizontal: 10,
backgroundColor: index % 2 === 1 ? palette['gray']['400'] : palette['gray']['200'],
}}
/>
);
})}
</ScrollView>
);
};
20 changes: 13 additions & 7 deletions apps/menu-bar/src/windows/DebugMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
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';

const DebugMenu = () => {
return (
<View flex="1" px="medium" pb="medium" padding="2" gap="1.5">
<Row>
<Text size="medium" style={{ fontWeight: 'bold' }}>
Logs
</Text>
</Row>
<DebugLogs />
<TouchableOpacity onPress={resetStorage}>
<Text color="warning">Reset storage</Text>
</TouchableOpacity>
<TouchableOpacity onPress={resetApolloStore}>
<Text color="warning">Clear Apollo Store</Text>
</TouchableOpacity>
<NativeColorPalette />
<Text color="secondary" style={styles.about}>
{`App version: ${MenuBarModule.appVersion}`}
</Text>
<Text color="secondary" style={styles.about}>
{`Build version: ${MenuBarModule.buildVersion}`}
</Text>
<Row>
<Text color="secondary" style={styles.about}>
{`App version: ${MenuBarModule.appVersion} - Build version: ${MenuBarModule.buildVersion}`}
</Text>
</Row>
</View>
);
};
Expand Down
15 changes: 5 additions & 10 deletions apps/menu-bar/src/windows/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,16 +227,11 @@ const Settings = () => {
<Text style={[styles.flex, { lineHeight: 15 }]} numberOfLines={2} size="tiny">
Log in or create an account to access your projects, builds and more.
</Text>
{__DEV__ ? (
<TouchableOpacity
onPress={() => WindowsNavigator.open('DebugMenu')}
style={[
styles.debugButton,
getStylesForColor('primary', theme)?.touchableStyle,
]}>
<SystemIconView systemIconName="ladybug" />
</TouchableOpacity>
) : null}
<TouchableOpacity
onPress={() => WindowsNavigator.open('DebugMenu')}
style={[styles.debugButton, getStylesForColor('primary', theme)?.touchableStyle]}>
<SystemIconView systemIconName="ladybug" />
</TouchableOpacity>
<Button
title="Sign Up"
onPress={() => handleAuthentication('signup')}
Expand Down
4 changes: 2 additions & 2 deletions apps/menu-bar/src/windows/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ export const WindowsNavigator = createWindowsNavigator({
options: {
title: 'Debug Menu',
windowStyle: {
height: 300,
width: 400,
height: 600,
width: 800,
},
},
},
Expand Down

0 comments on commit 5e10753

Please sign in to comment.