-
Notifications
You must be signed in to change notification settings - Fork 333
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(llm): 🥅 display human readable errors when the send flow fails (#…
…8081) * feat(llm): add a Collapsible component * feat(llm): add a copy button component * feat(llm): add the SendBroadcastError screen * feat(llm): catch the send flow broadcast errors * chore: update change log * fix(llm): linting * chore(llm): import `Icons` from native-ui instead of the individual icons * chore(llm): use the LLM alias for newArch components * fix(llm): only clamp the technical error messages to 3 lines * fix(llm): lower button opacity when pressed * chore(llm): remove unecessary styles * fix(llm): use a press event on the collapsable toggle * fix(llm): show the currency info in the erorr * fix(llm): error typo * fix(llm): tx broadcast error network name * chore(llm): extract urls from `createTransactionBroadcastError` * chore(lld): extract urls from createTransactionBroadcastError
- Loading branch information
Showing
14 changed files
with
353 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"live-mobile": minor | ||
"@ledgerhq/live-common": patch | ||
--- | ||
|
||
Display human readable errors when the send flow fails |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
apps/ledger-live-mobile/src/newArch/components/Collapsible/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import React, { memo, ReactNode, useCallback, useState } from "react"; | ||
import Animated, { | ||
useSharedValue, | ||
useAnimatedStyle, | ||
withTiming, | ||
runOnJS, | ||
} from "react-native-reanimated"; | ||
import styled from "styled-components/native"; | ||
import { Flex, Icons, Text } from "@ledgerhq/native-ui"; | ||
import { FlexBoxProps } from "@ledgerhq/native-ui/lib/components/Layout/Flex/index"; | ||
|
||
export default memo(Collapsible); | ||
|
||
type Props = FlexBoxProps & { | ||
title: ReactNode; | ||
children: ReactNode; | ||
collapsed?: boolean; | ||
}; | ||
|
||
function Collapsible({ title, children, collapsed = false, ...titleContainerProps }: Props) { | ||
const [isCollapsed, setIsCollapsed] = useState(collapsed); | ||
const collapseAnimation = useSharedValue(collapsed ? 0 : 1); | ||
|
||
const toggleCollapsed = useCallback(() => { | ||
const value = Math.round(collapseAnimation.value + 1) % 2; | ||
|
||
const { onStart, onDone }: { onStart?: () => void; onDone: () => void } = | ||
value === 0 | ||
? { onDone: () => setIsCollapsed(true) } | ||
: { onStart: () => setIsCollapsed(false), onDone: () => {} }; | ||
|
||
onStart?.(); | ||
|
||
collapseAnimation.value = withTiming(value, { duration: 200 }, finished => { | ||
if (finished) { | ||
runOnJS(onDone)(); | ||
} | ||
}); | ||
}, [collapseAnimation]); | ||
|
||
const animatedChevron = useAnimatedStyle(() => ({ | ||
transform: [{ rotate: `${collapseAnimation.value * 90}deg` }], | ||
})); | ||
const animateContent = useAnimatedStyle(() => ({ | ||
maxHeight: `${collapseAnimation.value * 100}%`, | ||
})); | ||
|
||
const header = typeof title === "string" ? <Text>{title}</Text> : title; | ||
|
||
return ( | ||
<> | ||
<Flex {...titleContainerProps}> | ||
<Toggle activeOpacity={1} onPress={toggleCollapsed}> | ||
{header} | ||
<Animated.View style={animatedChevron}> | ||
<Icons.ChevronRight /> | ||
</Animated.View> | ||
</Toggle> | ||
</Flex> | ||
|
||
<Animated.View style={[animateContent, { overflow: "hidden" }]}> | ||
{!isCollapsed && children} | ||
</Animated.View> | ||
</> | ||
); | ||
} | ||
|
||
const Toggle = styled.TouchableOpacity` | ||
flex-direction: row; | ||
align-items: center; | ||
`; |
58 changes: 58 additions & 0 deletions
58
apps/ledger-live-mobile/src/newArch/components/CopyButton/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import Clipboard from "@react-native-clipboard/clipboard"; | ||
import React, { memo, useCallback, useMemo } from "react"; | ||
import Animated, { useSharedValue, useAnimatedStyle, withTiming } from "react-native-reanimated"; | ||
import styled from "styled-components/native"; | ||
import { Button, Icons } from "@ledgerhq/native-ui"; | ||
import { ButtonProps } from "@ledgerhq/native-ui/components/cta/Button"; | ||
|
||
export default memo(CopyButton); | ||
|
||
type Props = Omit<ButtonProps, "Icon" | "isNewIcon" | "onPress"> & { | ||
text: string; | ||
transitionDuration?: number; | ||
}; | ||
|
||
function CopyButton({ text, ...props }: Props) { | ||
const transition = useSharedValue(0); | ||
const handleCopy = useCallback(() => { | ||
Clipboard.setString(text); | ||
|
||
transition.value = withTiming(1, { duration: 200 }); | ||
setTimeout(() => (transition.value = withTiming(0, { duration: 200 })), 1200); | ||
}, [text, transition]); | ||
|
||
const copyIconAnimation = useAnimatedStyle(() => ({ | ||
opacity: 1 - transition.value, | ||
})); | ||
|
||
const checkIconAnimation = useAnimatedStyle(() => ({ | ||
opacity: transition.value, | ||
})); | ||
|
||
const icon = useMemo( | ||
() => ( | ||
<IconContainer> | ||
<Animated.View style={copyIconAnimation}> | ||
<Icons.Copy /> | ||
</Animated.View> | ||
<Animated.View style={[checkIconAnimation, checkIconStyle]}> | ||
<Icons.Check /> | ||
</Animated.View> | ||
</IconContainer> | ||
), | ||
[copyIconAnimation, checkIconAnimation], | ||
); | ||
|
||
return <Button {...props} Icon={icon} isNewIcon onPress={handleCopy} />; | ||
} | ||
|
||
const IconContainer = styled.View` | ||
position: relative; | ||
`; | ||
const checkIconStyle = { | ||
position: "absolute", | ||
top: 0, | ||
bottom: 0, | ||
left: 0, | ||
right: 0, | ||
} as const; |
Oops, something went wrong.