Skip to content

Commit 9a904d9

Browse files
authored
Merge branch 'main' into TSA-114-traders-list-leaderboard
2 parents 82d18a2 + f6cdd71 commit 9a904d9

37 files changed

Lines changed: 1302 additions & 149 deletions

.github/workflows/build-and-upload-to-testflight.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ name: Build and upload to TestFlight
44
# Summary metadata is passed from build.yml outputs (no second checkout for version parsing).
55
#
66
on:
7+
workflow_call:
8+
inputs:
9+
source_branch:
10+
description: 'Branch, tag, or SHA to build'
11+
required: true
12+
type: string
13+
environment:
14+
description: 'Build environment / track (exp, beta, rc)'
15+
required: true
16+
type: string
17+
testflight_group:
18+
description: 'TestFlight external testing group'
19+
required: false
20+
type: string
21+
default: 'MetaMask BETA & Release Candidates'
722
workflow_dispatch:
823
inputs:
924
source_branch:

.github/workflows/build.yml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,10 @@ jobs:
333333
- name: Set Android environment variables
334334
if: matrix.platform == 'android'
335335
run: |
336-
echo "ANDROID_HOME=/opt/android-sdk" >> "$GITHUB_ENV"
337-
echo "ANDROID_SDK_ROOT=/opt/android-sdk" >> "$GITHUB_ENV"
336+
{
337+
echo "ANDROID_HOME=/opt/android-sdk"
338+
echo "ANDROID_SDK_ROOT=/opt/android-sdk"
339+
} >> "$GITHUB_ENV"
338340
339341
- name: Setup Java
340342
if: matrix.platform == 'android'
@@ -497,9 +499,10 @@ jobs:
497499
id: meta
498500
run: |
499501
REF="${{ needs.prepare.outputs.checkout_ref_for_setup }}"
500-
echo "checkout_ref=$REF" >> "$GITHUB_OUTPUT"
501-
echo "built_commit_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
502-
echo "semantic_version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
503-
# versionCode 4138 (no '=' in this repo)
504502
VC=$(awk '/versionCode[[:space:]]/{print $2; exit}' android/app/build.gradle | tr -d '\r')
505-
echo "android_version_code=$VC" >> "$GITHUB_OUTPUT"
503+
{
504+
echo "checkout_ref=$REF"
505+
echo "built_commit_sha=$(git rev-parse HEAD)"
506+
echo "semantic_version=$(node -p "require('./package.json').version")"
507+
echo "android_version_code=$VC"
508+
} >> "$GITHUB_OUTPUT"

.yarnrc.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ plugins:
1212

1313
npmAuditIgnoreAdvisories:
1414
- 1109627 # TODO: Upgrade @react-native-community/cli to 17.0.1+ when ready. Suppressing for now to unblock CI.
15-
- 1112455 # lodash prototype pollution in _.unset and _.omit. No fix available yet (latest is 4.17.21, affected <=4.17.22). Suppressing for now to unblock CI. https://github.com/advisories/GHSA-xxjr-mmjv-4gpg
1615
- 1113402 # bn.js affected by an infinite loop. No fix available yet (latest is 5.2.1, affected <=5.2.3). Suppressing for now to unblock CI. https://github.com/advisories/GHSA-378v-28hj-76wf
1716
- 1113441 # bn.js affected by an infinite loop. No fix available yet (latest is 5.2.1, affected <=5.2.3). Suppressing for now to unblock CI. https://github.com/advisories/GHSA-378v-28hj-76wf
1817
- 1113442 # bn.js affected by an infinite loop. No fix available yet (latest is 5.2.1, affected <=5.2.3). Suppressing for now to unblock CI. https://github.com/advisories/GHSA-378v-28hj-76wf

