From ac06f7a50f0642fb1decd4dac8fcd4efa2584a62 Mon Sep 17 00:00:00 2001 From: Martin Cayuelas Date: Thu, 18 Jul 2024 16:30:41 +0200 Subject: [PATCH 1/3] [FEAT] : Improve Market for Backend --- .changeset/cyan-melons-fetch.md | 5 ++++ .changeset/polite-bananas-relax.md | 5 ++++ .changeset/rare-windows-rhyme.md | 5 ++++ .../src/renderer/reducers/market.ts | 2 +- .../components/SearchInputComponent.tsx | 23 ++++++++++++++++--- .../components/SearchHeader/index.tsx | 2 +- .../ledger-live-mobile/src/reducers/market.ts | 2 +- .../src/market/api/index.ts | 2 +- .../src/market/hooks/useMarketDataProvider.ts | 2 +- 9 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 .changeset/cyan-melons-fetch.md create mode 100644 .changeset/polite-bananas-relax.md create mode 100644 .changeset/rare-windows-rhyme.md diff --git a/.changeset/cyan-melons-fetch.md b/.changeset/cyan-melons-fetch.md new file mode 100644 index 000000000000..ed0d7bae3def --- /dev/null +++ b/.changeset/cyan-melons-fetch.md @@ -0,0 +1,5 @@ +--- +"@ledgerhq/live-common": patch +--- + +Improve Search for Market when >=2 chars diff --git a/.changeset/polite-bananas-relax.md b/.changeset/polite-bananas-relax.md new file mode 100644 index 000000000000..ccea15a70ace --- /dev/null +++ b/.changeset/polite-bananas-relax.md @@ -0,0 +1,5 @@ +--- +"live-mobile": patch +--- + +Lowercase search on market diff --git a/.changeset/rare-windows-rhyme.md b/.changeset/rare-windows-rhyme.md new file mode 100644 index 000000000000..9227e7de025c --- /dev/null +++ b/.changeset/rare-windows-rhyme.md @@ -0,0 +1,5 @@ +--- +"ledger-live-desktop": patch +--- + +Lower case search + add debounce on Market Search diff --git a/apps/ledger-live-desktop/src/renderer/reducers/market.ts b/apps/ledger-live-desktop/src/renderer/reducers/market.ts index 9cf51fb90c20..ffeac6cc3959 100644 --- a/apps/ledger-live-desktop/src/renderer/reducers/market.ts +++ b/apps/ledger-live-desktop/src/renderer/reducers/market.ts @@ -16,7 +16,7 @@ const initialState: MarketState = { search: "", liveCompatible: false, page: 1, - counterCurrency: "usd", + counterCurrency: "USD", }, currentPage: 1, }; diff --git a/apps/ledger-live-desktop/src/renderer/screens/market/components/SearchInputComponent.tsx b/apps/ledger-live-desktop/src/renderer/screens/market/components/SearchInputComponent.tsx index de15e65ab343..eb4652079900 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/market/components/SearchInputComponent.tsx +++ b/apps/ledger-live-desktop/src/renderer/screens/market/components/SearchInputComponent.tsx @@ -1,8 +1,10 @@ +import { useDebounce } from "@ledgerhq/live-common/hooks/useDebounce"; import { Flex, SearchInput } from "@ledgerhq/react-ui"; -import React from "react"; +import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; +import { track } from "~/renderer/analytics/segment"; import { withV3StyleProvider } from "~/renderer/styles/StyleProviderV3"; const SearchContainer = styled(Flex).attrs({ flexShrink: "1" })` @@ -18,12 +20,27 @@ type Props = { function SearchInputComponent({ search, updateSearch }: Props) { const { t } = useTranslation(); + + const [inputSearch, setInputSearch] = useState(search); + const debouncedSearch = useDebounce(inputSearch, 300); + + useEffect(() => { + track("Page Market Query", { + currencyName: debouncedSearch, + }); + updateSearch(debouncedSearch ? debouncedSearch.trim() : ""); + }, [debouncedSearch, updateSearch]); + + useEffect(() => { + setInputSearch(search.toLowerCase()); + }, [search]); + return ( diff --git a/apps/ledger-live-mobile/src/newArch/features/Market/screens/MarketList/components/SearchHeader/index.tsx b/apps/ledger-live-mobile/src/newArch/features/Market/screens/MarketList/components/SearchHeader/index.tsx index 8bbbef359b54..bc2e3628b2bc 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Market/screens/MarketList/components/SearchHeader/index.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/Market/screens/MarketList/components/SearchHeader/index.tsx @@ -29,7 +29,7 @@ function SearchHeader({ search, refresh }: Props) { }, [debouncedSearch, refresh]); useEffect(() => { - setInputSearch(search); + setInputSearch(search?.toLowerCase()); }, [search]); return ( diff --git a/apps/ledger-live-mobile/src/reducers/market.ts b/apps/ledger-live-mobile/src/reducers/market.ts index 6b986d4a3564..42d52def4938 100644 --- a/apps/ledger-live-mobile/src/reducers/market.ts +++ b/apps/ledger-live-mobile/src/reducers/market.ts @@ -21,7 +21,7 @@ export const INITIAL_STATE: MarketState = { search: "", liveCompatible: false, page: 1, - counterCurrency: "usd", + counterCurrency: "USD", }, marketFilterByStarredCurrencies: false, marketCurrentPage: 1, diff --git a/libs/ledger-live-common/src/market/api/index.ts b/libs/ledger-live-common/src/market/api/index.ts index b9d771c492cd..a6b477042378 100644 --- a/libs/ledger-live-common/src/market/api/index.ts +++ b/libs/ledger-live-common/src/market/api/index.ts @@ -41,7 +41,7 @@ export async function fetchList({ pageSize: limit, to: counterCurrency, sort: getSortParam(order, range), - ...(search.length >= 1 && { filter: search }), + ...(search.length >= 2 && { filter: search }), ...(starred.length > 0 && { ids: starred.join(",") }), ...(liveCoinsList.length > 1 && { ids: liveCoinsList.join(",") }), ...([Order.topLosers, Order.topGainers].includes(order) && { top: 100 }), diff --git a/libs/ledger-live-common/src/market/hooks/useMarketDataProvider.ts b/libs/ledger-live-common/src/market/hooks/useMarketDataProvider.ts index dcc8054a724d..8d1fb2067d04 100644 --- a/libs/ledger-live-common/src/market/hooks/useMarketDataProvider.ts +++ b/libs/ledger-live-common/src/market/hooks/useMarketDataProvider.ts @@ -93,7 +93,7 @@ export function useMarketData(props: MarketListRequestParams): MarketListRequest props.order, { counterCurrency: props.counterCurrency, - ...(props.search && props.search?.length >= 1 && { search: props.search }), + ...(props.search && props.search?.length >= 2 && { search: props.search }), ...(props.starred && props.starred?.length >= 1 && { starred: props.starred }), ...(props.liveCoinsList && props.liveCoinsList?.length >= 1 && { liveCoinsList: props.liveCoinsList }), From b5c3a11738141d4acc9c936f56706f2b3d13e214 Mon Sep 17 00:00:00 2001 From: Martin Cayuelas Date: Thu, 18 Jul 2024 16:51:36 +0200 Subject: [PATCH 2/3] Sort ids --- libs/ledger-live-common/src/market/api/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/ledger-live-common/src/market/api/index.ts b/libs/ledger-live-common/src/market/api/index.ts index a6b477042378..df76b0981514 100644 --- a/libs/ledger-live-common/src/market/api/index.ts +++ b/libs/ledger-live-common/src/market/api/index.ts @@ -42,8 +42,8 @@ export async function fetchList({ to: counterCurrency, sort: getSortParam(order, range), ...(search.length >= 2 && { filter: search }), - ...(starred.length > 0 && { ids: starred.join(",") }), - ...(liveCoinsList.length > 1 && { ids: liveCoinsList.join(",") }), + ...(starred.length > 0 && { ids: starred.sort().join(",") }), + ...(liveCoinsList.length > 1 && { ids: liveCoinsList.sort().join(",") }), ...([Order.topLosers, Order.topGainers].includes(order) && { top: 100 }), }, }); From ecca5e6668ead4425fcb3f26b66557eeeff4022b Mon Sep 17 00:00:00 2001 From: Martin Cayuelas Date: Fri, 19 Jul 2024 10:39:00 +0200 Subject: [PATCH 3/3] Lowercase in hook --- .../screens/market/components/SearchInputComponent.tsx | 2 +- .../screens/MarketList/components/SearchHeader/index.tsx | 2 +- .../src/market/hooks/useMarketDataProvider.ts | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/ledger-live-desktop/src/renderer/screens/market/components/SearchInputComponent.tsx b/apps/ledger-live-desktop/src/renderer/screens/market/components/SearchInputComponent.tsx index eb4652079900..d081a3f7cf23 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/market/components/SearchInputComponent.tsx +++ b/apps/ledger-live-desktop/src/renderer/screens/market/components/SearchInputComponent.tsx @@ -32,7 +32,7 @@ function SearchInputComponent({ search, updateSearch }: Props) { }, [debouncedSearch, updateSearch]); useEffect(() => { - setInputSearch(search.toLowerCase()); + setInputSearch(search); }, [search]); return ( diff --git a/apps/ledger-live-mobile/src/newArch/features/Market/screens/MarketList/components/SearchHeader/index.tsx b/apps/ledger-live-mobile/src/newArch/features/Market/screens/MarketList/components/SearchHeader/index.tsx index bc2e3628b2bc..8bbbef359b54 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Market/screens/MarketList/components/SearchHeader/index.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/Market/screens/MarketList/components/SearchHeader/index.tsx @@ -29,7 +29,7 @@ function SearchHeader({ search, refresh }: Props) { }, [debouncedSearch, refresh]); useEffect(() => { - setInputSearch(search?.toLowerCase()); + setInputSearch(search); }, [search]); return ( diff --git a/libs/ledger-live-common/src/market/hooks/useMarketDataProvider.ts b/libs/ledger-live-common/src/market/hooks/useMarketDataProvider.ts index 8d1fb2067d04..badd1f6ec071 100644 --- a/libs/ledger-live-common/src/market/hooks/useMarketDataProvider.ts +++ b/libs/ledger-live-common/src/market/hooks/useMarketDataProvider.ts @@ -85,6 +85,7 @@ export const useSupportedCurrencies = () => }); export function useMarketData(props: MarketListRequestParams): MarketListRequestResult { + const search = props.search?.toLowerCase() ?? ""; return useQueries({ queries: Array.from({ length: props.page ?? 1 }, (_, i) => i).map(page => ({ queryKey: [ @@ -93,7 +94,7 @@ export function useMarketData(props: MarketListRequestParams): MarketListRequest props.order, { counterCurrency: props.counterCurrency, - ...(props.search && props.search?.length >= 2 && { search: props.search }), + ...(props.search && props.search?.length >= 2 && { search: search }), ...(props.starred && props.starred?.length >= 1 && { starred: props.starred }), ...(props.liveCoinsList && props.liveCoinsList?.length >= 1 && { liveCoinsList: props.liveCoinsList }), @@ -101,7 +102,7 @@ export function useMarketData(props: MarketListRequestParams): MarketListRequest [Order.topLosers, Order.topGainers].includes(props.order) && { range: props.range }), }, ], - queryFn: () => fetchList({ ...props, page }), + queryFn: () => fetchList({ ...props, page, search }), select: (data: MarketItemResponse[]) => ({ formattedData: currencyFormatter(data, cryptoCurrenciesList), page,