Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const PerpsMarketListView = ({
route.params?.showWatchlistOnly ?? propShowWatchlistOnly ?? false;
const defaultMarketTypeFilter =
route.params?.defaultMarketTypeFilter ?? 'all';
const defaultSortOptionId = route.params?.defaultSortOptionId;

const fadeAnimation = useRef(new Animated.Value(0)).current;
const [isSortFieldSheetVisible, setIsSortFieldSheetVisible] = useState(false);
Expand All @@ -84,6 +85,7 @@ const PerpsMarketListView = ({
enablePolling: false,
showWatchlistOnly,
defaultMarketTypeFilter,
defaultSortOptionId,
showZeroVolume: __DEV__,
});

Expand Down
62 changes: 62 additions & 0 deletions app/components/UI/Perps/hooks/usePerpsMarketListView.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,68 @@ describe('usePerpsMarketListView', () => {
});
});

it('defaultSortOptionId overrides the saved sort option and resets direction to default', () => {
let selectorCallCount = 0;
mockUseSelector.mockImplementation(() => {
selectorCallCount++;
if (selectorCallCount % 2 === 1) {
return ['BTC'];
}
// Saved preference is volume/asc — user had it sorted ascending
return { optionId: 'volume', direction: 'asc' };
});

renderHook(() =>
usePerpsMarketListView({ defaultSortOptionId: 'priceChange' }),
);

// Option overridden → direction must reset to default (desc), not carry 'asc'
expect(mockUsePerpsSorting).toHaveBeenCalledWith({
initialOptionId: 'priceChange',
initialDirection: 'desc',
});
});

it('preserves saved direction when defaultSortOptionId matches the saved option', () => {
let selectorCallCount = 0;
mockUseSelector.mockImplementation(() => {
selectorCallCount++;
if (selectorCallCount % 2 === 1) {
return ['BTC'];
}
// Saved preference is priceChange/asc
return { optionId: 'priceChange', direction: 'asc' };
});

renderHook(() =>
usePerpsMarketListView({ defaultSortOptionId: 'priceChange' }),
);

// Same option — carry the saved direction, don't reset
expect(mockUsePerpsSorting).toHaveBeenCalledWith({
initialOptionId: 'priceChange',
initialDirection: 'asc',
});
});

it('falls back to saved sort preference when defaultSortOptionId is not provided', () => {
let selectorCallCount = 0;
mockUseSelector.mockImplementation(() => {
selectorCallCount++;
if (selectorCallCount % 2 === 1) {
return ['BTC'];
}
return { optionId: 'fundingRate', direction: 'asc' };
});

renderHook(() => usePerpsMarketListView());

expect(mockUsePerpsSorting).toHaveBeenCalledWith({
initialOptionId: 'fundingRate',
initialDirection: 'asc',
});
});

it('exposes sort state correctly', () => {
const { result } = renderHook(() => usePerpsMarketListView());

Expand Down
23 changes: 20 additions & 3 deletions app/components/UI/Perps/hooks/usePerpsMarketListView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { usePerpsMarkets } from './usePerpsMarkets';
import { usePerpsSearch } from './usePerpsSearch';
import { usePerpsSorting } from './usePerpsSorting';
import {
MARKET_SORTING_CONFIG,
sortMarkets,
type PerpsMarketData,
type MarketTypeFilter,
Expand Down Expand Up @@ -33,6 +34,11 @@ interface UsePerpsMarketListViewParams {
* @default 'all'
*/
defaultMarketTypeFilter?: MarketTypeFilter;
/**
* Initial sort option ID — overrides the persisted user preference when provided.
* @default undefined (falls back to saved user preference)
*/
defaultSortOptionId?: SortOptionId;
/**
* Show markets with $0.00 volume
* @default false
Expand Down Expand Up @@ -133,6 +139,7 @@ export const usePerpsMarketListView = ({
enablePolling = false,
showWatchlistOnly = false,
defaultMarketTypeFilter = 'all',
defaultSortOptionId,
showZeroVolume = false,
}: UsePerpsMarketListViewParams = {}): UsePerpsMarketListViewReturn => {
// Fetch markets data
Expand Down Expand Up @@ -196,10 +203,20 @@ export const usePerpsMarketListView = ({
return searchedMarkets;
}, [searchedMarkets, marketTypeFilter]);

// Use sorting hook for sort state and sorting logic
// Use sorting hook for sort state and sorting logic.
// defaultSortOptionId (from navigation params) takes precedence over the saved user
// preference. When it overrides a *different* option, reset direction to the default
// so the market list opens sorted the same way the explore feed displayed it (always desc).
// When there is no override, or the override matches the saved option, carry the saved direction.
const isOptionOverridden =
defaultSortOptionId !== undefined &&
defaultSortOptionId !== savedSortPreference.optionId;
const sortingHook = usePerpsSorting({
initialOptionId: savedSortPreference.optionId as SortOptionId,
initialDirection: savedSortPreference.direction,
initialOptionId: (defaultSortOptionId ??
savedSortPreference.optionId) as SortOptionId,
Comment thread
cursor[bot] marked this conversation as resolved.
initialDirection: isOptionOverridden
? MARKET_SORTING_CONFIG.DefaultDirection
: savedSortPreference.direction,
});

// Wrap handleOptionChange to save preference to PerpsController
Expand Down
2 changes: 2 additions & 0 deletions app/components/UI/Perps/types/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
type OrderType,
type PerpsMarketData,
type TPSLTrackingData,
type SortOptionId,
} from '@metamask/perps-controller';
import { PerpsTransaction } from './transactionHistory';
import type { DataMonitorParams } from '../hooks/usePerpsDataMonitor';
Expand Down Expand Up @@ -90,6 +91,7 @@ export interface PerpsNavigationParamList extends ParamListBase {
| 'commodities'
| 'forex'
| 'new';
defaultSortOptionId?: SortOptionId;
fromHome?: boolean;
button_clicked?: string;
button_location?: string;
Expand Down
Loading
Loading