Skip to content

Commit

Permalink
bugfix: reintroduce NFT spam operation in OperationsHistory
Browse files Browse the repository at this point in the history
  • Loading branch information
mcayuelas-ledger committed Feb 12, 2025
1 parent 527e63a commit 0061fb0
Show file tree
Hide file tree
Showing 19 changed files with 623 additions and 379 deletions.
6 changes: 6 additions & 0 deletions .changeset/dirty-bears-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"ledger-live-desktop": minor
"@ledgerhq/live-nft-react": minor
---

reintroduce spamTx for NFts operations
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ function View({
account={account}
title={t("NFT.gallery.collection.operationList.header")}
filterOperation={collectionAddress ? filterOperation : undefined}
t={t}
/>
</Flex>
</>
Expand Down
3 changes: 0 additions & 3 deletions apps/ledger-live-desktop/src/renderer/Default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ import { isLocked as isLockedSelector } from "~/renderer/reducers/application";
import { useAutoDismissPostOnboardingEntryPoint } from "@ledgerhq/live-common/postOnboarding/hooks/index";
import { setShareAnalytics, setSharePersonalizedRecommendations } from "./actions/settings";
import useEnv from "@ledgerhq/live-common/hooks/useEnv";
import { useSyncNFTsWithAccounts } from "./hooks/nfts/useSyncNFTsWithAccounts";

const PlatformCatalog = lazy(() => import("~/renderer/screens/platform"));
const Dashboard = lazy(() => import("~/renderer/screens/dashboard"));
Expand Down Expand Up @@ -203,8 +202,6 @@ export default function Default() {
useRecoverRestoreOnboarding();
useAutoDismissPostOnboardingEntryPoint();

useSyncNFTsWithAccounts();

const analyticsFF = useFeature("lldAnalyticsOptInPrompt");
const hasSeenAnalyticsOptInPrompt = useSelector(hasSeenAnalyticsOptInPromptSelector);
const nftReworked = useFeature("lldNftsGalleryNewArch");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,18 @@
import React, { PureComponent } from "react";
import React from "react";
import styled from "styled-components";
import { connect } from "react-redux";
import { compose } from "redux";
import { withTranslation } from "react-i18next";
import { TFunction } from "i18next";
import { useTranslation, withTranslation } from "react-i18next";
import { Operation, Account, AccountLike } from "@ledgerhq/types-live";
import keyBy from "lodash/keyBy";
import {
groupAccountOperationsByDay,
groupAccountsOperationsByDay,
flattenAccounts,
getMainAccount,
} from "@ledgerhq/live-common/account/index";
import { getMainAccount } from "@ledgerhq/live-common/account/index";
import logger from "~/renderer/logger";
import { openModal } from "~/renderer/actions/modals";
import IconAngleDown from "~/renderer/icons/AngleDown";
import Box from "~/renderer/components/Box";
import Text from "~/renderer/components/Text";
import { track } from "~/renderer/analytics/segment";
import { createStructuredSelector } from "reselect";
import { accountsSelector } from "~/renderer/reducers/accounts";
import SectionTitle from "./SectionTitle";
import OperationC from "./Operation";
import OperationComponent from "./Operation";
import TableContainer, { TableHeader } from "../TableContainer";
import { OperationDetails } from "~/renderer/drawers/OperationDetails";
import { setDrawer } from "~/renderer/drawers/Provider";
import { isEditableOperation } from "@ledgerhq/live-common/operation";
import { useOperationsList } from "./useOperationsList";

const ShowMore = styled(Box).attrs(() => ({
horizontal: true,
Expand All @@ -41,157 +28,113 @@ const ShowMore = styled(Box).attrs(() => ({
text-decoration: underline;
}
`;
const mapDispatchToProps = {
openModal,
};

type Props = {
account?: AccountLike;
parentAccount?: Account | null;
accounts?: AccountLike[];
allAccounts?: AccountLike[];
openModal?: (b: string, a: object) => void;
t: TFunction;
withAccount?: boolean;
withSubAccounts?: boolean;
title?: string;
filterOperation?: (b: Operation, a: AccountLike) => boolean;
};
type State = {
nbToShow: number;
};
const initialState = {
nbToShow: 20,
};
export class OperationsList extends PureComponent<Props, State> {
static defaultProps = {
withAccount: false,
};

state = initialState;
handleClickOperation = (operation: Operation, account: AccountLike, parentAccount?: Account) =>
setDrawer(OperationDetails, {
operationId: operation.id,
accountId: account.id,
parentId: parentAccount?.id,
});

// TODO: convert of async/await if fetching with the api
fetchMoreOperations = () => {
track("FetchMoreOperations");
this.setState({
nbToShow: this.state.nbToShow + 20,
});
};

render() {
const {
export function OperationsList({
account,
parentAccount,
accounts,
allAccounts,
withAccount,
withSubAccounts,
title,
filterOperation,
}: Props) {
const { t } = useTranslation();
const { fetchMoreOperations, handleClickOperation, groupedOperations, accountsMap } =
useOperationsList({
account,
parentAccount,
accounts,
allAccounts,
t,
title,
withAccount,
withSubAccounts,
filterOperation,
} = this.props;
const { nbToShow } = this.state;
if (!account && !accounts) {
console.warn("Preventing render OperationsList because not received account or accounts"); // eslint-disable-line no-console
return null;
}
const groupedOperations = account
? groupAccountOperationsByDay(account, {
count: nbToShow,
withSubAccounts,
filterOperation,
})
: accounts
? groupAccountsOperationsByDay(accounts, {
count: nbToShow,
withSubAccounts,
filterOperation,
})
: undefined;
});

const all = flattenAccounts(accounts || []).concat(
[account as AccountLike, parentAccount as AccountLike].filter(Boolean),
);
const accountsMap = keyBy(all, "id");
return (
<>
<TableContainer id="operation-list">
{title && (
<TableHeader
title={title}
titleProps={{
"data-e2e": "dashboard_OperationList",
}}
/>
)}
{groupedOperations?.sections.map(group => (
<Box key={group.day.toISOString()}>
<SectionTitle date={group.day} />
<Box p={0}>
{group.data.map(operation => {
const account = accountsMap[operation.accountId];
if (!account) {
logger.warn(`no account found for operation ${operation.id}`);
return null;
}
let parentAccount;
if (account.type !== "Account") {
const pa =
accountsMap[account.parentId] ||
allAccounts?.find(a => a.id === account.parentId);
if (pa && pa.type === "Account") {
parentAccount = pa;
}
if (!parentAccount) {
logger.warn(`no token account found for token operation ${operation.id}`);
if (!account && !accounts) {
console.warn("Preventing render OperationsList because not received account or accounts"); // eslint-disable-line no-console
return null;
}
return (
<>
<TableContainer id="operation-list">
{title && (
<TableHeader
title={title}
titleProps={{
"data-e2e": "dashboard_OperationList",
}}
/>
)}
{groupedOperations?.sections?.map(
group =>
group.data.length > 0 && (
<Box key={group.day.toISOString()}>
<SectionTitle date={group.day} />
<Box p={0}>
{group.data.map(operation => {
const account = accountsMap[operation.accountId];
if (!account) {
logger.warn(`no account found for operation ${operation.id}`);
return null;
}
}
const mainAccount = getMainAccount(account, parentAccount);
return (
<OperationC
operation={operation}
account={account}
parentAccount={parentAccount}
key={`${account.id}_${operation.id}`}
onOperationClick={this.handleClickOperation}
t={t}
withAccount={withAccount}
editable={account && isEditableOperation({ account: mainAccount, operation })}
/>
);
})}
let parentAccount;
if (account.type !== "Account") {
const pa =
accountsMap[account.parentId] ||
allAccounts?.find(a => a.id === account.parentId);
if (pa && pa.type === "Account") {
parentAccount = pa;
}
if (!parentAccount) {
logger.warn(`no token account found for token operation ${operation.id}`);
return null;
}
}
const mainAccount = getMainAccount(account, parentAccount);
return (
<OperationComponent
operation={operation}
account={account}
parentAccount={parentAccount}
key={`${account.id}_${operation.id}`}
onOperationClick={handleClickOperation}
t={t}
withAccount={withAccount}
editable={
account && isEditableOperation({ account: mainAccount, operation })
}
/>
);
})}
</Box>
</Box>
</Box>
))}
</TableContainer>
{!groupedOperations?.completed ? (
<ShowMore onClick={this.fetchMoreOperations}>
<span>{t("common.showMore")}</span>
<IconAngleDown size={12} />
</ShowMore>
) : (
<Box p={3} alignItems="center">
<Text ff="Inter" fontSize={3}>
{t("operationList.noMoreOperations")}
</Text>
</Box>
),
)}
</>
);
}
</TableContainer>
{!groupedOperations?.completed ? (
<ShowMore onClick={fetchMoreOperations}>
<span>{t("common.showMore")}</span>
<IconAngleDown size={12} />
</ShowMore>
) : (
<Box p={3} alignItems="center">
<Text ff="Inter" fontSize={3}>
{t("operationList.noMoreOperations")}
</Text>
</Box>
)}
</>
);
}
export default compose<React.ComponentType<Props>>(
withTranslation(),
connect(
createStructuredSelector({
allAccounts: accountsSelector,
}),
mapDispatchToProps,
),
)(OperationsList);

export default compose<React.ComponentType<Props>>(withTranslation())(OperationsList);
Loading

0 comments on commit 0061fb0

Please sign in to comment.