app/component-library/components/BottomSheets/BottomSheet/BottomSheet.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const BottomSheet = forwardRef<BottomSheetRef, BottomSheetProps>(
4848
shouldNavigateBack = true,
4949
isFullscreen = false,
5050
keyboardAvoidingViewEnabled = true,
51+
panGestureHandlerProps,
5152
...props
5253
},
5354
ref,
@@ -163,6 +164,7 @@ const BottomSheet = forwardRef<BottomSheetRef, BottomSheetProps>(
163164
isFullscreen={isFullscreen}
164165
style={style}
165166
keyboardAvoidingViewEnabled={keyboardAvoidingViewEnabled}
167+
panGestureHandlerProps={panGestureHandlerProps}
166168
>
167169
{children}
168170
</BottomSheetDialog>

app/component-library/components/BottomSheets/BottomSheet/foundation/BottomSheetDialog/BottomSheetDialog.test.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ describe('BottomSheetDialog', () => {
5656
<Text>Test Child</Text>
5757
</BottomSheetDialog>,
5858
);
59-
expect(getByText('Test Child')).toBeTruthy();
59+
expect(getByText('Test Child')).toBeOnTheScreen();
6060
});
6161
it('should call onOpen when onOpenDialog ref is called', () => {
6262
const onOpenMock = jest.fn();
@@ -110,4 +110,26 @@ describe('BottomSheetDialog', () => {
110110
expect(onCloseMock).toHaveBeenCalled();
111111
});
112112
// Note: Add Gesture tests when react-native-gesture-handler gets updated
113+
114+
describe('panGestureHandlerProps', () => {
115+
it('passes props to the PanGestureHandler via panGestureHandlerProps', () => {
116+
const { getByTestId } = render(
117+
<BottomSheetDialog
118+
panGestureHandlerProps={{ testID: 'pan-gesture-handler' }}
119+
>
120+
<Text>Test Child</Text>
121+
</BottomSheetDialog>,
122+
);
123+
expect(getByTestId('pan-gesture-handler')).toBeOnTheScreen();
124+
});
125+
126+
it('renders normally when panGestureHandlerProps is undefined', () => {
127+
const { getByText } = render(
128+
<BottomSheetDialog panGestureHandlerProps={undefined}>
129+
<Text>No Handler Props</Text>
130+
</BottomSheetDialog>,
131+
);
132+
expect(getByText('No Handler Props')).toBeOnTheScreen();
133+
});
134+
});
113135
});

app/component-library/components/BottomSheets/BottomSheet/foundation/BottomSheetDialog/BottomSheetDialog.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ const BottomSheetDialog = forwardRef<
6565
keyboardAvoidingViewEnabled = true,
6666
onClose,
6767
onOpen,
68+
panGestureHandlerProps,
6869
style,
6970
...props
7071
},
@@ -245,6 +246,7 @@ const BottomSheetDialog = forwardRef<
245246
<PanGestureHandler
246247
enabled={isInteractable}
247248
onGestureEvent={gestureHandler}
249+
{...panGestureHandlerProps}
248250
>
249251
<Animated.View
250252
onLayout={updateSheetHeight}

app/component-library/components/BottomSheets/BottomSheet/foundation/BottomSheetDialog/BottomSheetDialog.types.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Third party dependencies.
22
import { StyleProp, ViewProps, ViewStyle } from 'react-native';
3+
import { PanGestureHandlerProps } from 'react-native-gesture-handler';
34

45
/**
56
* BottomSheetDialog component props.
@@ -32,6 +33,16 @@ export interface BottomSheetDialogProps extends ViewProps {
3233
* Optional callback that gets triggered when sheet is opened.
3334
*/
3435
onOpen?: (hasPendingAction?: boolean) => void;
36+
/**
37+
* Optional props forwarded directly to the underlying `PanGestureHandler`.
38+
* Provides access to all `PanGestureHandler` configuration (e.g.
39+
* `simultaneousHandlers`, `activeOffsetY`, `failOffsetX`) so consumers are
40+
* not limited to a single prop subset.
41+
*/
42+
panGestureHandlerProps?: Omit<
43+
PanGestureHandlerProps,
44+
'onGestureEvent' | 'enabled'
45+
>;
3546
}
3647

