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

Wallet Switcher v2 #6318

Merged
merged 58 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
778117b
new wallet switcher UI
maxbbb Dec 10, 2024
74b4019
dnd flatlist autoscrolling
maxbbb Dec 10, 2024
71d6b46
fix layout/spacing issues
maxbbb Dec 11, 2024
e8fc4f8
pinned wallet grid edit mode jiggle animation
maxbbb Dec 11, 2024
2fa3f66
add long press option and optional callback data to dropdown menu com…
maxbbb Dec 12, 2024
089a164
address context menu on long press, refactor context menu to use new …
maxbbb Dec 12, 2024
4b8b989
add drag handler icon
maxbbb Dec 13, 2024
63d9683
selected wallet shadow, watching & hw wallet badge fixes
maxbbb Dec 13, 2024
54e2911
fix address label abbreviation & truncation
maxbbb Dec 13, 2024
2339bd0
fix total owned wallet balance formatting
maxbbb Dec 13, 2024
b85e0c7
fix autoscrolling can scroll logic & add inset behavior
maxbbb Dec 13, 2024
5134fcc
general purpose feature hint tooltip component
maxbbb Dec 14, 2024
a8ede2b
edit wallets hint tooltip
maxbbb Dec 14, 2024
10faef3
fix dnd provider gesture disabled toggle logic
maxbbb Dec 16, 2024
f69dcdf
add DraggableScrollView based on DraggableFlatList
maxbbb Dec 16, 2024
6455f0b
fix gesture problems by switching to draggable scrollview
maxbbb Dec 16, 2024
6cb4663
fixes for DnD children layout changes & draggable scrollview refactor
maxbbb Dec 17, 2024
e1bfada
fix different account emoji in list vs pinned grid
maxbbb Dec 17, 2024
e8d706d
dynamically size pinned account avatars
maxbbb Dec 17, 2024
b384ec7
copy & settings dropdown menu options, fix account emoji size
maxbbb Dec 17, 2024
8ed6aec
localization
maxbbb Dec 17, 2024
120483c
misc. styling fixes for light mode, android, design spec matching
maxbbb Dec 17, 2024
ccbf096
update dropdown menu component to work for checkbox & regular items
maxbbb Dec 18, 2024
8b63d33
tooltip localization
maxbbb Dec 18, 2024
45c4b1a
remove unused wallet item fields
maxbbb Dec 18, 2024
959b774
auto pin addresses
maxbbb Dec 18, 2024
1ec4446
refactor wallet list loading animation transition
maxbbb Dec 18, 2024
d137c40
autoscroll easing & scroll to end logic fix
maxbbb Dec 18, 2024
746b79b
fix remove pinned address logic
maxbbb Dec 18, 2024
b4c1691
integrate auto-pin wallet feature with backend implementation
maxbbb Dec 18, 2024
41925ed
misc. DnD bug fixes, worklet haptic activation, and styling cleanup
maxbbb Dec 18, 2024
50b5e04
fix dnd onUpdate logic, add onUpdateWorklet for haptic trigger on reo…
maxbbb Dec 18, 2024
dd774e2
android button & padding fixes, grid layout jank fix
maxbbb Dec 18, 2024
0b778ef
misc. cleanup
maxbbb Dec 19, 2024
aa75d33
Merge develop into @kane/APP-2081
maxbbb Dec 19, 2024
b116d1a
dnd: refactor offset update logic
maxbbb Dec 19, 2024
1ffd763
delete unused component
maxbbb Dec 19, 2024
2d582fa
move components to screen/components directory
maxbbb Dec 19, 2024
af1e1b6
migrate DraggableFlatList to use useDraggableScroll
maxbbb Dec 19, 2024
ff44d3e
update import, change max panel height
maxbbb Dec 19, 2024
174f57d
fix various shadows
maxbbb Dec 19, 2024
dbf1131
fix shadow opacity, revert dnd offset drift fix for useDraggableScroll
maxbbb Dec 19, 2024
f4017fe
fix tooltip zindex, add shadow
maxbbb Dec 19, 2024
76470ff
improve jiggle animation
maxbbb Dec 19, 2024
b713e71
Merge branch 'develop' into @kane/APP-2081
maxbbb Dec 19, 2024
69ca2b4
minor adjustments
maxbbb Dec 19, 2024
69bc587
hide total balance display if user only has watched wallets
maxbbb Dec 20, 2024
f445acd
fix total balance NaN by fixing addDisplay utility, add new test for …
maxbbb Dec 20, 2024
3e9572e
custom spring config for wallet draggable return to origin
maxbbb Dec 20, 2024
b3a9702
fix navigation param address type error
maxbbb Dec 20, 2024
a3b285b
Merge branch 'develop' into @kane/APP-2081
maxbbb Dec 20, 2024
c534b4a
prevent auto pin from running multiple times, remove total balance text
maxbbb Dec 20, 2024
90bd1e7
Merge remote-tracking branch 'origin/develop' into @kane/APP-2081
maxbbb Jan 3, 2025
e6a8307
add back testID to add wallet button to fix e2e
maxbbb Jan 4, 2025
286b901
remove concept of per item activation delays in dnd, move logic to ge…
maxbbb Jan 6, 2025
9f71e17
make grid wallets & other wallets gesture wait for each other to prev…
maxbbb Jan 6, 2025
3fe3ed8
remove unused code
maxbbb Jan 6, 2025
0bbdd5c
undo changes to dropdown component for data type
maxbbb Jan 6, 2025
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
32 changes: 25 additions & 7 deletions src/components/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ export const DropdownMenuRoot = DropdownMenuPrimitive.Root;
export const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
export const DropdownMenuContent = DropdownMenuPrimitive.Content;
export const DropdownMenuItem = DropdownMenuPrimitive.create(
styled(DropdownMenuPrimitive.Item)({
height: 34,
}),
'Item'
);
export const DropdownMenuCheckboxItem = DropdownMenuPrimitive.create(
styled(DropdownMenuPrimitive.CheckboxItem)({
height: 34,
}),
Expand All @@ -35,6 +41,7 @@ export type MenuItemIcon = Omit<IconConfig, 'iconValue' | 'iconType'> & (MenuIte
export type MenuItem<T> = Omit<MenuActionConfig, 'icon'> & {
actionKey: T;
actionTitle: string;
destructive?: boolean;
icon?: MenuItemIcon | { iconType: string; iconValue: string };
};

Expand All @@ -43,10 +50,12 @@ export type MenuConfig<T extends string> = Omit<_MenuConfig, 'menuItems' | 'menu
menuItems: Array<MenuItem<T>>;
};

type DropDownMenuProps<T extends string> = {
type DropdownMenuProps<T extends string> = {
children: React.ReactElement;
menuConfig: MenuConfig<T>;
onPressMenuItem: (actionKey: T) => void;
triggerAction?: 'press' | 'longPress';
menuItemType?: 'checkbox';
} & DropdownMenuContentProps;

const buildIconConfig = (icon?: MenuItemIcon) => {
Expand Down Expand Up @@ -75,17 +84,21 @@ export function DropdownMenu<T extends string>({
side = 'right',
alignOffset = 5,
avoidCollisions = true,
}: DropDownMenuProps<T>) {
triggerAction = 'press',
menuItemType,
}: DropdownMenuProps<T>) {
const handleSelectItem = useCallback(
(actionKey: T) => {
onPressMenuItem(actionKey);
},
[onPressMenuItem]
);

const MenuItemComponent = menuItemType === 'checkbox' ? DropdownMenuCheckboxItem : DropdownMenuItem;

Comment on lines +97 to +98
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually not sure we ever need to use the bare DropdownMenuItem. Can't we optimistically assume it's a DropdownMenuCheckboxItem and just not show the checkmark by setting value={undefined}? Unsure, but worth trying if it simplifies this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Android an empty checkbox gets automatically added when using the DropdownMenuCheckboxItem. The value prop is required for DropdownMenuCheckboxItem and can't be set to undefined. I could change it to assume undefined value types should use the other component, but I don't think there is a way tot get around needing to conditionally use the DropdownMenuCheckboxItem or DropdownMenuItem

return (
<DropdownMenuRoot>
<DropdownMenuTrigger>{children}</DropdownMenuTrigger>
<DropdownMenuTrigger action={triggerAction}>{children}</DropdownMenuTrigger>
<DropdownMenuContent
loop={loop}
side={side}
Expand All @@ -97,19 +110,24 @@ export function DropdownMenu<T extends string>({
>
{!!menuConfig.menuTitle?.trim() && (
<DropdownMenuPrimitive.Group>
<DropdownMenuItem disabled>
<MenuItemComponent disabled>
<DropdownMenuItemTitle>{menuConfig.menuTitle}</DropdownMenuItemTitle>
</DropdownMenuItem>
</MenuItemComponent>
</DropdownMenuPrimitive.Group>
)}
{menuConfig.menuItems?.map(item => {
const Icon = buildIconConfig(item.icon as MenuItemIcon);

return (
<DropdownMenuItem value={item.menuState ?? 'off'} key={item.actionKey} onSelect={() => handleSelectItem(item.actionKey)}>
<MenuItemComponent
value={item.menuState ?? 'off'}
destructive={item.destructive}
key={item.actionKey}
onSelect={() => handleSelectItem(item.actionKey)}
>
<DropdownMenuItemTitle>{item.actionTitle}</DropdownMenuItemTitle>
{Icon}
</DropdownMenuItem>
</MenuItemComponent>
);
})}
</DropdownMenuContent>
Expand Down
2 changes: 1 addition & 1 deletion src/components/SmoothPager/ListPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const TapToDismiss = memo(function TapToDismiss() {
});

const PANEL_INSET = 8;
const PANEL_WIDTH = DEVICE_WIDTH - PANEL_INSET * 2;
export const PANEL_WIDTH = DEVICE_WIDTH - PANEL_INSET * 2;
const PANEL_BORDER_RADIUS = 42;
const LIST_SCROLL_INDICATOR_BOTTOM_INSET = { bottom: PANEL_BORDER_RADIUS };

Expand Down
67 changes: 67 additions & 0 deletions src/components/animations/JiggleAnimation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useEffect } from 'react';
import Animated, {
useSharedValue,
useAnimatedStyle,
withTiming,
withRepeat,
cancelAnimation,
useAnimatedReaction,
SharedValue,
withSequence,
} from 'react-native-reanimated';

type JiggleAnimationProps = {
amplitude?: number;
duration?: number;
children: React.ReactNode;
enabled: boolean | SharedValue<boolean>;
};

export function JiggleAnimation({ children, amplitude = 2, duration = 125, enabled }: JiggleAnimationProps) {
const rotation = useSharedValue(0);
const internalEnabled = useSharedValue(typeof enabled === 'boolean' ? enabled : false);

// Randomize some initial values to avoid sync with other jiggles
// Randomize duration (5% variance)
const instanceDuration = duration * (1 + (Math.random() - 0.5) * 0.1);

// Randomize initial rotation that's at least 50% of the amplitude
const minInitialRotation = amplitude * 0.5;
const rotationRange = amplitude - minInitialRotation;
const initialRotation = minInitialRotation + Math.random() * rotationRange;

// Randomize initial direction
const initialDirection = Math.random() < 0.5 ? -1 : 1;
const firstRotation = initialRotation * initialDirection;

useEffect(() => {
if (typeof enabled === 'boolean') {
internalEnabled.value = enabled;
}
}, [enabled, internalEnabled]);

useAnimatedReaction(
() => {
return typeof enabled === 'boolean' ? internalEnabled.value : (enabled as SharedValue<boolean>).value;
},
enabled => {
if (enabled) {
rotation.value = withSequence(
withTiming(firstRotation, { duration: instanceDuration / 2 }),
withRepeat(withTiming(-amplitude * initialDirection, { duration: instanceDuration }), -1, true)
);
} else {
cancelAnimation(rotation);
rotation.value = withTiming(0, { duration: instanceDuration / 2 });
}
}
);

const animatedStyle = useAnimatedStyle(() => {
return {
transform: [{ rotate: `${rotation.value}deg` }],
};
});

return <Animated.View style={animatedStyle}>{children}</Animated.View>;
}
1 change: 1 addition & 0 deletions src/components/animations/animationConfigs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const springAnimations = createSpringConfigs({
keyboardConfig: disableForTestingEnvironment({ damping: 500, mass: 3, stiffness: 1000 }),
sliderConfig: disableForTestingEnvironment({ damping: 40, mass: 1.25, stiffness: 450 }),
slowSpring: disableForTestingEnvironment({ damping: 500, mass: 3, stiffness: 800 }),
walletDraggableConfig: disableForTestingEnvironment({ damping: 36, mass: 0.8, stiffness: 800 }),
snappierSpringConfig: disableForTestingEnvironment({ damping: 42, mass: 0.8, stiffness: 800 }),
snappySpringConfig: disableForTestingEnvironment({ damping: 100, mass: 0.8, stiffness: 275 }),
springConfig: disableForTestingEnvironment({ damping: 100, mass: 1.2, stiffness: 750 }),
Expand Down
2 changes: 1 addition & 1 deletion src/components/cards/MintsCard/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function Menu() {
);

return (
<DropdownMenu<MintsFilter> menuConfig={menuConfig} onPressMenuItem={onPressMenuItem}>
<DropdownMenu<MintsFilter> menuItemType="checkbox" menuConfig={menuConfig} onPressMenuItem={onPressMenuItem}>
<ButtonPressAnimation>
<Inset top="2px">
<Inline alignVertical="center" space={{ custom: 5 }}>
Expand Down
Loading
Loading