Skip to content

Commit 229a143

Browse files
committed
fixes for bluetooth connect flows
1 parent 5e826af commit 229a143

File tree

14 files changed

+1497
-745
lines changed

14 files changed

+1497
-745
lines changed

packages/core-mobile/app/assets/lotties/connect-waves.json

Lines changed: 1192 additions & 1 deletion
Large diffs are not rendered by default.

packages/core-mobile/app/new/features/ledger/components/AnimatedIconWithText.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { View } from 'react-native'
33
import LottieView from 'lottie-react-native'
44
import { Text, useTheme } from '@avalabs/k2-alpine'
55

6+
// Import animation at the top level
7+
const connectWavesAnimation = require('assets/lotties/connect-waves.json')
8+
69
interface AnimatedIconWithTextProps {
710
/** The icon component to display */
811
icon: React.ReactNode
@@ -18,15 +21,18 @@ interface AnimatedIconWithTextProps {
1821
animationSize?: { width: number; height: number }
1922
/** Custom icon positioning offset for animation centering */
2023
animationOffset?: { top: number; left: number }
24+
/** Custom color for the animation (defaults to theme textPrimary) */
25+
animationColor?: string
2126
}
2227

2328
export const AnimatedIconWithText: React.FC<AnimatedIconWithTextProps> = ({
2429
icon,
2530
title,
2631
subtitle,
2732
showAnimation = false,
28-
animationSource = require('assets/lotties/connect-waves.json'),
29-
animationSize = { width: 220, height: 220 }
33+
animationSource = connectWavesAnimation,
34+
animationSize = { width: 220, height: 220 },
35+
animationColor
3036
}) => {
3137
const {
3238
theme: { colors }
@@ -66,6 +72,13 @@ export const AnimatedIconWithText: React.FC<AnimatedIconWithTextProps> = ({
6672
source={animationSource}
6773
autoPlay
6874
loop
75+
resizeMode="contain"
76+
colorFilters={[
77+
{
78+
keypath: '*', // Apply to all layers
79+
color: animationColor || colors.$textPrimary // Use custom color or theme default
80+
}
81+
]}
6982
style={{
7083
position: 'absolute',
7184
width: animationSize.width,

packages/core-mobile/app/new/features/ledger/components/DerivationPathSelector.tsx

Lines changed: 180 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,186 @@ interface DerivationPathOption {
1717

1818
interface DerivationPathSelectorProps {
1919
onSelect: (derivationPathType: LedgerDerivationPathType) => void
20+
onCancel?: () => void
21+
}
22+
23+
interface ListItemProps {
24+
text: string
25+
type: 'benefit' | 'consideration'
26+
isFirst?: boolean
27+
}
28+
29+
const ListItem: React.FC<ListItemProps> = ({ text, type, isFirst = false }) => {
30+
const {
31+
theme: { colors }
32+
} = useTheme()
33+
34+
const iconProps =
35+
type === 'benefit'
36+
? {
37+
Icon: Icons.Custom.CheckSmall,
38+
color: colors.$textSuccess
39+
}
40+
: {
41+
Icon: Icons.Custom.RedExclamation,
42+
color: colors.$textDanger,
43+
width: 16,
44+
height: 12
45+
}
46+
47+
return (
48+
<View
49+
style={{
50+
flexDirection: 'row',
51+
alignItems: 'center',
52+
marginTop: isFirst ? 4 : 0
53+
}}>
54+
<iconProps.Icon
55+
color={iconProps.color}
56+
{...(iconProps.width && {
57+
width: iconProps.width,
58+
height: iconProps.height
59+
})}
60+
/>
61+
<Text
62+
variant="subtitle2"
63+
style={{
64+
color: colors.$textPrimary,
65+
lineHeight: 18,
66+
marginLeft: type === 'consideration' ? 4 : 0
67+
}}>
68+
{text}
69+
</Text>
70+
</View>
71+
)
72+
}
73+
74+
interface OptionCardProps {
75+
option: DerivationPathOption
76+
onPress?: () => void
77+
}
78+
79+
const OptionCard: React.FC<OptionCardProps> = ({ option, onPress }) => {
80+
const {
81+
theme: { colors }
82+
} = useTheme()
83+
84+
return (
85+
<TouchableOpacity
86+
onPress={onPress}
87+
style={{
88+
width: '100%',
89+
borderRadius: 12,
90+
overflow: 'hidden',
91+
backgroundColor: colors.$surfaceSecondary
92+
}}>
93+
<View
94+
style={{
95+
padding: 16,
96+
paddingBottom: 12,
97+
display: 'flex',
98+
flexDirection: 'row',
99+
alignItems: 'center',
100+
justifyContent: 'space-between'
101+
}}>
102+
<View
103+
style={{
104+
display: 'flex',
105+
flexDirection: 'row',
106+
alignItems: 'center',
107+
gap: 16
108+
}}>
109+
<Icons.Custom.Ledger
110+
color={colors.$textPrimary}
111+
width={24}
112+
height={24}
113+
/>
114+
<View
115+
style={{
116+
display: 'flex',
117+
flexDirection: 'column',
118+
gap: 4
119+
}}>
120+
<Text
121+
variant="subtitle1"
122+
style={{
123+
color: colors.$textPrimary,
124+
fontWeight: '500',
125+
fontSize: 16,
126+
lineHeight: 16
127+
}}>
128+
{option.title}
129+
</Text>
130+
<Text
131+
variant="caption"
132+
style={{
133+
color: colors.$textSecondary,
134+
fontSize: 12,
135+
lineHeight: 15
136+
}}>
137+
{option.subtitle}
138+
</Text>
139+
</View>
140+
</View>
141+
{onPress && (
142+
<Icons.Navigation.ChevronRight color={colors.$textSecondary} />
143+
)}
144+
</View>
145+
146+
{/* Divider that spans from text start to card end */}
147+
<View
148+
style={{
149+
height: 1,
150+
backgroundColor: colors.$borderPrimary,
151+
width: '85%',
152+
alignSelf: 'flex-end'
153+
}}
154+
/>
155+
156+
<View style={{ paddingTop: 12, paddingStart: '15%' }}>
157+
<Text
158+
variant="caption"
159+
style={{
160+
color: colors.$textSecondary,
161+
fontSize: 12,
162+
lineHeight: 15
163+
}}>
164+
Benefits
165+
</Text>
166+
{option.benefits.map((benefit, index) => (
167+
<ListItem
168+
key={index}
169+
text={benefit}
170+
type="benefit"
171+
isFirst={index === 0}
172+
/>
173+
))}
174+
</View>
175+
176+
{option.warnings.length > 0 && (
177+
<View
178+
style={{ paddingTop: 12, paddingStart: '15%', paddingBottom: 12 }}>
179+
<Text
180+
variant="caption"
181+
style={{
182+
color: colors.$textSecondary,
183+
fontSize: 12,
184+
lineHeight: 15
185+
}}>
186+
Considerations
187+
</Text>
188+
{option.warnings.map((warning, index) => (
189+
<ListItem
190+
key={index}
191+
text={warning}
192+
type="consideration"
193+
isFirst={index === 0}
194+
/>
195+
))}
196+
</View>
197+
)}
198+
</TouchableOpacity>
199+
)
20200
}
21201

22202
const derivationPathOptions: DerivationPathOption[] = [
@@ -54,77 +234,6 @@ const derivationPathOptions: DerivationPathOption[] = [
54234
export const DerivationPathSelector: React.FC<DerivationPathSelectorProps> = ({
55235
onSelect
56236
}) => {
57-
const {
58-
theme: { colors }
59-
} = useTheme()
60-
const [selectedType, setSelectedType] =
61-
useState<LedgerDerivationPathType | null>(null)
62-
63-
const selectedOption = derivationPathOptions.find(
64-
option => option.type === selectedType
65-
)
66-
67-
const renderFooter = useCallback(() => {
68-
return (
69-
<View style={{ padding: 16, gap: 12 }}>
70-
<Button
71-
type="primary"
72-
size="large"
73-
disabled={!selectedType}
74-
onPress={() => selectedType && onSelect(selectedType)}>
75-
Continue
76-
</Button>
77-
</View>
78-
)
79-
}, [selectedType, onSelect])
80-
81-
const groupListData = derivationPathOptions.map(option => ({
82-
title: option.title,
83-
subtitle: (
84-
<Text variant="caption" sx={{ fontSize: 12, paddingTop: 4 }}>
85-
{option.subtitle}
86-
</Text>
87-
),
88-
leftIcon: (
89-
<View
90-
style={{
91-
width: 40,
92-
height: 40,
93-
borderRadius: 20,
94-
backgroundColor: option.recommended
95-
? colors.$textSuccess
96-
: colors.$surfaceSecondary,
97-
alignItems: 'center',
98-
justifyContent: 'center'
99-
}}>
100-
<Icons.Device.Encrypted
101-
color={option.recommended ? colors.$white : colors.$textPrimary}
102-
width={20}
103-
height={20}
104-
/>
105-
</View>
106-
),
107-
accessory:
108-
selectedType === option.type ? (
109-
<Icons.Action.CheckCircle
110-
color={colors.$textSuccess}
111-
width={24}
112-
height={24}
113-
/>
114-
) : (
115-
<View
116-
style={{
117-
width: 24,
118-
height: 24,
119-
borderRadius: 12,
120-
borderWidth: 2,
121-
borderColor: colors.$borderPrimary
122-
}}
123-
/>
124-
),
125-
onPress: () => setSelectedType(option.type)
126-
}))
127-
128237
return (
129238
<ScrollScreen
130239
title="First, choose your setup Method"

0 commit comments

Comments
 (0)