3748
export interface BottomSheetDialogRef {

app/components/UI/Carousel/fetchCarouselSlidesFromContentful.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,13 @@ export async function fetchCarouselSlidesFromContentful(): Promise<{
7575
return { prioritySlides: [], regularSlides: [] };
7676
}
7777

78-
const host = `https://${domain}/spaces/${spaceId}/environments/${environment}/entries`;
79-
8078
// First try through the Contentful Client
8179
try {
8280
const contentfulClient = createClient({
8381
space: spaceId,
8482
accessToken,
8583
environment,
86-
host,
84+
host: domain,
8785
});
8886

8987
const entries = await contentfulClient.getEntries({
@@ -102,7 +100,8 @@ export async function fetchCarouselSlidesFromContentful(): Promise<{
102100

103101
// Otherwise fallback to URL fetch
104102
try {
105-
const url = new URL(`${host}`);
103+
const fallbackHost = `https://${domain}/spaces/${spaceId}/environments/${environment}/entries`;
104+
const url = new URL(fallbackHost);
106105
url.searchParams.set('access_token', accessToken);
107106
url.searchParams.set('content_type', CONTENT_TYPE);
108107
url.searchParams.set('fields.showInMobile', 'true');

app/components/UI/Perps/Views/PerpsMarketDetailsView/PerpsMarketDetailsView.test.tsx

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,12 @@ jest.mock('../../hooks', () => ({
495495
isClosing: false,
496496
})),
497497
usePerpsMarkets: () => mockUsePerpsMarketsImpl(),
498+
usePerpsMarketData: jest.fn(() => ({
499+
marketData: null,
500+
isLoading: false,
501+
error: null,
502+
refetch: jest.fn(),
503+
})),
498504
usePerpsTrading: jest.fn(() => ({
499505
placeOrder: jest.fn(),
500506
cancelOrder: jest.fn(),
@@ -1482,6 +1488,63 @@ describe('PerpsMarketDetailsView', () => {
14821488
});
14831489
});
14841490

1491+
it('passes marketData defaults to order screen when available', async () => {
1492+
const { useSelector } = jest.requireMock('react-redux');
1493+
const { usePerpsMarketData } = jest.requireMock('../../hooks');
1494+
const mockSelectPerpsEligibility = jest.requireMock(
1495+
'../../selectors/perpsController',
1496+
).selectPerpsEligibility;
1497+
useSelector.mockImplementation((selector: unknown) => {
1498+
if (selector === mockSelectPerpsEligibility) {
1499+
return true;
1500+
}
1501+
return undefined;
1502+
});
1503+
1504+
usePerpsMarketData.mockReturnValue({
1505+
marketData: { szDecimals: 4, maxLeverage: 50 },
1506+
isLoading: false,
1507+
error: null,
1508+
refetch: jest.fn(),
1509+
});
1510+
1511+
try {
1512+
const { getByTestId } = renderWithProvider(
1513+
<PerpsConnectionProvider>
1514+
<PerpsMarketDetailsView />
1515+
</PerpsConnectionProvider>,
1516+
{
1517+
state: initialState,
1518+
},
1519+
);
1520+
1521+
const longButton = getByTestId(
1522+
PerpsMarketDetailsViewSelectorsIDs.LONG_BUTTON,
1523+
);
1524+
await act(async () => {
1525+
fireEvent.press(longButton);
1526+
});
1527+
1528+
expect(mockNavigateToOrder).toHaveBeenCalledTimes(1);
1529+
expect(mockNavigateToOrder).toHaveBeenCalledWith(
1530+
expect.objectContaining({
1531+
direction: 'long',
1532+
asset: 'BTC',
1533+
source: 'perp_asset_screen',
1534+
defaultSzDecimals: 4,
1535+
defaultMaxLeverage: 50,
1536+
}),
1537+
);
1538+
} finally {
1539+
usePerpsMarketData.mockReturnValue({
1540+
marketData: null,
1541+
isLoading: false,
1542+
error: null,
1543+
refetch: jest.fn(),
1544+
});
1545+
}
1546+
});
1547+
14851548
it('navigates to short order screen when short button is pressed and user is eligible', async () => {
14861549
const { useSelector } = jest.requireMock('react-redux');
14871550
const mockSelectPerpsEligibility = jest.requireMock(

app/components/UI/Perps/Views/PerpsMarketDetailsView/PerpsMarketDetailsView.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ import {
9696
usePerpsNavigation,
9797
usePositionManagement,
9898
usePerpsTrading,
99+
usePerpsMarketData,
99100
} from '../../hooks';
100101
import { useConfirmNavigation } from '../../../../Views/confirmations/hooks/useConfirmNavigation';
101102
import { useDefaultPayWithTokenWhenNoPerpsBalance } from '../../hooks/useDefaultPayWithTokenWhenNoPerpsBalance';
@@ -638,6 +639,10 @@ const PerpsMarketDetailsView: React.FC<PerpsMarketDetailsViewProps> = () => {
638639
}
639640
};
640641

642+
const { marketData } = usePerpsMarketData({
643+
asset: market?.symbol || '',
644+
});
645+
641646
const handleWatchlistPress = useCallback(() => {
642647
if (!market?.symbol) return;
643648

@@ -715,9 +720,12 @@ const PerpsMarketDetailsView: React.FC<PerpsMarketDetailsViewProps> = () => {
715720
direction,
716721
asset: market.symbol,
717722
source: PERPS_EVENT_VALUE.SOURCE.PERP_ASSET_SCREEN,
723+
defaultSzDecimals: marketData?.szDecimals,
724+
defaultMaxLeverage: marketData?.maxLeverage,
718725
});
719726
},
720727
[
728+
marketData,
721729
isEligible,
722730
existingPosition,
723731
navigation,

0 commit comments

Comments
 (0)