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

[LIVE-16529] Fix Add Custom Manifest Screen #8996

Merged
merged 12 commits into from
Jan 30, 2025
Merged
5 changes: 5 additions & 0 deletions .changeset/orange-drinks-explode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": minor
---

Fixes Add Custom Manifest screen
4 changes: 2 additions & 2 deletions apps/ledger-live-mobile/src/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -3122,7 +3122,7 @@
"title": "Developer",
"desc": "Try out the Developer features and let us know what you think.",
"customManifest": {
"title": "Load Custom Platform Manifest"
"title": "Load Manifest"
},
"exchangeDeveloperMode": {
"title": "Exchange Dev Mode",
Expand Down Expand Up @@ -7225,4 +7225,4 @@
"detectedAccounts_plural": "{{count}} accounts (detected)"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import React, { useState, useCallback, useLayoutEffect } from "react";
import { TextInput, StyleSheet, TouchableOpacity, TouchableOpacityProps } from "react-native";
import {
TextInput,
StyleSheet,
TouchableOpacity,
TouchableOpacityProps,
Alert,
} from "react-native";
import { useTheme, CompositeScreenProps } from "@react-navigation/native";
import { useLocalLiveAppContext } from "@ledgerhq/live-common/wallet-api/LocalLiveAppProvider/index";
import { Box, Text } from "@ledgerhq/native-ui";
import NavigationScrollView from "~/components/NavigationScrollView";
import { Box, Icons, Text } from "@ledgerhq/native-ui";
import { ScreenName } from "~/const";
import KeyboardView from "~/components/KeyboardView";
import ImportIcon from "~/icons/Import";
import type { SettingsNavigatorStackParamList } from "~/components/RootNavigator/types/SettingsNavigator";
import type { BaseNavigatorStackParamList } from "~/components/RootNavigator/types/BaseNavigator";
import type { StackNavigatorProps } from "~/components/RootNavigator/types/helpers";
import AppCard from "~/screens/Platform/Catalog/AppCard";
import Plus from "~/icons/Plus";
import Trash from "~/icons/Trash";
import { DEFAULT_MANIFEST } from "./manifests/metamask";
import { LAGADO_MANIFEST, LAGADO_MANIFEST_BUST, LAGADO_MANIFEST_NOCACHE } from "./manifests/lagado";
import {
ONEINCH_MANIFEST,
Expand All @@ -26,14 +29,16 @@ import {
HEADERS_MANIFEST_BUST,
HEADERS_MANIFEST_NOCACHE,
} from "./manifests/headerSniffer";
import { ScrollView } from "react-native-gesture-handler";
import Clipboard from "@react-native-clipboard/clipboard";

const DebuggerButton: React.ComponentType<{
onPress: TouchableOpacityProps["onPress"];
text?: string;
}> = ({ onPress, text }) => {
const { colors } = useTheme();
return (
<>
<Box flexDirection="row">
{text && (
<Text flex={1} ml={4} variant="body" fontWeight="semiBold">
{text}
Expand All @@ -42,7 +47,7 @@ const DebuggerButton: React.ComponentType<{
<TouchableOpacity style={styles.buttons} onPress={onPress}>
<ImportIcon size={18} color={colors.grey} />
</TouchableOpacity>
</>
</Box>
);
};

Expand All @@ -53,7 +58,30 @@ const AddButton: React.ComponentType<{
const { colors } = useTheme();
return (
<TouchableOpacity style={styles.buttons} onPress={onPress} disabled={disabled}>
<Plus size={18} color={disabled ? colors.grey : colors.black} />
<Icons.Plus size="S" color={disabled ? colors.grey : colors.black} />
</TouchableOpacity>
);
};

const DeleteTextButton: React.ComponentType<{
onPress: TouchableOpacityProps["onPress"];
disabled: boolean;
}> = ({ onPress, disabled }) => {
const { colors } = useTheme();
return (
<TouchableOpacity style={styles.buttons} onPress={onPress} disabled={disabled}>
<Icons.Close size="S" color={disabled ? colors.grey : colors.black} />
</TouchableOpacity>
);
};

const PasteButton: React.ComponentType<{
onPress: TouchableOpacityProps["onPress"];
}> = ({ onPress }) => {
const { colors } = useTheme();
return (
<TouchableOpacity style={styles.buttons} onPress={onPress}>
<Icons.Paste size="S" color={colors.grey} />
</TouchableOpacity>
);
};
Expand Down Expand Up @@ -92,46 +120,62 @@ export default function CustomManifest({ navigation }: Props) {
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<Box flexDirection="row">
<DebuggerButton onPress={() => onChange(JSON.stringify(JSON.parse(DEFAULT_MANIFEST)))} />
<AddButton
<Box flexDirection="row" alignItems="center">
<PasteButton
onPress={async () => {
const text = await Clipboard.getString();

setManifest(text);
}}
/>
<DeleteTextButton
disabled={manifest === null}
onPress={() => {
manifest !== null && addLocalManifest(JSON.parse(manifest));
setManifest(null);
}}
/>
<AddButton
disabled={manifest === null}
onPress={() => {
try {
manifest !== null && addLocalManifest(JSON.parse(manifest));
setManifest(null);
} catch (e) {
Alert.alert("Invalid JSON");
}
}}
/>
</Box>
),
});
}, [addLocalManifest, manifest, navigation, onChange, onOpen, removeLocalManifestById]);

return (
<KeyboardView>
<NavigationScrollView>
<ScrollView>
<TextInput
style={[
styles.input,
{
borderColor: colors.border,
color: colors.text,
},
]}
value={manifest === null ? "" : manifest}
onChangeText={onChange}
placeholder="Paste your manifest json"
placeholderTextColor={"#a3a7ad"}
multiline
autoCorrect={false}
scrollEnabled={false}
/>
<>
<AddButton
disabled={manifest === null}
onPress={() => {
manifest !== null && addLocalManifest(JSON.parse(manifest));
setManifest(null);
}}
/>
<Box flexDirection="row" marginTop={20}>
<Text flex={1} ml={4} mb={4} variant="h3" fontWeight="semiBold" color={colors.fog}>
{"Example Manifests"}
</Text>
</>
<>
<Box mt={5}>
<DebuggerButton
onPress={() => onChange(JSON.stringify(JSON.parse(LAGADO_MANIFEST)))}
text="Lagado"
Expand All @@ -140,16 +184,19 @@ export default function CustomManifest({ navigation }: Props) {
onPress={() => onChange(JSON.stringify(JSON.parse(LAGADO_MANIFEST_BUST)))}
text="Lagado cachebust"
/>
</Box>
<Box>
<DebuggerButton
onPress={() => onChange(JSON.stringify(JSON.parse(LAGADO_MANIFEST_NOCACHE)))}
text="Lagado nocache"
/>
</Box>
<Box flexDirection="row">

<DebuggerButton
onPress={() => onChange(JSON.stringify(JSON.parse(ONEINCH_MANIFEST)))}
text="1inch"
/>
</Box>
<Box>
<DebuggerButton
onPress={() => onChange(JSON.stringify(JSON.parse(ONEINCH_MANIFEST_V3)))}
text="1inch v3"
Expand All @@ -158,16 +205,19 @@ export default function CustomManifest({ navigation }: Props) {
onPress={() => onChange(JSON.stringify(JSON.parse(ONEINCH_MANIFEST_BUST)))}
text="1inch cachebust"
/>
</Box>
<Box>
<DebuggerButton
onPress={() => onChange(JSON.stringify(JSON.parse(ONEINCH_MANIFEST_NOCACHE)))}
text="1inch nocache"
/>
</Box>
<Box flexDirection="row">

<DebuggerButton
onPress={() => onChange(JSON.stringify(JSON.parse(HEADERS_MANIFEST)))}
text="Headers Sniffer"
/>
</Box>
<Box>
<DebuggerButton
onPress={() => onChange(JSON.stringify(JSON.parse(HEADERS_MANIFEST_BUST)))}
text="Headers Sniffer cachebust"
Expand All @@ -180,6 +230,11 @@ export default function CustomManifest({ navigation }: Props) {
</>

<>
{list.length > 0 && (
<Text flex={1} ml={4} mb={4} variant="h3" fontWeight="semiBold" color={colors.fog}>
{"Loaded Manifests"}
</Text>
)}
{list.map(m => {
return (
<Box key={m.id} flexDirection="row">
Expand Down Expand Up @@ -208,7 +263,7 @@ export default function CustomManifest({ navigation }: Props) {
);
})}
</>
</NavigationScrollView>
</ScrollView>
</KeyboardView>
);
}
Expand All @@ -231,9 +286,12 @@ const styles = StyleSheet.create({
flex: 1,
borderWidth: 1,
marginBottom: 16,
height: 60,
marginHorizontal: 10,
padding: 5,
},
buttons: {
paddingVertical: 8,
paddingHorizontal: 8,
paddingVertical: 12,
paddingHorizontal: 12,
},
});

This file was deleted.

Loading