Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [EUDIW-210] Add debug overlay screen #52

Merged
merged 6 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
} from '@pagopa/io-app-design-system';
import {BottomSheetModalProvider} from '@gorhom/bottom-sheet';
import {persistor, store} from './ts/store';
import {RootStackNavigator} from './ts/navigation/RootStacknavigator';
import IdentificationModal from './ts/screens/IdentificationModal';
import RootContainer from './ts/screens/RootContainer';

function App(): React.JSX.Element {
return (
Expand All @@ -25,7 +25,7 @@ function App(): React.JSX.Element {
<IODSExperimentalContextProvider isExperimentaEnabled={true}>
<ToastProvider>
<BottomSheetModalProvider>
<RootStackNavigator />
<RootContainer />
<IdentificationModal />
</BottomSheetModalProvider>
</ToastProvider>
Expand Down
6 changes: 6 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1578,6 +1578,8 @@ PODS:
- React-Core
- RNCAsyncStorage (2.1.0):
- React-Core
- RNCClipboard (1.15.0):
- React-Core
- RNDeviceInfo (14.0.1):
- React-Core
- RNGestureHandler (2.21.2):
Expand Down Expand Up @@ -1810,6 +1812,7 @@ DEPENDENCIES:
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- RNBootSplash (from `../node_modules/react-native-bootsplash`)
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`)
Expand Down Expand Up @@ -1967,6 +1970,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-bootsplash"
RNCAsyncStorage:
:path: "../node_modules/@react-native-async-storage/async-storage"
RNCClipboard:
:path: "../node_modules/@react-native-clipboard/clipboard"
RNDeviceInfo:
:path: "../node_modules/react-native-device-info"
RNGestureHandler:
Expand Down Expand Up @@ -2055,6 +2060,7 @@ SPEC CHECKSUMS:
ReactCommon: 36d48f542b4010786d6b2bcee615fe5f906b7105
RNBootSplash: 74d11cdbe6bfafa66014fc54a7105b79350333bd
RNCAsyncStorage: c91d753ede6dc21862c4922cd13f98f7cfde578e
RNCClipboard: dbcf25b8f666b4685c02eeb65be981d30198e505
RNDeviceInfo: afc27b3f24bd0e97181bf3e9f23cfa4c9040dd32
RNGestureHandler: 5b24d10761754ad271b714e536c457fd89b17c54
RNReactNativeHapticFeedback: 00ba111b82aa266bb3ee1aa576831c2ea9a9dfad
Expand Down
17 changes: 10 additions & 7 deletions locales/en/global.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
},
"settings": {
"title": "Settings",
"listHeaders": {
"test": {
"title": "Test",
"walletReset": "Reset wallet",
"onboardingReset": "Reset onboarding"
}
}
"reset": {
"title": "Reset App",
"walletReset": "Reset wallet",
"onboardingReset": "Reset onboarding"
},
"debug": "Enable debug mode",
"version": "Version"
},
"buttons": {
"next": "Next",
Expand Down Expand Up @@ -44,6 +44,9 @@
"hint": "Wait for the content load"
}
},
"clipboard": {
"copyFeedback": "Copied to clipboard"
},
"identification": {
"title": {
"validation": "Authorise the operation.",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@pagopa/io-react-native-wallet": "^0.27.0",
"@pagopa/react-native-nodelibs": "^0.1.0",
"@react-native-async-storage/async-storage": "^2.0.0",
"@react-native-clipboard/clipboard": "^1.15.0",
"@react-navigation/bottom-tabs": "^7.0.5",
"@react-navigation/native": "^7.0.3",
"@react-navigation/native-stack": "^7.0.4",
Expand Down
35 changes: 35 additions & 0 deletions ts/components/AppVersion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as React from 'react';
import {GestureResponderEvent, StyleSheet, View} from 'react-native';
import {BodySmall, IOStyles, WithTestID} from '@pagopa/io-app-design-system';
import {useTranslation} from 'react-i18next';
import {getAppVersion} from '../utils/device';

export type AppVersion = WithTestID<{
onPress: (event: GestureResponderEvent) => void;
}>;

const styles = StyleSheet.create({
versionButton: {
paddingVertical: 20,
alignSelf: 'flex-start'
}
});

/**
* This component renders a text with the current app version, to be shown in the settings screen.
*/
const AppVersion = () => {
const appVersion = getAppVersion();
const {t} = useTranslation('global');
const appVersionText = `${t('settings.version')} ${appVersion}`;

return (
<View style={[styles.versionButton, IOStyles.row, IOStyles.alignCenter]}>
<BodySmall numberOfLines={1} weight="Semibold" color="grey-650">
{appVersionText}
</BodySmall>
</View>
);
};

export default AppVersion;
68 changes: 68 additions & 0 deletions ts/components/debug/DebugDataIndicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
HStack,
IOColors,
IOText,
Icon,
hexToRgba
} from '@pagopa/io-app-design-system';
import _ from 'lodash';
import * as React from 'react';
import {Pressable, StyleSheet} from 'react-native';
import {selectDebugData} from '../../store/reducers/debug';
import {useAppSelector} from '../../store';

type DebugDataIndicatorProps = {
onPress: () => void;
};

/**
* This component renders an icon with a ladybug which opens the debug info overlay when pressed.
* Used in {@link DebugInfoOverlay}
*/
export const DebugDataIndicator = (props: DebugDataIndicatorProps) => {
const data = useAppSelector(selectDebugData);
const dataSize = _.size(data);

if (dataSize === 0) {
return null;
}

return (
<Pressable
style={styles.wrapper}
accessibilityRole="button"
onPress={props.onPress}>
<HStack space={4} style={{alignItems: 'center'}}>
<Icon name="ladybug" size={16} color="warning-850" />
<IOText
size={14}
font={'TitilliumSansPro'}
weight={'Semibold'}
color="warning-850"
style={{
letterSpacing: 0.2,
textTransform: 'uppercase'
}}>
{dataSize}
</IOText>
</HStack>
</Pressable>
);
};

const debugItemBgColor = hexToRgba(IOColors['warning-500'], 0.4);
const debugItemBorderColor = hexToRgba(IOColors['warning-850'], 0.1);

const styles = StyleSheet.create({
wrapper: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
borderColor: debugItemBorderColor,
borderWidth: 1,
paddingHorizontal: 6,
borderRadius: 8,
backgroundColor: debugItemBgColor
}
});
72 changes: 72 additions & 0 deletions ts/components/debug/DebugDataOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from 'react';
import {
ScrollView,
StyleSheet,
TouchableWithoutFeedback,
View
} from 'react-native';
import {SafeAreaView} from 'react-native-safe-area-context';
import {useAppSelector} from '../../store';
import {selectDebugData} from '../../store/reducers/debug';
import {DebugPrettyPrint} from './DebugPrettyPrint';

type DebugDataOverlayProps = {
onDismissed?: () => void;
};

/**
* Debug overlay to show all the debug data in a list for each entry in the debug state via {@link DebugPrettyPrint}.
* Used in {@link DebugInfoOverlay}
*/
export const DebugDataOverlay = ({onDismissed}: DebugDataOverlayProps) => {
const debugData = useAppSelector(selectDebugData);

return (
<SafeAreaView style={styles.container}>
<TouchableWithoutFeedback onPress={onDismissed} accessibilityRole="none">
<View style={styles.overlay} />
</TouchableWithoutFeedback>
<ScrollView
style={styles.scroll}
contentContainerStyle={styles.scrollContainer}>
{Object.entries(debugData).map(([key, value]) => (
<DebugPrettyPrint
key={`debug_data_${key}`}
title={key}
data={value}
expandable={true}
isExpanded={false}
/>
))}
</ScrollView>
</SafeAreaView>
);
};

const overlayColor = '#000000B0';

const styles = StyleSheet.create({
container: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
zIndex: 999,
paddingTop: 60
},
overlay: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
backgroundColor: overlayColor
},
scroll: {
flexGrow: 0
},
scrollContainer: {
paddingHorizontal: 16
}
});
75 changes: 75 additions & 0 deletions ts/components/debug/DebugInfoOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {
IOColors,
IOText,
VStack,
hexToRgba,
useIOTheme
} from '@pagopa/io-app-design-system';
import * as React from 'react';
import {useState} from 'react';
import {Platform, SafeAreaView, StyleSheet, View} from 'react-native';
import {getAppVersion} from '../../utils/device';
import {DebugDataIndicator} from './DebugDataIndicator';
import {DebugDataOverlay} from './DebugDataOverlay';

const debugItemBgColor = hexToRgba(IOColors.white, 0.4);
const debugItemBorderColor = hexToRgba(IOColors.black, 0.1);

/**
* Overlay which shows the debug data stored in the debug state.
*/
const DebugInfoOverlay = () => {
const theme = useIOTheme();
const appVersion = getAppVersion();
const [isDebugDataVisibile, showDebugData] = useState(false);

const appVersionText = `DEBUG ENABLED: v${appVersion}`;

return (
<>
<SafeAreaView style={styles.versionContainer} pointerEvents="box-none">
<VStack space={4} style={{alignItems: 'center'}}>
<View style={styles.versionTextWrapper}>
<IOText
color={theme['textBody-secondary']}
font="TitilliumSansPro"
weight="Semibold"
size={12}
lineHeight={16}>
{appVersionText}
</IOText>
</View>
<DebugDataIndicator
onPress={() => showDebugData(prevState => !prevState)}
/>
</VStack>
</SafeAreaView>
{isDebugDataVisibile && (
<DebugDataOverlay onDismissed={() => showDebugData(false)} />
)}
</>
);
};

const styles = StyleSheet.create({
versionContainer: {
...StyleSheet.absoluteFillObject,
top: Platform.OS === 'android' ? 0 : -8,
justifyContent: 'flex-start',
alignItems: 'center',
zIndex: 1000
},
versionTextWrapper: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
borderColor: debugItemBorderColor,
borderWidth: 1,
paddingHorizontal: 4,
borderRadius: 8,
backgroundColor: debugItemBgColor
}
});

export default DebugInfoOverlay;
Loading
Loading